Skip to content

Commit 0c26467

Browse files
committed
海康威视面经
1 parent de52f4f commit 0c26467

File tree

3 files changed

+140
-31
lines changed

3 files changed

+140
-31
lines changed

docs/src/sidebar/sanfene/javathread.md

Lines changed: 122 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -68,9 +68,11 @@ volatile 关键字可以保证了变量的修改对所有线程立即可见,
6868

6969
#### 如何理解协程?
7070

71-
协程通常被视为比线程更轻量级的并发单元,它们主要在一些支持异步编程模型的语言中得到了原生支持,如 Kotlin、Go 等
71+
协程被视为比线程更轻量级的并发单元,可以在单线程中实现并发执行,由我们开发者显式调度
7272

73-
不过,我们可以使用 CompletableFuture 来模拟协程式的异步执行任务。
73+
我们可以使用 CompletableFuture 来模拟协程式的异步执行任务。比如说我们创建两个 CompletableFuture 对象来异步执行两个简单的数值返回任务。这两个任务都会休眠 1 秒钟来模拟耗时计算。
74+
75+
然后我们使用 thenCombine 方法来合并这两个任务的结果。最后,我们通过 get 方法等待最终结果的完成,并打印出来。
7476

7577
```java
7678
class CompletableFutureExample {
@@ -105,9 +107,7 @@ class CompletableFutureExample {
105107
}
106108
```
107109

108-
在这个示例中,我们创建了两个 CompletableFuture 对象来异步执行两个简单的数值返回任务。这两个任务都会休眠 1 秒钟来模拟耗时计算。
109-
110-
然后我们使用 thenCombine 方法来合并这两个任务的结果。最后,我们通过 get 方法等待最终结果的完成,并打印出来。
110+
协程在用户态进行调度,避免了线程切换时的内核态开销。
111111

112112
#### 说说线程的共享内存?
113113

@@ -136,6 +136,7 @@ class CompletableFutureExample {
136136
> 8. [Java 面试指南(付费)](https://javabetter.cn/zhishixingqiu/mianshi.html)收录的招商银行面经同学 6 招银网络科技面试原题:进程和线程的区别?
137137
> 9. [Java 面试指南(付费)](https://javabetter.cn/zhishixingqiu/mianshi.html)收录的用友面试原题:线程和进程的区别
138138
> 10. [Java 面试指南(付费)](https://javabetter.cn/zhishixingqiu/mianshi.html)收录的vivo 面经同学 10 技术一面面试原题:线程的概念,线程有哪些状态
139+
> 11. [Java 面试指南(付费)](https://javabetter.cn/zhishixingqiu/mianshi.html)收录的海康威视同学 4面试原题:对协程的了解,为什么协程比线程还有更低的资源消耗
139140
140141
### 3.说说线程有几种创建方式?
141142

@@ -1663,33 +1664,29 @@ GitHub 上标星 10000+ 的开源知识库《[二哥的 Java 进阶之路](https
16631664

16641665
##
16651666

1666-
### 26.synchronized 用过吗?怎么使用?
1667+
### 26.synchronized 用过吗?
16671668

1668-
在 Java 中,synchronized 是最常用的锁,它使用简单,并且可以保证线程安全,避免多线程并发访问时出现数据不一致的情况
1669+
在 Java 中,使用 synchronized 是最常用的上锁方式,直接在方法上加关键字就可以保证线程安全
16691670

1670-
随着 JDK 版本的进化,synchronized 的性能也得到了进一步的提升,不再像以前样重量级了
1671+
并且随着 JDK 版本的进化,synchronized 的性能也得到了进一步的提升,比如 JDK 1.6 中引入的偏向锁和轻量级锁
16711672

1672-
synchronized 可以用在方法和代码块中。
1673-
1674-
①、修饰方法
1673+
synchronized 可以用在方法上,表示该方法是同步的,线程在执行这个方法的时候,其他线程不能同时执行,需要等待锁释放。
16751674

16761675
```java
16771676
public synchronized void increment() {
16781677
this.count++;
16791678
}
16801679
```
16811680

1682-
当在方法声明中使用了 synchronized 关键字,就表示该方法是同步的,也就是说,线程在执行这个方法的时候,其他线程不能同时执行,需要等待锁释放。
1683-
1684-
如果是静态方法的话,锁的是这个类的 Class 对象,因为静态方法是属于类级别的。
1681+
如果 synchronized 修饰的是静态方法,上锁的是这个类的 Class 对象,因为静态方法是属于类级别的。
16851682

16861683
```java
16871684
public static synchronized void increment() {
16881685
count++;
16891686
}
16901687
```
16911688

1692-
②、修饰代码块
1689+
synchronized 关键字还可以用在代码块上,表示对这个代码块上锁。
16931690

16941691
```java
16951692
public void increment() {
@@ -1705,8 +1702,6 @@ public void increment() {
17051702
17061703
### 27.synchronized 的实现原理?
17071704

1708-
#### synchronized 是怎么加锁的呢?
1709-
17101705
synchronized 是 JVM 帮我们实现的,因此在使用的时候不用手动去 lock 和 unlock,JVM 会帮我们自动加锁和解锁。
17111706

17121707
①、synchronized 修饰代码块时,JVM 会通过 `monitorenter``monitorexit` 两个指令来实现同步:
@@ -1818,12 +1813,10 @@ synchronized 之所以支持可重入,是因为 Java 的对象头包含了一
18181813

18191814
> 1. [Java 面试指南(付费)](https://javabetter.cn/zhishixingqiu/mianshi.html)收录的快手面经同学 5 面试原题:synchronized 可重入锁怎么实现的
18201815
1821-
### 29.锁升级?synchronized 优化了解吗
1816+
### 29.synchronized 锁升级了解吗
18221817

18231818
推荐阅读:[偏向锁、轻量级锁、重量级锁到底是什么?](https://javabetter.cn/thread/synchronized.html)
18241819

1825-
#### 什么是锁升级?
1826-
18271820
锁升级是 Java 虚拟机中的一个优化机制,用于提高多线程环境下 synchronized 的并发性能。锁升级涉及从较轻的锁状态(如无锁或偏向锁)逐步升级到较重的锁状态(如轻量级锁和重量级锁),以适应不同程度的竞争情况。
18281821

18291822
Java 对象头里的 `Mark Word` 会记录锁的状态,一共有四种状态:
@@ -1860,7 +1853,7 @@ Java 对象头里的 `Mark Word` 会记录锁的状态,一共有四种状态
18601853

18611854
如果成功,该线程持有锁;如果失败,表示有其他线程竞争,锁会升级为重量级锁。
18621855

1863-
**③、自旋锁**:当线程尝试获取轻量级锁失败时,它会进行自旋,即循环检查锁是否可用,以避免立即进入阻塞状态。
1856+
**③、自旋**:当线程尝试获取轻量级锁失败时,它会进行自旋,即循环检查锁是否可用,以避免立即进入阻塞状态。
18641857

18651858
自旋的次数不是固定的,而是根据之前在同一个锁上的自旋时间和锁的状态动态调整的。
18661859

@@ -1909,6 +1902,7 @@ Java 对象头里的 `Mark Word` 会记录锁的状态,一共有四种状态
19091902
> 3. [Java 面试指南(付费)](https://javabetter.cn/zhishixingqiu/mianshi.html)收录的去哪儿面经同学 1 技术二面面试原题:锁升级,synchronized 底层,会不会牵扯到 os 层面
19101903
> 4. [Java 面试指南(付费)](https://javabetter.cn/zhishixingqiu/mianshi.html)收录的快手同学 2 一面面试原题:锁升级的过程?
19111904
1905+
19121906
### 30.synchronized 和 ReentrantLock 的区别?
19131907

19141908
[synchronized](https://javabetter.cn/thread/synchronized-1.html) 是一个关键字,[ReentrantLock](https://javabetter.cn/thread/reentrantLock.html)是 Lock 接口的一个实现。
@@ -2490,6 +2484,61 @@ class DeadLockDemo {
24902484
- **自旋锁**:自旋锁是一种锁的实现方式,它不会让线程进入睡眠状态,而是一直循环检测锁是否被释放。自旋锁适用于锁的持有时间非常短的情况。
24912485
- 信号量:信号量([Semaphore](https://javabetter.cn/thread/CountDownLatch.html))本质上是一个计数器,用于为多个进程提供共享数据对象的访问。
24922486

2487+
#### 说说自旋锁?
2488+
2489+
自旋锁是指当线程尝试获取锁时,如果锁已经被占用,线程不会立即阻塞,而是**通过自旋**,也就是循环等待的方式不断尝试获取锁,通常依赖于 CAS 来实现。
2490+
2491+
```
2492+
线程1 线程2
2493+
| |
2494+
| 获取锁成功 | 尝试获取锁
2495+
|------------>|(锁已被占用,自旋等待)
2496+
| 释放锁 |
2497+
|<------------| 获取锁成功
2498+
| |
2499+
```
2500+
2501+
自旋锁的优点是避免线程切换,缺点是如果锁被占用时间过长,会导致线程空转,浪费 CPU 资源。
2502+
2503+
```java
2504+
class SpinLock {
2505+
private AtomicBoolean lock = new AtomicBoolean(false);
2506+
2507+
public void lock() {
2508+
while (!lock.compareAndSet(false, true)) {
2509+
// 自旋等待,不断尝试获取锁
2510+
}
2511+
}
2512+
2513+
public void unlock() {
2514+
lock.set(false);
2515+
}
2516+
2517+
public static void main(String[] args) {
2518+
SpinLock spinLock = new SpinLock();
2519+
2520+
Runnable task = () -> {
2521+
spinLock.lock();
2522+
try {
2523+
System.out.println(Thread.currentThread().getName() + " 获取到锁");
2524+
} finally {
2525+
spinLock.unlock();
2526+
}
2527+
};
2528+
2529+
Thread t1 = new Thread(task);
2530+
Thread t2 = new Thread(task);
2531+
2532+
t1.start();
2533+
t2.start();
2534+
}
2535+
}
2536+
```
2537+
2538+
默认情况下,自旋锁会一直等待,直到获取到锁为止。但是,在实际开发中,通常会设置自旋次数或者超时时间。如果超过阈值,线程可以选择放弃锁或者进入阻塞状态。
2539+
2540+
2541+
24932542
#### 互斥和同步在时间上有要求吗?
24942543

24952544
互斥和同步在时间上是有一定要求的,因为它们都涉及到对资源的访问顺序和时机控制。
@@ -2528,6 +2577,7 @@ class SyncExample {
25282577

25292578
> 1. [Java 面试指南(付费)](https://javabetter.cn/zhishixingqiu/mianshi.html)收录的科大讯飞非凡计划研发类面经原题:聊聊线程同步
25302579
> 2. [Java 面试指南(付费)](https://javabetter.cn/zhishixingqiu/mianshi.html)收录的拼多多面经同学 4 技术一面面试原题:java多线程,同步与互斥,互斥和同步在时间上有要求吗?
2580+
> 3. [Java 面试指南(付费)](https://javabetter.cn/zhishixingqiu/mianshi.html)收录的海康威视同学 4面试原题:自旋锁是什么,自旋锁会一直等待吗?自旋锁的劣势是什么?
25312581
25322582
### 42.聊聊悲观锁和乐观锁?(补充)
25332583

@@ -2537,16 +2587,63 @@ class SyncExample {
25372587

25382588
悲观锁的代表有 [synchronized 关键字](https://javabetter.cn/thread/synchronized-1.html)[Lock 接口](https://javabetter.cn/thread/reentrantLock.html)
25392589

2540-
乐观锁,顾名思义,它是乐观派。乐观锁总是假设对共享资源的访问没有冲突,线程可以不停地执行,无需加锁也无需等待。一旦多个线程发生冲突,乐观锁通常使用一种称为 [CAS](https://javabetter.cn/thread/cas.html) 的技术来保证线程执行的安全性。
2590+
悲观锁多用于”写多读少“的环境,避免频繁失败和重试影响性能。
2591+
2592+
乐观锁,是个乐观派,总是假设对共享资源的访问没有冲突,线程可以不停地执行,无需加锁也无需等待,通常使用 [CAS](https://javabetter.cn/thread/cas.html) 的技术来保证线程执行的安全性。
2593+
2594+
多用于“读多写少“的环境,避免频繁加锁影响性能。
2595+
2596+
#### Java中有几种锁?
2597+
2598+
按照锁的使用方式来分类的话,Java 中的锁可以分为两大类:悲观锁和乐观锁。悲观锁的代表就是 synchronized 关键字,乐观锁的代表就是 CAS。
2599+
2600+
#### 乐观锁时有线程过来修改数据,怎么办?
2601+
2602+
此时可以重新读取数据并再次尝试更新,直到成功为止或达到最大重试次数。
2603+
2604+
```
2605+
读取数据 -> 尝试更新 -> 成功(返回成功)
2606+
|
2607+
-> 失败 -> 重试 -> 达到最大次数 -> 返回失败
2608+
```
2609+
2610+
类似这样:
2611+
2612+
```java
2613+
class CasRetryExample {
2614+
private static AtomicInteger counter = new AtomicInteger(0);
2615+
private static final int MAX_RETRIES = 5;
2616+
2617+
public static void main(String[] args) {
2618+
boolean success = false;
2619+
int retries = 0;
25412620

2542-
由于乐观锁假想操作中没有锁的存在,因此不太可能出现死锁的情况,换句话说,乐观锁天生免疫死锁。
2621+
while (retries < MAX_RETRIES) {
2622+
int currentValue = counter.get();
2623+
boolean updated = counter.compareAndSet(currentValue, currentValue + 1);
2624+
2625+
if (updated) {
2626+
System.out.println("更新成功,当前值: " + counter.get());
2627+
success = true;
2628+
break;
2629+
} else {
2630+
retries++;
2631+
System.out.println("更新失败,进行第 " + retries + " 次重试");
2632+
}
2633+
}
2634+
2635+
if (!success) {
2636+
System.out.println("达到最大重试次数,操作失败");
2637+
}
2638+
}
2639+
}
2640+
```
25432641

2544-
- 乐观锁多用于“读多写少“的环境,避免频繁加锁影响性能;
2545-
- 悲观锁多用于”写多读少“的环境,避免频繁失败和重试影响性能。
25462642

25472643
> 1. [Java 面试指南(付费)](https://javabetter.cn/zhishixingqiu/mianshi.html)收录的阿里面经同学 5 阿里妈妈 Java 后端技术一面面试原题:说说 Java 的并发系统(从悲观锁聊到乐观锁,还有线程、线程池之类的,聊了快十分钟这个)
25482644
> 2. [Java 面试指南(付费)](https://javabetter.cn/zhishixingqiu/mianshi.html)收录的阿里面经同学 1 闲鱼后端一面的原题:乐观锁、悲观锁、ABA 问题
25492645
> 3. [Java 面试指南(付费)](https://javabetter.cn/zhishixingqiu/mianshi.html)收录的腾讯云智面经同学 20 二面面试原题:乐观锁和悲观锁怎么理解的?
2646+
> 4. [Java 面试指南(付费)](https://javabetter.cn/zhishixingqiu/mianshi.html)收录的海康威视同学 4面试原题:java中锁种类,什么场景下用乐观锁,什么场景下用悲观锁?使用乐观锁时有线程过来修改数据,此时应该怎么做
25502647
25512648
GitHub 上标星 10000+ 的开源知识库《[二哥的 Java 进阶之路](https://github.com/itwanger/toBeBetterJavaer)》第一版 PDF 终于来了!包括 Java 基础语法、数组&字符串、OOP、集合框架、Java IO、异常处理、Java 新特性、网络编程、NIO、并发编程、JVM 等等,共计 32 万余字,500+张手绘图,可以说是通俗易懂、风趣幽默……详情戳:[太赞了,GitHub 上标星 10000+ 的 Java 教程](https://javabetter.cn/overview/)
25522649

docs/src/sidebar/sanfene/redis.md

Lines changed: 14 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -20,11 +20,11 @@ head:
2020

2121
### 1.说说什么是 Redis?
2222

23-
[Redis](https://javabetter.cn/redis/rumen.html)**Re**mote **Di**ctionary **S**ervice 三个单词中加粗字母的组合,是一种基于键值对(key-value)的 NoSQL 数据库。
23+
[Redis](https://javabetter.cn/redis/rumen.html)**Re**mote **Di**ctionary **S**ervice 三个单词中加粗字母的组合,是一种基于键值对的 NoSQL 数据库。
2424

2525
![三分恶面渣逆袭:Redis图标](https://cdn.tobebetterjavaer.com/tobebetterjavaer/images/sidebar/sanfene/redis-96e079f9-49a3-4c55-b0a4-47d043732b62.png)
2626

27-
但比一般的键值对,比如 [HashMap](https://javabetter.cn/collection/hashmap.html) 强大的多,Redis 中的 value 支持 string(字符串)、hash(哈希)、 list(列表)、set(集合)、zset(有序集合)、Bitmaps(位图)[HyperLogLog](https://www.cnblogs.com/54chensongxia/p/13803465.html)(基数估算)、GEO(地理信息定位)等多种数据结构
27+
但比一般的键值对,比如 [HashMap](https://javabetter.cn/collection/hashmap.html) 强大的多,Redis 中的 value 支持 string、hash、 list、set、zset、Bitmaps、 [HyperLogLog](https://www.cnblogs.com/54chensongxia/p/13803465.html)、GEO等多种数据结构
2828

2929
而且因为 Redis 的所有数据都存放在内存当中,所以它的读写性能非常出色。
3030

@@ -43,6 +43,17 @@ head:
4343

4444
![技术派专栏](https://cdn.tobebetterjavaer.com/stutymore/redis-20240420093229.png)
4545

46+
#### 部署过 Redis 吗?
47+
48+
我是直接在本地部署的单机版,只需要下载 Redis 的安装包,解压后运行 `redis-server` 命令即可。
49+
50+
也可以通过 Docker 拉取 Redis 镜像,然后运行容器。
51+
52+
```shell
53+
docker run -d --name redis -p 6379:6379 redis
54+
```
55+
56+
4657
> 1. [Java 面试指南(付费)](https://javabetter.cn/zhishixingqiu/mianshi.html)收录的华为一面原题:说下 Redis 和 HashMap 的区别
4758
> 2. [Java 面试指南(付费)](https://javabetter.cn/zhishixingqiu/mianshi.html)收录的字节跳动商业化一面的原题:Redis 和 MySQL 的区别
4859
> 3. [Java 面试指南(付费)](https://javabetter.cn/zhishixingqiu/mianshi.html)收录的农业银行面经同学 7 Java 后端面试原题:Redis 相关的基础知识
@@ -53,6 +64,7 @@ head:
5364
> 8. [Java 面试指南(付费)](https://javabetter.cn/zhishixingqiu/mianshi.html)收录的百度面经同学 1 文心一言 25 实习 Java 后端面试原题:项目中什么地方使用了 redis 缓存,redis 为什么快?
5465
> 9. [Java 面试指南(付费)](https://javabetter.cn/zhishixingqiu/mianshi.html)收录的国企零碎面经同学 9 面试原题:数据库用什么多(说了 Mysql 和 Redis)
5566
> 10. [Java 面试指南(付费)](https://javabetter.cn/zhishixingqiu/mianshi.html)收录的荣耀面经同学 4 面试原题:Redis和MySQL的区别?
67+
> 11. [Java 面试指南(付费)](https://javabetter.cn/zhishixingqiu/mianshi.html)收录的海康威视同学 4面试原题:Redis部署
5668
5769

5870
### 2.Redis 可以用来干什么?

docs/src/xuexiluxian/java/yitiaolong.md

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -27,22 +27,22 @@ head:
2727

2828
对于科班的同学来说,我建议在学习 Java 这门编程语言之前,学一下 C 语言。我上大学那会,教材用的是《Java 编程思想》,但说真的,这本书对初学者并不友好。
2929

30-
![](https://cdn.tobebetterjavaer.com/tobebetterjavaer/images/xuexiluxian/java/yitiaolong-d5e5b52c-1744-468c-ab9c-f77c24415394.jpg)
30+
![Java 编程思想](https://cdn.tobebetterjavaer.com/tobebetterjavaer/images/xuexiluxian/java/yitiaolong-d5e5b52c-1744-468c-ab9c-f77c24415394.jpg)
3131

3232
编程语言都是相通的,C语言作为 Java 语言的母胎,**还是非常值得科班去学习一下打打基础的**。其实对于我们程序员来说,学的是计算机科学,而不是编程语言,语言只是工具,没有优劣。像我,就学过 Java、C 语言、Ruby、JavaScript 等等这些编程语言,他们之间确实有很多相似之处。如果学过 JavaScript,能很容易搞懂 Java 的 Lambda 表达式。
3333

3434
C 语言的特殊性就在于它可能是唯一一门最适合来学习一系列计算机基础的媒介,比如 Linux 操作系统,就是用 C 语言重构的;比如计算机网络,里面有很多网络协议,有不同的 header 定义,这些字段用 C 语言的 union 和 struct 来操作非常便捷。Java 中虽然剔除了指针这种烦人的东西,但说白了,引用其实和指针差不多,理解了 C 语言中的指针,就能很好的理解 Java 中的引用。
3535

3636
当然了,由于 C 语言的抽象程度更高,学起来也需要花费一番功夫。对于科班的初学者来说,我推荐翁恺教授的 C 语言程序设计。
3737

38-
![](https://cdn.tobebetterjavaer.com/tobebetterjavaer/images/xuexiluxian/java/yitiaolong-82aefde9-8a3f-4f28-aad5-02e39a6b9d4b.png)
38+
![翁恺教授的 C 语言程序设计](https://cdn.tobebetterjavaer.com/tobebetterjavaer/images/xuexiluxian/java/yitiaolong-82aefde9-8a3f-4f28-aad5-02e39a6b9d4b.png)
3939

4040
>B 站地址:[https://www.bilibili.com/video/BV19W411B7w1](https://www.bilibili.com/video/BV19W411B7w1)
4141
4242
喜欢看书的同学我只推荐一本,《**阮一峰老师的 C语言入门教程**》,我第一时间就拜读了一遍,受益匪浅!可以说目前我见到的最好的 C语言入门教程了,没有之一!
4343

4444

45-
![](https://cdn.tobebetterjavaer.com/tobebetterjavaer/images/xuexiluxian/java/yitiaolong-3507eb06-8424-4b8e-b20d-046268508c9d.png)
45+
![阮一峰老师的 C语言入门教程](https://cdn.tobebetterjavaer.com/tobebetterjavaer/images/xuexiluxian/java/yitiaolong-3507eb06-8424-4b8e-b20d-046268508c9d.png)
4646

4747
我第一时间就整理了一份 PDF 版的,需要的小伙伴可以长按识别/扫描下方二维码,关注后回复 「**阮一峰**」 下载这份 PDF 吧:
4848

@@ -65,7 +65,7 @@ JDK 是 Java Development ToolKit 的简称,也就是 Java 开发工具包。JD
6565
Intellij IDEA,不用说,是编写 Java 程序的最佳 IDE,初学者选择社区版就完全够用了。
6666

6767

68-
![](https://cdn.tobebetterjavaer.com/tobebetterjavaer/images/xuexiluxian/java/yitiaolong-3fb56f9d-942a-4439-8bab-0f19bd59ef58.png)
68+
![Intellij IDEA](https://cdn.tobebetterjavaer.com/tobebetterjavaer/images/xuexiluxian/java/yitiaolong-3fb56f9d-942a-4439-8bab-0f19bd59ef58.png)
6969

7070

7171
初次使用的话,建议阅读一下《IntelliJ IDEA 简体中文专题教程》,GitHub 上已开源。

0 commit comments

Comments
 (0)