第 2 章 Java 基础

1、58 同城 java 字符串常量池

1.1、面试题代码

代码

/*** @ClassName StringPool58Demo* @Description TODO* @Author Oneby* @Date 2020/12/23 10:52* @Version 1.0*/
public class StringPool58Demo {public static void main(String[] args) {String str1 = new StringBuilder("58").append("tongcheng").toString();System.out.println(str1);System.out.println(str1.intern());System.out.println(str1 == str1.intern());System.out.println("------------");String str2 = new StringBuilder("ja").append("va").toString();System.out.println(str2);System.out.println(str2.intern());System.out.println(str2 == str2.intern());}
}

程序运行结果

58tongcheng
58tongcheng
true
------------
java
java
false

1.2、代码讲解

1.2.1、intern() 方法

intern() 方法的注释

读一遍 intern() 方法的注释:当 intern() 方法被调用时

  1. 如果字符串常量池中已经包含了此字符串(通过 equals() 方法判断),那么就将此字符串返回
  2. 否则,该字符串将被添加至字符串常量池中,并且返回该字符串在常量池中的引用

以下内容摘自书本

由于运行时常量池是方法区的一部分,所以这两个区域的溢出测试可以放到一起进行。前面曾经提到HotSpot从JDK7开始逐步“去永久代”的计划,并在DK8中完全使用元空间来代替永久代的背景故事,在此我们就以测试代码来观察一下,使用“永久代”还是“元空间”来实现方法区,对程序有什么实际的影响。

String::intern() 是一个本地方法,它的作用是如果字符串常量池中已经包含一个等于此String对象的字符串,则返回代表池中这个字符串的String对象的引用;否则,会将此String对象包含的字串添加到常量池中,并且返回此String对象的引用。在JDK6或更早之前的HotSpot虚拟机中,常量池都是分配在永久代中,我们可以通过 -XX:PermSize-XX:MaxPermSize 限制永久代的大小,即可间接限制其中常量池的容量

1.2.2、运行结果解释

归根结底:“java” 已经提前被加载过了。。。

为什么 "58tongcheng" 能输出 truenew StringBuilder("58").append("tongcheng").toString(); 的结果是在堆中创建了一个值为 "58tongcheng" 的字符串,在 JDK8 中,将字符串常量池移到了堆中,因此只要堆中只要有值为 "58tongcheng" 的字符串,调用 intern() 方法返回的就是该字符串的引用

为什么 "java" 能输出 false"java"字符串答案为 false,必然是两个不同的 "java",那另外一个 "java" 字符串如何加载进来的?有一个初始化的 "java" 字符串(JDK 出娘胎自带的), 在加载 sun.misc.Version 这个类的时候进入常量池

1.2.3、OpenJDK8 源码

递推步骤

System 类 → initializeSystemClass() 方法 → Version 类 → 类加载器和 rt.jar → OpenJDK8源码

1、System

哇哦~虚拟机会调用 System.initializeSystemClass() 方法完成对 System 类的初始化

2、initializeSystemClass() 方法

initializeSystemClass() 方法中调用 sun.misc.Version.init() 完成了一些初始化工作

3、Version

哇哦~ Version 类里面定义了一个 launcher_name 字段,其值为 "java"

4、类加载器和 rt.jar

根加载器 bootstrap 会提前部署加载 rt.jar,Version 这个类就在 rt.jar 包中,位于 sun.misc 包下

5、OpenJDK8源码

官网地址:http://openjdk.java.net/

类所在的路径:openjdk8\jdk\srclshare\classes\sun\misc

1.3、考查点

是否读过经典JVM书籍:《深入理解java虚拟机》书原题

  1. 代码:

  2. 解释:

2、字节跳动两数求和

2.1、题目要求

题目描述

2.2、代码实现

1、暴力法

双层 for 循环解决,缺点是时间复杂度为 O(n2)

class Solution {public int[] twoSum(int[] arr, int target) {for (int i = 0; i < arr.length; i++) {for (int j = i + 1; j < arr.length; j++) {if (arr[i] + arr[j] == target) {return new int[]{i, j};}}}return null;}
}

2、方便理解的 HashMap 版本

HashMap 查询的时间复杂度为 O(1),因此利用 HashMap 可以将算法复杂度降为 O(n)

// HashMap 版本
class Solution {public int[] twoSum(int[] arr, int target) {HashMap<Integer, Integer> valueToIndex = new HashMap<>();// 构造 HashMap,Key 是数组元素的值,Value 是数组元素的下标for (int i = 0; i < arr.length; i++) {valueToIndex.put(arr[i], i);}for (int i = 0; i < arr.length; i++) {// arr[i] + remain = targetint remain = target - arr[i];// remain 在 HashMap 中,且 remain 对应的下标和 arr[i] 对应的下标不同if (valueToIndex.containsKey(remain) && (valueToIndex.get(remain) != i)) {return new int[]{i, valueToIndex.get(remain)};}}return null;}
}

3、使用一次循环的版本

边遍历边判断

class Solution {public int[] twoSum(int[] arr, int target) {HashMap<Integer, Integer> valueToIndex = new HashMap<>();for (int i = 0; i < arr.length; i++) {// arr[i] + remain = targetint remain = target - arr[i];// 如果存在于 HashMap 之中,就返回数组下标if (valueToIndex.containsKey(remain)) {return new int[]{valueToIndex.get(remain), i};}// 否则记录数组元素的值和下标valueToIndex.put(arr[i], i);}return null;}
}

3、字节跳动手写LRUs算法

见redis最后(请坚持到最后一章)

第 2 章 Java 基础相关推荐

  1. [Spring 深度解析]第1章 Java基础

    第1章 ◄Java基础► 在学习Spring之前我们需要对Java基础语法有一定的了解,Java中最重要的两个知识点是注解和反射.注解和反射在Spring框架中应用的最广泛.掌握注解和反射,有助于后面 ...

  2. 使用java实现面向对象编程第二章_java面向对象编程——第二章 java基础语法

    第二章 java基础语法 1.java关键字 abstract boolean break byte case catch char class const continue default do d ...

  3. JavaSE入门0基础笔记 第二章Java基础语法

    JavaSE入门0基础笔记 第二章Java基础语法 1.运算符 1.1算术运算符 1.1.1运算符和表达式 1.1.2 算术运算符 1.1.3字符的"+"操作 1.1.4 字符串中 ...

  4. JavaSE_第2章 Java基础语法

    JavaSE_第2章 Java基础语法 今日内容 数据类型 运算符 学习目标 了解进制 理解基本数据类型的自动类型转换 理解基本数据类型的强制类型转换 了解ASCII编码表和Unicode编码表 理解 ...

  5. 第2章 Java基础语法

    JavaSE_第2章 Java基础语法 学习目标 会使用单行注释和多行注释 能够辨识关键字 理解标识符的含义,正确定义标识符 理解Java中的基本数据类型分类 能够理解常量的概念 能够定义8种基本数据 ...

  6. 第七章 Java基础类库

    前言:如果你真正学习到了这里,那么先容许我夸赞一下你,太棒了!哪怕你对前面六篇文章的掌握度达到50%也是非常了不起的了,关于后面的文章学习我只能说,非常简单,只是我们文章会非常详细的介绍实现原理和一些 ...

  7. 1.第一章 Java基础语法 第一节(一)初识java

    初识java 1.java的发展史 1.1.起源 1.2.演变 2.Java体系与特点 2.1java的体系 2.2java的应用 2.3java的特性 3.JVM,JDK,JRE与GC 3.1jav ...

  8. 第三章 Java基础 (二)

    文章目录 (八)Java的反射机制 1.什么是反射?--框架设计的灵魂 2.字节码Class对象 3.反射机制 (3.1)类成员变量的反射 (3.2)类成员方法的反射 (3.3)类构造方法的反射 (3 ...

  9. java基础语法的书_第一章--Java基础语法

    一.Java变量的分类: a.按声明的位置划分: 1.局部变量:方法或语句块内部定义的变量 2.成员变量:方法外部,类的内部定义的变量 3.注意:类外面(与类对应的大括号外面)不能有变量的声明 b.按 ...

最新文章

  1. qq浏览器网页翻译_科研利器 | NCBI网站影响因子与网页翻译插件安装指南
  2. 原来 Kubernetes 部署如此简单,看完全明白了
  3. 你的电脑上的应用需要使用以下window功能.NET Framework3.5(包括.NET2.0和3.0)——解决方案
  4. android的log.d不显示结果
  5. Kafka单机、集群模式安装详解(二)
  6. java 正则匹配括号是否成对_十分钟学会正则表达式
  7. 层次分析法AHP - 代码注释多 - ( 数据建模 Python代码)
  8. Java利用stream(流)对map中的values进行过滤、排序操作
  9. 【C++】带空格输入
  10. python-操作xml格式的文件
  11. 连 CEO 都不香了?这些互联网大佬接连辞任
  12. Java==与equals方法的区别
  13. excel保存快捷键_只会用Ctrl+C和Ctrl+V怎么行?真正的Excel高手都是快捷键达人!...
  14. idea lanyu方式激活
  15. C++解决程序一闪而退及清屏函数
  16. 设置div高度等于屏幕高度
  17. 如何进入csdn的我的收藏? 我的收藏在哪里?
  18. bzoj2683/4066 简单题
  19. 大学计算机课读书笔记,信息技术读书笔记
  20. 如何将下载的影像变换为西安80坐标系

热门文章

  1. 数字测图原理与方法的实习日志_数字测图原理与方法实习与习题.doc
  2. html页面可以用在webview,使用WebView加载HTML代码
  3. 我们为何总是掉进“杀熟”的圈套?
  4. 还在 Bug 不断?不妨试试这 2 个装X技巧
  5. 优酷响应式在消费场景的落地之 iOS 篇
  6. NBA 投篮数据可视化,4行代码就能实现!
  7. 混合云存储:大数据应用的上云之道
  8. Nutanix推出自动化功能,助力企业保证业务连续性
  9. 让 AI 训练 AI:揭秘阿里、浙大的 AI 训练师助手
  10. 温暖守护美好生活,科技从不冷冰冰