Skip to content

Commit c232082

Browse files
committed
腾讯面经
1 parent 33fa7ac commit c232082

File tree

5 files changed

+236
-92
lines changed

5 files changed

+236
-92
lines changed

docs/src/sidebar/sanfene/collection.md

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -343,6 +343,7 @@ HashMap 的初始容量是 16,随着元素的不断添加,HashMap 的容量
343343
> 6. [Java 面试指南(付费)](https://javabetter.cn/zhishixingqiu/mianshi.html)收录的腾讯云智面经同学 16 一面面试原题:HashMap 的底层实现,它为什么是线程不安全的?
344344
> 7. [Java 面试指南(付费)](https://javabetter.cn/zhishixingqiu/mianshi.html)收录的快手面经同学 1 部门主站技术部面试原题:HashMap 的结构?
345345
> 8. [Java 面试指南(付费)](https://javabetter.cn/zhishixingqiu/mianshi.html)收录的百度面经同学 1 文心一言 25 实习 Java 后端面试原题:hashmap 的底层实现原理、put()方法实现流程、扩容机制?
346+
> 9. [Java 面试指南(付费)](https://javabetter.cn/zhishixingqiu/mianshi.html)收录的腾讯面经同学 27 云后台技术一面面试原题:Hashmap的底层?为什么链表要变成红黑树?为什么不用平衡二叉树?
346347
347348
### 9.你对红黑树了解多少?为什么不用二叉树/平衡树呢?
348349

@@ -362,7 +363,7 @@ HashMap 的初始容量是 16,随着元素的不断添加,HashMap 的容量
362363

363364
#### 为什么不用平衡二叉树?
364365

365-
平衡二叉树比红黑树的要求更高,每个节点的左右子树的高度最多相差 1,这种高度的平衡保证了极佳的查找效率,但在进行插入和删除操作时,可能需要频繁地进行旋转来维持树的平衡,这在某些情况下可能导致更高的维护成本
366+
平衡二叉树比红黑树的要求更高,每个节点的左右子树的高度最多相差 1,这种高度的平衡保证了极佳的查找效率,但在进行插入和删除操作时,可能需要频繁地进行旋转来维持树的平衡,维护成本更高
366367

367368
#### 为什么用红黑树?
368369

@@ -1095,7 +1096,7 @@ HashMap 不是线程安全的,因此在早期的 JDK 版本中,是用 Hashta
10951096

10961097
内部是通过 synchronized 对象锁来保证线程安全的。
10971098

1098-
③、[ConcurrentHashMap](https://javabetter.cn/thread/ConcurrentHashMap.html) 在 JDK 7 中使用分段锁,在 JKD 8 中使用 [CAS(Compare-And-Swap)](https://javabetter.cn/thread/cas.html)+ [synchronized 关键字](https://javabetter.cn/thread/synchronized-1.html),性能得到了进一步提升
1099+
③、[ConcurrentHashMap](https://javabetter.cn/thread/ConcurrentHashMap.html) 在 JDK 7 中使用了分段锁来保证线程安全,在 JDK 8 中使用了[CAS(Compare-And-Swap)](https://javabetter.cn/thread/cas.html)+ [synchronized 关键字](https://javabetter.cn/thread/synchronized-1.html)
10991100

11001101
![初念初恋:ConcurrentHashMap 8 中的实现](https://cdn.tobebetterjavaer.com/stutymore/map-20230816155924.png)
11011102

@@ -1108,6 +1109,7 @@ HashMap 不是线程安全的,因此在早期的 JDK 版本中,是用 Hashta
11081109
> 5. [Java 面试指南(付费)](https://javabetter.cn/zhishixingqiu/mianshi.html)收录的招商银行面经同学 6 招银网络科技面试原题:线程不安全的集合变成线程安全的方法?
11091110
> 6. [Java 面试指南(付费)](https://javabetter.cn/zhishixingqiu/mianshi.html)收录的京东面经同学 8 面试原题:hashMap和hashTable的区别
11101111
> 8. [Java 面试指南(付费)](https://javabetter.cn/zhishixingqiu/mianshi.html)收录的 OPPO 面经同学 1 面试原题:和ConcurrentHashMap的差异
1112+
> 9. [Java 面试指南(付费)](https://javabetter.cn/zhishixingqiu/mianshi.html)收录的腾讯面经同学 27 云后台技术一面面试原题:HashTable了解吗?Hashmap能保证并发安全吗?ConcurrentHashMap是怎么保证的?
11111113
11121114

11131115
### 26.HashMap 内部节点是有序的吗?

docs/src/sidebar/sanfene/javathread.md

Lines changed: 12 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -2047,14 +2047,16 @@ FairSync、NonfairSync 都是 ReentrantLock 的内部类,分别实现了公平
20472047

20482048
推荐阅读:[一文彻底搞清楚 Java 实现 CAS 的原理](https://javabetter.cn/thread/cas.html)
20492049

2050-
CAS(Compare-and-Swap)是一种乐观锁的实现方式,全称为“比较并交换”,是一种无锁的原子操作。
2050+
CAS 是一种乐观锁的实现方式,全称为“比较并交换”(Compare-and-Swap),是一种无锁的原子操作。
20512051

20522052
在 Java 中,我们可以使用 [synchronized](https://javabetter.cn/thread/synchronized-1.html)关键字和 `CAS` 来实现加锁效果。
20532053

20542054
synchronized 是悲观锁,尽管随着 JDK 版本的升级,synchronized 关键字已经“轻量级”了很多,但依然是悲观锁,线程开始执行第一步就要获取锁,一旦获得锁,其他的线程进入后就会阻塞并等待锁。
20552055

20562056
CAS 是乐观锁,线程执行的时候不会加锁,它会假设此时没有冲突,然后完成某项操作;如果因为冲突失败了就重试,直到成功为止。
20572057

2058+
![CAS 原子性:博客园的紫薇哥哥](https://cdn.tobebetterjavaer.com/stutymore/javathread-20241115160840.png)
2059+
20582060
在 CAS 中,有这样三个值:
20592061

20602062
- V:要更新的变量(var)
@@ -2082,12 +2084,19 @@ compareAndSet 就是一个 CAS 方法,它调用的是 Unsafe 的 compareAndSwa
20822084

20832085
![](https://cdn.tobebetterjavaer.com/stutymore/javathread-20240326095144.png)
20842086

2085-
Unsafe 对 CAS 的实现是通过 C++ 实现的,它的具体实现和操作系统、CPU 都有关系。
2087+
为了保证CAS的原子性,CPU 提供了两种实现方式:
2088+
2089+
①、总线锁定,通过锁定 CPU 的总线,禁止其他 CPU 或设备访问内存。在进行操作时,CPU 发出一个 LOCK 信号,这会阻止其他处理器对内存地址进行操作,直到当前指令执行完成。
2090+
2091+
![总线锁定:博客园的紫薇哥哥](https://cdn.tobebetterjavaer.com/stutymore/javathread-20241115161305.png)
2092+
2093+
②、缓存锁定,当多个 CPU 操作同一块内存地址时,如果该内存地址已经被缓存到某个 CPU 的缓存中,缓存锁定机制会锁定该缓存行,防止其他 CPU 对这块内存进行修改。
20862094

2087-
Linux 的 X86 下主要是通过 cmpxchgl 这个指令在 CPU 上完成 CAS 操作的,但在多处理器情况下,必须使用 lock 指令加锁来完成。当然,不同的操作系统和处理器在实现方式上肯定会有所不同
2095+
现代CPU基本都支持和使用缓存锁定机制
20882096

20892097
> 1. [Java 面试指南(付费)](https://javabetter.cn/zhishixingqiu/mianshi.html)收录的华为面经同学 8 技术二面面试原题:乐观锁是怎样实现的?
20902098
> 2. [Java 面试指南(付费)](https://javabetter.cn/zhishixingqiu/mianshi.html)收录的携程面经同学 1 Java 后端技术一面面试原题:cas 和 aba(原子操作+时间戳)
2099+
> 3. [Java 面试指南(付费)](https://javabetter.cn/zhishixingqiu/mianshi.html)收录的腾讯面经同学 27 云后台技术一面面试原题:CAS算法具体内容是啥?他怎么保证数据原子性(这个没答出来)
20912100
20922101
### 35.CAS 有什么问题?如何解决?
20932102

docs/src/sidebar/sanfene/jvm.md

Lines changed: 37 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -495,18 +495,19 @@ PhantomReference<String> phantomRef = new PhantomReference<>(new String("沉默
495495
496496
### 12.Java 堆的内存分区了解吗?
497497

498-
Java 堆被划分为**新生代**(Young Generation)**老年代**(Old Generation)两个区域。
498+
Java 堆被划分为**新生代****老年代**两个区域。
499499

500500
![三分恶面渣逆袭:Java堆内存划分](https://cdn.tobebetterjavaer.com/tobebetterjavaer/images/sidebar/sanfene/jvm-21.png)
501501

502502
新生代又被划分为 Eden 空间和两个 Survivor 空间(From 和 To)。
503503

504504
- **Eden 空间**:大多数新创建的对象会被分配到 Eden 空间中。当 Eden 区填满时,会触发一次轻量级的垃圾回收(Minor GC),清除不再使用的对象。
505-
- **Survivor 空间**:每次 Minor GC 后,仍然存活的对象会从 Eden 区或 From 区复制到 To 区。From 和 To 区交替使用
505+
- **Survivor 空间**:每次 Minor GC 后,仍然存活的对象会从 Eden 区或 From 区复制到 To 区。From 和 To 区可以交替使用
506506

507507
对象在新生代中经历多次 GC 后,如果仍然存活,会被移动到老年代。
508508

509509
> 1. [Java 面试指南(付费)](https://javabetter.cn/zhishixingqiu/mianshi.html)收录的得物面经同学 8 一面面试原题:Java 中堆内存怎么组织的
510+
> 2. [Java 面试指南(付费)](https://javabetter.cn/zhishixingqiu/mianshi.html)收录的腾讯面经同学 27 云后台技术一面面试原题:怎么来区分对象是属于哪个代的?
510511
511512
### 13.说一下新生代的区域划分?
512513

@@ -887,6 +888,7 @@ Java 的垃圾回收过程主要分为标记存活对象、清除无用对象、
887888
> 7. [Java 面试指南(付费)](https://javabetter.cn/zhishixingqiu/mianshi.html)收录的vivo 面经同学 10 技术一面面试原题:说一下GC,有哪些方法
888889
> 8. [Java 面试指南(付费)](https://javabetter.cn/zhishixingqiu/mianshi.html)收录的荣耀面经同学 4 面试原题:对垃圾回收的理解?
889890
> 9. [Java 面试指南(付费)](https://javabetter.cn/zhishixingqiu/mianshi.html)收录的字节跳动同学 17 后端技术面试原题:垃圾回收机制 为什么要学jvm 内存泄漏场景
891+
> 10. [Java 面试指南(付费)](https://javabetter.cn/zhishixingqiu/mianshi.html)收录的腾讯面经同学 27 云后台技术一面面试原题:GC?怎么样去识别垃圾?
890892
891893
### 24.如何判断对象仍然存活?
892894

@@ -931,7 +933,7 @@ Java 的垃圾回收过程主要分为标记存活对象、清除无用对象、
931933

932934
![](https://cdn.tobebetterjavaer.com/stutymore/neicun-jiegou-20231227111238.png)
933935

934-
#### 1、虚拟机栈中的引用(方法的参数、局部变量等)
936+
**1、虚拟机栈中的引用(方法的参数、局部变量等)**
935937

936938
来看下面这段代码:
937939

@@ -954,7 +956,7 @@ public class StackReference {
954956

955957
当 greet 方法执行完毕后,localVar 的作用域结束,localVar 引用的 Object 对象不再由任何 GC Roots 引用(假设没有其他引用指向这个对象),因此它将有资格作为垃圾被回收掉 😁。
956958

957-
#### 2、本地方法栈中 JNI 的引用
959+
**2、本地方法栈中 JNI 的引用**
958960

959961
Java 通过 JNI(Java Native Interface)提供了一种机制,允许 Java 代码调用本地代码(通常是 C 或 C++ 编写的代码)。
960962

@@ -984,7 +986,7 @@ JNIEXPORT void JNICALL Java_NativeExample_nativeMethod(JNIEnv *env, jobject this
984986

985987
一旦 JNI 方法执行完毕,除非这个引用是全局的(Global Reference),否则它指向的对象将会被作为垃圾回收掉(假设没有其他地方再引用这个对象)。
986988

987-
#### 3、类静态变量
989+
**3、类静态变量**
988990

989991
来看下面这段代码:
990992

@@ -1002,7 +1004,7 @@ StaticFieldReference 类中的 staticVar 引用了一个 Object 对象,这个
10021004

10031005
只要 StaticFieldReference 类未被卸载,staticVar 引用的对象都不会被垃圾回收。如果 StaticFieldReference 类被卸载(这通常发生在其类加载器被垃圾回收时),那么 staticVar 引用的对象也将有资格被垃圾回收(如果没有其他引用指向这个对象)。
10041006

1005-
#### 4、运行时常量池中的常量
1007+
**4、运行时常量池中的常量**
10061008

10071009
来看这段代码:
10081010

@@ -1023,6 +1025,7 @@ public class ConstantPoolReference {
10231025
这些常量引用的对象(字符串"Hello, World"和 Object.class 类对象)在常量池中,只要包含这些常量的 ConstantPoolReference 类未被卸载,这些对象就不会被垃圾回收。
10241026

10251027
> 1. [Java 面试指南(付费)](https://javabetter.cn/zhishixingqiu/mianshi.html)收录的帆软同学 3 Java 后端一面的原题:哪些对象可以作为 GC Roots
1028+
> 2. [Java 面试指南(付费)](https://javabetter.cn/zhishixingqiu/mianshi.html)收录的腾讯面经同学 27 云后台技术一面面试原题:GC Root?
10261029
10271030
### 26.finalize()方法了解吗?有什么作用?
10281031

@@ -1038,7 +1041,7 @@ public class ConstantPoolReference {
10381041

10391042
#### 说说标记-清除算法?
10401043

1041-
`标记-清除`(Mark-Sweep)算法分为两个阶段:
1044+
`标记-清除`算法分为两个阶段:
10421045

10431046
- **标记**:标记所有需要回收的对象
10441047
- **清除**:回收所有被标记的对象
@@ -1049,24 +1052,39 @@ public class ConstantPoolReference {
10491052

10501053
#### 说说标记-复制算法?
10511054

1052-
`标记-复制`(Mark-Copy)算法可以解决标记-清除算法的内存碎片问题,因为它将内存空间划分为两块,每次只使用其中一块。当这一块的内存用完了,就将还存活着的对象复制到另外一块上面,然后清理掉这一块。
1055+
`标记-复制`算法可以解决标记-清除算法的内存碎片问题,因为它将内存空间划分为两块,每次只使用其中一块。当这一块的内存用完了,就将还存活着的对象复制到另外一块上面,然后清理掉这一块。
10531056

10541057
![三分恶面渣逆袭:标记-复制算法](https://cdn.tobebetterjavaer.com/tobebetterjavaer/images/sidebar/sanfene/jvm-23.png)
10551058

10561059
缺点是浪费了一半的内存空间。
10571060

10581061
#### 说说标记-整理算法?
10591062

1060-
`标记-整理`(Mark-Compact)算法是标记-清除复制算法的升级版,它不再划分内存空间,而是将存活的对象向内存的一端移动,然后清理边界以外的内存。
1063+
`标记-整理`算法是标记-清除复制算法的升级版,它不再划分内存空间,而是将存活的对象向内存的一端移动,然后清理边界以外的内存。
10611064

10621065
![标记-整理算法](https://cdn.tobebetterjavaer.com/tobebetterjavaer/images/sidebar/sanfene/jvm-24.png)
10631066

10641067
缺点是移动对象的成本比较高。
10651068

1069+
#### 说说分代收集算法?
1070+
1071+
`分代收集`算法是目前主流的垃圾收集算法,它根据对象存活周期的不同将内存划分为几块,一般分为新生代和老年代。
1072+
1073+
![二哥的 Java 进阶之路:Java 堆划分](https://cdn.tobebetterjavaer.com/stutymore/gc-20231227131241.png)
1074+
1075+
新生代用复制算法,因为大部分对象生命周期短。老年代用标记-整理算法,因为对象存活率较高。
1076+
1077+
#### 为什么要用分代收集呢?
1078+
1079+
分代收集算法的核心思想是根据对象的生命周期优化垃圾回收。
1080+
1081+
新生代的对象生命周期短,使用复制算法可以快速回收。老年代的对象生命周期长,使用标记-整理算法可以减少移动对象的成本。
1082+
10661083
> 1. [Java 面试指南(付费)](https://javabetter.cn/zhishixingqiu/mianshi.html)收录的字节跳动面经同学 1 Java 后端技术一面面试原题:垃圾回收算法了解多少?
10671084
> 2. [Java 面试指南(付费)](https://javabetter.cn/zhishixingqiu/mianshi.html)收录的小米面经同学 F 面试原题:垃圾回收的算法及详细介绍
1085+
> 3. [Java 面试指南(付费)](https://javabetter.cn/zhishixingqiu/mianshi.html)收录的腾讯面经同学 27 云后台技术一面面试原题:回收的方法?分代收集算法里面具体是怎么回收的?为什么要用分代收集呢?
10681086
1069-
### 28.Minor GC/Young GC、Major GC/Old GC、Mixed GC、Full GC 都是什么意思?
1087+
### 28.Minor GC、Major GC、Mixed GC、Full GC 都是什么意思?
10701088

10711089
Minor GC 也称为 Young GC,是指发生在年轻代(Young Generation)的垃圾收集。年轻代包含 Eden 区以及两个 Survivor 区。
10721090

@@ -1076,11 +1094,18 @@ Major GC 也称为 Old GC,主要指的是发生在老年代的垃圾收集。C
10761094

10771095
Mixed GC 是 G1 垃圾收集器特有的一种 GC 类型,它在一次 GC 中同时清理年轻代和部分老年代。
10781096

1079-
Full GC 是最彻底的垃圾收集,涉及整个 Java 堆和方法区(或元空间)。它是最耗时的 GC,通常在 JVM 压力很大时发生。
1097+
Full GC 是最彻底的垃圾收集,涉及整个 Java 堆和方法区(元空间)。它是最耗时的 GC,通常在 JVM 压力很大时发生。
1098+
1099+
#### FULL gc怎么去清理的?
1100+
1101+
Full GC 会从 GC Root 出发,标记所有可达对象。新生代使用复制算法,清空 Eden 区。老年代使用标记-整理算法,回收对象并消除碎片。
1102+
1103+
停顿时间较长(STW),会影响系统响应性能。
10801104

10811105
> 1. [Java 面试指南(付费)](https://javabetter.cn/zhishixingqiu/mianshi.html)收录的阿里面经同学 5 阿里妈妈 Java 后端技术一面面试原题:full gc 和 young gc 的区别
1106+
> 2. [Java 面试指南(付费)](https://javabetter.cn/zhishixingqiu/mianshi.html)收录的腾讯面经同学 27 云后台技术一面面试原题:FULL gc怎么去清理的?
10821107
1083-
### 29.Minor GC/Young GC 什么时候触发?
1108+
### 29.Minor GC 什么时候触发?
10841109

10851110
新创建的对象优先在新生代 Eden 区进行分配,如果 Eden 区没有足够的空间时,就会触发 Young GC 来清理新生代。
10861111

0 commit comments

Comments
 (0)