第 2 章 Java 基础
第 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()
方法被调用时
- 如果字符串常量池中已经包含了此字符串(通过
equals()
方法判断),那么就将此字符串返回 - 否则,该字符串将被添加至字符串常量池中,并且返回该字符串在常量池中的引用
以下内容摘自书本
由于运行时常量池是方法区的一部分,所以这两个区域的溢出测试可以放到一起进行。前面曾经提到HotSpot从JDK7开始逐步“去永久代”的计划,并在DK8中完全使用元空间来代替永久代的背景故事,在此我们就以测试代码来观察一下,使用“永久代”还是“元空间”来实现方法区,对程序有什么实际的影响。
String::intern()
是一个本地方法,它的作用是如果字符串常量池中已经包含一个等于此String对象的字符串,则返回代表池中这个字符串的String对象的引用;否则,会将此String对象包含的字串添加到常量池中,并且返回此String对象的引用。在JDK6或更早之前的HotSpot虚拟机中,常量池都是分配在永久代中,我们可以通过 -XX:PermSize
和 -XX:MaxPermSize
限制永久代的大小,即可间接限制其中常量池的容量
1.2.2、运行结果解释
归根结底:“java” 已经提前被加载过了。。。
为什么 "58tongcheng"
能输出 true
?new 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虚拟机》书原题
代码:
解释:
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 基础相关推荐
- [Spring 深度解析]第1章 Java基础
第1章 ◄Java基础► 在学习Spring之前我们需要对Java基础语法有一定的了解,Java中最重要的两个知识点是注解和反射.注解和反射在Spring框架中应用的最广泛.掌握注解和反射,有助于后面 ...
- 使用java实现面向对象编程第二章_java面向对象编程——第二章 java基础语法
第二章 java基础语法 1.java关键字 abstract boolean break byte case catch char class const continue default do d ...
- JavaSE入门0基础笔记 第二章Java基础语法
JavaSE入门0基础笔记 第二章Java基础语法 1.运算符 1.1算术运算符 1.1.1运算符和表达式 1.1.2 算术运算符 1.1.3字符的"+"操作 1.1.4 字符串中 ...
- JavaSE_第2章 Java基础语法
JavaSE_第2章 Java基础语法 今日内容 数据类型 运算符 学习目标 了解进制 理解基本数据类型的自动类型转换 理解基本数据类型的强制类型转换 了解ASCII编码表和Unicode编码表 理解 ...
- 第2章 Java基础语法
JavaSE_第2章 Java基础语法 学习目标 会使用单行注释和多行注释 能够辨识关键字 理解标识符的含义,正确定义标识符 理解Java中的基本数据类型分类 能够理解常量的概念 能够定义8种基本数据 ...
- 第七章 Java基础类库
前言:如果你真正学习到了这里,那么先容许我夸赞一下你,太棒了!哪怕你对前面六篇文章的掌握度达到50%也是非常了不起的了,关于后面的文章学习我只能说,非常简单,只是我们文章会非常详细的介绍实现原理和一些 ...
- 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 ...
- 第三章 Java基础 (二)
文章目录 (八)Java的反射机制 1.什么是反射?--框架设计的灵魂 2.字节码Class对象 3.反射机制 (3.1)类成员变量的反射 (3.2)类成员方法的反射 (3.3)类构造方法的反射 (3 ...
- java基础语法的书_第一章--Java基础语法
一.Java变量的分类: a.按声明的位置划分: 1.局部变量:方法或语句块内部定义的变量 2.成员变量:方法外部,类的内部定义的变量 3.注意:类外面(与类对应的大括号外面)不能有变量的声明 b.按 ...
最新文章
- qq浏览器网页翻译_科研利器 | NCBI网站影响因子与网页翻译插件安装指南
- 原来 Kubernetes 部署如此简单,看完全明白了
- 你的电脑上的应用需要使用以下window功能.NET Framework3.5(包括.NET2.0和3.0)——解决方案
- android的log.d不显示结果
- Kafka单机、集群模式安装详解(二)
- java 正则匹配括号是否成对_十分钟学会正则表达式
- 层次分析法AHP - 代码注释多 - ( 数据建模 Python代码)
- Java利用stream(流)对map中的values进行过滤、排序操作
- 【C++】带空格输入
- python-操作xml格式的文件
- 连 CEO 都不香了?这些互联网大佬接连辞任
- Java==与equals方法的区别
- excel保存快捷键_只会用Ctrl+C和Ctrl+V怎么行?真正的Excel高手都是快捷键达人!...
- idea lanyu方式激活
- C++解决程序一闪而退及清屏函数
- 设置div高度等于屏幕高度
- 如何进入csdn的我的收藏? 我的收藏在哪里?
- bzoj2683/4066 简单题
- 大学计算机课读书笔记,信息技术读书笔记
- 如何将下载的影像变换为西安80坐标系