提交 e5f8a66b 编写于 作者: 沉默王二's avatar 沉默王二 💬

面试

上级 9cc6f805
<p align="center">
<a href="https://tobebetterjavaer.com">
<img src="https://itwanger-oss.oss-cn-beijing.aliyuncs.com/tobebetterjavaer/images/logo-01.png" width="260px" alt="Java 程序员进阶之路">
<img src="https://cdn.tobebetterjavaer.com/tobebetterjavaer/images/logo-01.png" width="260px" alt="Java 程序员进阶之路">
</a>
</p>
......@@ -10,7 +10,9 @@
<a href="#联系方式" target="_blank"><img src="https://img.shields.io/badge/公众号-沉默王二-brightgreen.svg?style=for-the-badge"></a>
<a href="https://space.bilibili.com/513340480" target="_blank"><img src="https://img.shields.io/badge/bilibili-哔哩哔哩-critical?style=for-the-badge"></a>
<a href="https://tobebetterjavaer.com/download/java.html" target="_blank"><img src="https://img.shields.io/badge/计算机经典电子书-下载-yellow.svg?style=for-the-badge" alt="无套路下载"></a>
<a href="https://github.com/itwanger/toBeBetterJavaer" target="_blank"><img alt="Java程序员进阶之路" src="https://img.shields.io/github/stars/itwanger/toBeBetterJavaer?style=for-the-badge"></a>
<a href="https://github.com/itwanger/toBeBetterJavaer" target="_blank"><img alt="Java程序员进阶之路" src="https://img.shields.io/github/stars/itwanger/toBeBetterJavaer?style=for-the-badge"></a><br><br>
<a href="https://github.com/itwanger/toBeBetterJavaer">Github</a> |
<a href="https://gitee.com/itwanger/toBeBetterJavaer">Gitee</a>
</p>
# 为什么会有这个开源知识库
......
---
title: Java 基础背诵版八股文必看🍉
shortTitle: Java 基础背诵版八股文必看🍉
shortTitle: Java基础背诵版八股文🍉
category:
- 求职面试
tag:
......
---
title: 13 道 Java HashMap 精选面试题👍
shortTitle: 13 道 Java HashMap 精选面试题👍
shortTitle: 13道HashMap精选面试题👍
category:
- 求职面试
tag:
......
---
title: Java 虚拟机背诵版八股文必看🍉
shortTitle: Java 虚拟机背诵版八股文必看🍉
shortTitle: JVM背诵版八股文🍉
category:
- 求职面试
tag:
......
---
title: Java 并发编程背诵版八股文必看🍉
shortTitle: Java 并发编程背诵版八股文必看🍉
shortTitle: 并发编程背诵版八股文🍉
category:
- 求职面试
tag:
......
---
title: 淘宝面试官👤:优惠券系统该如何设计?
shortTitle: 大厂的优惠券系统是如何设计的
shortTitle: 如何设计优惠券系统
description: 大厂的优惠券系统是如何设计的?
category:
- 求职面试
......
---
title: 16天5面,我终于拿到了鹅厂Offer
shortTitle: 16天5面,我终于拿到了鹅厂Offer
author: 瘦风
category:
- 博客园
---
> 上一篇 [我在华为OD的275天](https://www.cnblogs.com/shoufeng/p/14322931.html) 最后说,要讲讲自己为什么会坚持在年底离职,以及离开后去了哪儿。趁周末,鸽王本鸽来交下作业😂
## 1 - 为什么要在年底离职
### 1.1 好像都没有什么成长
20年11月初的一天,在同事们讨论“某某被其他公司高薪挖去了,钱景无限”的消息。
我忽然惊觉,自己来到华为半年多,除了熟悉内部的系统和流程,好像没有什么成长和进步?
不禁反思:只有厉害的人才会被挖,现在这个状态的我,在市场上值几个钱?
### 1.2 投简历,找面试官求虐
刚好想起了之前的一个同事在离职聚会上分享的经验:
> 技术人不能闭门造车,要多交流,多看看外面的动态。
>
> 如果感觉自己太安逸了,那就把简历挂出去,去了解其他公司用的是什么技术,他们更关注哪些痛点?面几次你就有方向了。
这时候起了个念头:找面试官求虐,以此来鞭策自己,进而更好地制定学习方向。
于是我重新下载了某聘软件,在首页推荐里投了几家公司。
### 1.3 开始面试了……
11月10号投的简历,当天就有2家预约了11号下午的线上面试,其中就有鹅厂🐧
好巧不巧,10号晚上要双十一业务保障,一直到第二天凌晨2点半才下班。
熬夜太伤身,还好能申请调休一天,也省去了找借口请假🙊
这段时间集中面了3家:
> 第1个是广州的公司,11号当晚就完成了2轮线上面试,开得有点低,就婉拒了;
>
> 第2个就是本文的重点——鹅厂;
>
> 第3个是做跨境电商的公司,一面就跪(恭喜它荣升为“在我有限的工作经历中,面试体验最差的2家公司之一”🙂️)
### 1.4 鹅厂,去还是不去?
一直有一个大厂梦,奈何菜鸟一枚,之前试过好几次,都跪在技术面了。
所以想了个曲线救国的方法:先在其他单位积累着,有机会了再争取大厂的机会💪
很幸运,也很猝不及防,这次竟然通过了鹅厂的所有面试。
虽然已到年底,但是要是错过这么难得的机会,下次就不知道什么时候才能再通关了。
所以,**年后拿到年终再跳槽 vs 已到手的鹅厂 Offer,我选择了后者😄**
## 2 - 我的鹅厂面试
如本文标题所说,16天通关五轮面试,第17天,我终于收到了期盼已久的鹅厂 Offer。
做技术的同学,可能会对鹅厂的面试很好奇,他们都会问哪些问题呢?
我应聘的是大数据开发(Java)岗位,接下来对我的面试做个梳理,也给想来鹅厂的同学们一个参考😊
> 几乎所有问题都能在网络上找到很详细的答案。
>
> 篇幅有限,这里只写题目和一些引申的问题。
### 2.1 技术一面
#### Java 语言相关
1、对 Java 的类加载器有没有了解?如何自定义类加载器?
> 引申:一个类能被加载多次吗?`java/javax` 包下的类会被加载多次吗?
2、Java 中要怎么创建一个对象🐘?
3、对多线程有了解吗?在什么场景下需要使用多线程?
> 引申:对 **线程安全** 的认识;对线程池的了解,以及各个线程池的适用场景。
4、对垃圾回收的了解?
5、对 JVM 分代的了解?
6、NIO 的了解?用过 RandomAccessFile 吗?
> 引申:对 **同步、异步,阻塞、非阻塞** 的理解?
>
> 多路复用 IO 的优势?
7、ArrayList 和 LinkedList 的区别?各自的适用场景?
8、实现一个 Hash 集合,需要考虑哪些因素?
> 引申:JDK 对 HashMap 的设计关键点,比如初识容量,扩所容,链表转红黑树,以及 JDK 7 和 JDK 8 的区别等等。
#### 通用学科相关
1、TCP 的三次握手;
2、Linux 的常用命令,比如:
> ```shell
> ps aux / ps -ef、top C
> df -h、du -sh *、free -g
> vmstat、mpstat、iostat、netstat
> ```
>
#### 项目框架相关
1、Kafka 和其他 MQ 的区别?它的吞吐量为什么高?
> 消费者主动 pull 数据,目的是:控制消费节奏,还可以重复消费;
>
> 吞吐量高:各 partition 顺序写 IO,批量刷新到磁盘(OS 的 pageCache 负责刷盘,Kafka 不用管),比随机 IO 快;读取数据基于 sendfile 的 Zero Copy;批量数据压缩……
2、Hive 和 SparkSQL 的区别?
3、Ranger 的权限模型、权限对象,鉴权过程,策略如何刷新……
#### 问题定位方法
1、ssh 连接失败,如何定位?
> 是否能 ping 通(DNS是否正确)、对端端口是否开了防火墙、对端服务是否正常……
2、运行 Java 程序的服务器,CPU 使用率达到 100%,如何定位?
> `ps aux | grep xxx` 或 `jps` 命令找到 Java 的进程号 `pid`,
>
> 然后用 `top -Hp pid` 命令查看其阻塞的线程序号,**将其转换为16进制**;
>
> 再通过 `jstack pid` 命令跟踪此 Java 进程的堆栈,搜索上述转换来的16进制线程号,即可找到对应的线程名及其堆栈信息……
3、Java 程序发生了内存溢出,如何定位?
> `jmap` 工具查看堆栈信息,看 Eden、Old 区的变化……
### 2.2 技术二面
二面主要是过往项目相关的问题:
1、Solr 和 Elasticsearch 的区别 / 优劣?
2、对 Elasticsearch 的优化,它的索引过程,选主过程等问题……
3、项目中遇到的难题,如何解决的?
blabla 有少量的基础问题和一面有重复,还有几个和大数据相关的问题,记不太清了😅
### 2.3 技术三面
这一面是总监面,更多是个人关于职业发展的一些想法,以及在之前公司的成长和收获、对下一份工作的期望等问题。
但也问了几个技术问题。印象比较深的是这个:
> 1个1TB 的大文件,每行都只是1个数字,无重复,8GB 内存,要怎么对这个文件进行排序?
首先想到的是 MapReduce 的思路,拆分小文件,分批排序,最后合并。
**此时连环追问来了:**
> Q:如何尽可能多的利用内存呢?
>
> A:用位图法的思路,对数字按顺序映射。(对映射方法要有基本的了解)
>
> Q:如果在排好序之后,还需要快速查找呢?
>
> A:可以做索引,类似 Redis 的跳表,通过多级索引提高查找速度。
>
> Q:索引查找的还是文件。要如何才能更多地利用内存呢?
>
> A:那就要添加缓存了,把读取过的数字缓存到内存中。
>
> Q:缓存应该满足什么特点呢?
>
> A:应该使用 LRU 型的缓存。
*呼。。总算是追问完了这道题😂*
* * *
还有 GM 面和 HR 面,问题都和个人经历相关,这里就略去不表。
## 3 - 文末的絮叨
**入职鹅厂已经1月有余。不同的岗位,不同的工作内容,也是不同的挑战。**
感受比较深的是,作为程序员,还是要自我驱动,努力提升个人技术能力,横向纵向都要扩充,这样才能走得长远。
最后再广告下,有想要加入鹅厂、或者有疑问的同学,可以留言,或关注公众号加我好友,我尽力给你解答😊
> ## 版权声明
>
> 作者:[瘦风(https://healchow.com)](https://healchow.com)
>
> 出处:[博客园-瘦风的南墙(https://www.cnblogs.com/shoufeng)](https://www.cnblogs.com/shoufeng)
>
> **感谢阅读,公众号 [「瘦风的南墙」](https://mp.weixin.qq.com/s/EPUA_78SNmVqoCB4CcrJag) ,手机端阅读更佳,还有其他福利和心得输出,欢迎扫码关注🤝**
>
> [
>
> ![](https://images.cnblogs.com/cnblogs_com/shoufeng/1423755/o_200301011427%E5%85%AC%E4%BC%97%E5%8F%B7%E5%9B%BE%E7%89%87.jpg)
>
> ](https://mp.weixin.qq.com/s/EPUA_78SNmVqoCB4CcrJag)
>
> 本文版权归博主所有,欢迎转载,但 **\[必须在页面明显位置标明原文链接\]**,否则博主保留追究相关人士法律责任的权利。
>参考链接:[https://www.cnblogs.com/shoufeng/p/14381680.html](https://www.cnblogs.com/shoufeng/p/14381680.html),整理:沉默王二
---
title: MySQL 自增主键一定是连续的吗?
shortTitle: MySQL 自增主键一定是连续的吗?
description: 一位读者面试美团遇到的关于 MySQL 自增主键的问题。
author: 小牛肉
category:
- 微信公众号
---
MySQL 一直是二哥强调的 Java 后端开发四大件之一,希望球友们也能重视起来。2023 年也打算把这一块的专栏更新起来,目前也是处在学习的过程中,上次把《MySQL 是怎样运行的》这本小册推荐给一个球友后,她也感慨写得真好。
今天这篇是一个读者面试美团遇到的关于 **MySQL 自增主键是否是连续的**主题。
----
众所周知,自增主键可以让聚集索引尽量地保持递增顺序插入,避免了随机查询,从而提高查询效率,但实际上,MySQL 的自增主键并不能保证一定是连续递增的。
下面举个例子来看下,创建一张表:
![](https://mmbiz.qpic.cn/mmbiz_png/PocakShgoGEDRrKUhdJJj0j170jAhFlSsBiaN3ibx0tWhhbpjyQo8T8XbxLggR4GtWsaNzACbK0kWqNylfoorLHQ/640?wx_fmt=png&wxfrom=5&wx_lazy=1&wx_co=1)
### 自增值保存在哪里?
使用 `insert into test_pk values(null, 1, 1)` 插入一行数据,再执行 `show create table` 命令来看一下表的结构定义:
![](https://mmbiz.qpic.cn/mmbiz_png/PocakShgoGEDRrKUhdJJj0j170jAhFlShzcyORDsddElUwICr30F21IAjOAxMOO0bNCL1rtK8hxmnFaicH0XGeA/640?wx_fmt=png&wxfrom=5&wx_lazy=1&wx_co=1)
上述表的结构定义存放在后缀名为 `.frm` 的本地文件中,在 MySQL 安装目录下的 data 文件夹下可以找到这个 `.frm` 文件:
![](https://mmbiz.qpic.cn/mmbiz_png/PocakShgoGEDRrKUhdJJj0j170jAhFlScTWqJCIkj1IW8XVWiaAWRyjVXPIFX9ma5rmvqp5QwYEO2fRH6beMx7w/640?wx_fmt=png&wxfrom=5&wx_lazy=1&wx_co=1)
从上述表结构可以看到,表定义里面出现了一个 `AUTO_INCREMENT=2`,表示下一次插入数据时,如果需要自动生成自增值,会生成 id = 2。
但需要注意的是,自增值并不会保存在这个表结构也就是 `.frm` 文件中,不同的引擎对于自增值的保存策略不同:
1)MyISAM 引擎的自增值保存在数据文件中
2)InnoDB 引擎的自增值,其实是保存在了内存里,并没有持久化。第一次打开表的时候,都会去找自增值的最大值 `max(id)`,然后将 `max(id)+1` 作为这个表当前的自增值。
举个例子:我们现在表里当前数据行里最大的 id 是 1,AUTO\_INCREMENT=2,对吧。这时候,我们删除 id=1 的行,AUTO\_INCREMENT 还是 2。
![](https://mmbiz.qpic.cn/mmbiz_png/PocakShgoGEDRrKUhdJJj0j170jAhFlS0HgyyZPQHnFS8bF8eIA1yB2keNPXibBF2TrVkv5DsXiccd19k2ABictPQ/640?wx_fmt=png&wxfrom=5&wx_lazy=1&wx_co=1)
但如果马上重启 MySQL 实例,重启后这个表的 AUTO\_INCREMENT 就会变成 1。 也就是说,MySQL 重启可能会修改一个表的 AUTO\_INCREMENT 的值。
![](https://mmbiz.qpic.cn/mmbiz_png/PocakShgoGEDRrKUhdJJj0j170jAhFlScGQLqBeF4EwNW2n1ic8GVrn1MzcDeDpR7OL5bGsic2MCbmiaGFKpwTEow/640?wx_fmt=png&wxfrom=5&wx_lazy=1&wx_co=1)
![](https://mmbiz.qpic.cn/mmbiz_png/PocakShgoGEDRrKUhdJJj0j170jAhFlSPcnibHJkomqQslkzGBG2wAQTwWdXfbViaDRcm0jUqlSOrcT9UkRqlkVw/640?wx_fmt=png&wxfrom=5&wx_lazy=1&wx_co=1)
以上,是在我本地 MySQL 5.x 版本的实验,实际上,到了 MySQL 8.0 版本后,自增值的变更记录被放在了 redo log 中,提供了自增值持久化的能力,也就是实现了“如果发生重启,表的自增值可以根据 redo log 恢复为 MySQL 重启前的值”
也就是说对于上面这个例子来说,重启实例后这个表的 AUTO\_INCREMENT 仍然是 2。
理解了 MySQL 自增值到底保存在哪里以后,我们再来看看自增值的修改机制,并以此引出第一种自增值不连续的场景。
### 自增值不连续场景 1
在 MySQL 里面,如果字段 id 被定义为 AUTO\_INCREMENT,在插入一行数据的时候,自增值的行为如下:
* 如果插入数据时 id 字段指定为 0、null 或未指定值,那么就把这个表当前的 AUTO\_INCREMENT 值填到自增字段;
* 如果插入数据时 id 字段指定了具体的值,就直接使用语句里指定的值。
根据要插入的值和当前自增值的大小关系,自增值的变更结果也会有所不同。假设某次要插入的值是 `insert_num`,当前的自增值是 `autoIncrement_num`
* 如果 `insert_num < autoIncrement_num`,那么这个表的自增值不变
* 如果 `insert_num >= autoIncrement_num`,就需要把当前自增值修改为新的自增值
也就是说,如果插入的 id 是 100,当前的自增值是 90,`insert_num >= autoIncrement_num`,那么自增值就会被修改为新的自增值即 101
一定是这样吗?
非也~
了解过分布式 id 的小伙伴一定知道,为了避免两个库生成的主键发生冲突,我们可以让一个库的自增 id 都是奇数,另一个库的自增 id 都是偶数
这个奇数偶数其实是通过 `auto_increment_offset``auto_increment_increment` 这两个参数来决定的,这俩分别用来表示自增的初始值和步长,默认值都是 1。
所以,上面的例子中生成新的自增值的步骤实际是这样的:从 `auto_increment_offset` 开始,以 `auto_increment_increment` 为步长,持续叠加,直到找到第一个大于 100 的值,作为新的自增值。
所以,这种情况下,自增值可能会是 102,103 等等之类的,就会导致不连续的主键 id。
更遗憾的是,即使在自增初始值和步长这两个参数都设置为 1 的时候,自增主键 id 也不一定能保证主键是连续的
### 自增值不连续场景 2
举个例子,我们现在往表里插入一条 (null,1,1) 的记录,生成的主键是 1,AUTO\_INCREMENT= 2,对吧
![](https://mmbiz.qpic.cn/mmbiz_png/PocakShgoGEDRrKUhdJJj0j170jAhFlSsgKOh3PPxE0GpdWWu4ce6M4REWM9E2z245FDUBh5CGYnQibUIM06SSQ/640?wx_fmt=png&wxfrom=5&wx_lazy=1&wx_co=1)
这时我再执行一条插入 `(null,1,1)` 的命令,很显然会报错 `Duplicate entry`,因为我们设置了一个唯一索引字段 `a`
![](https://mmbiz.qpic.cn/mmbiz_png/PocakShgoGEDRrKUhdJJj0j170jAhFlSMic0AoqHE1gWOvO3rvsibyZUazjiaen17HQnn0rgnUM3FDc10P9eytwjQ/640?wx_fmt=png&wxfrom=5&wx_lazy=1&wx_co=1)
但是,你会惊奇的发现,虽然插入失败了,但自增值仍然从 2 增加到了 3!
这是为啥?
我们来分析下这个 insert 语句的执行流程:
1. 执行器调用 InnoDB 引擎接口准备插入一行记录 (null,1,1);
2. InnoDB 发现用户没有指定自增 id 的值,则获取表 `test_pk` 当前的自增值 2;
3. 将传入的记录改成 (2,1,1);
4. 将表的自增值改成 3;
5. 继续执行插入数据操作,由于已经存在 a=1 的记录,所以报 Duplicate key error,语句返回
可以看到,自增值修改的这个操作,是在真正执行插入数据的操作之前。
这个语句真正执行的时候,因为碰到唯一键 a 冲突,所以 id = 2 这一行并没有插入成功,但也没有将自增值再改回去。所以,在这之后,再插入新的数据行时,拿到的自增 id 就是 3。也就是说,出现了自增主键不连续的情况。
至此,我们已经罗列了两种自增主键不连续的情况:
1. 自增初始值和自增步长设置不为 1
2. 唯一键冲突
除此之外,事务回滚也会导致这种情况
### 自增值不连续场景 3
我们现在表里有一行 `(1,1,1)` 的记录,AUTO\_INCREMENT = 3:
![](https://mmbiz.qpic.cn/mmbiz_png/PocakShgoGEDRrKUhdJJj0j170jAhFlSFjZ40sUdKXibmLhFxfXJoU5ic85QcTUhrHBlVGkqu7jUorksdy5HWAEQ/640?wx_fmt=png&wxfrom=5&wx_lazy=1&wx_co=1)
我们先插入一行数据 `(null, 2, 2)`,也就是 (3, 2, 2) 嘛,并且 AUTO\_INCREMENT 变为 4:
![](https://mmbiz.qpic.cn/mmbiz_png/PocakShgoGEDRrKUhdJJj0j170jAhFlSZYtkzeS6Ric9s0TSCsUrhCUBZ5zSwtP8LPN8HaDKLgVicU7ZVZkQlNlA/640?wx_fmt=png&wxfrom=5&wx_lazy=1&wx_co=1)
再去执行这样一段 SQL:
![](https://mmbiz.qpic.cn/mmbiz_png/PocakShgoGEDRrKUhdJJj0j170jAhFlSPkib5TowVXBmW7Sn6xLyEU5qMBjebODMf9VyIGhK5ONz32x2MY5ZibDg/640?wx_fmt=png&wxfrom=5&wx_lazy=1&wx_co=1)
虽然我们插入了一条 (null, 3, 3) 记录,但是使用 rollback 进行回滚了,所以数据库中是没有这条记录的:
![](https://mmbiz.qpic.cn/mmbiz_png/PocakShgoGEDRrKUhdJJj0j170jAhFlSy5lJTyl2e0aZ4nDXbJ9opGPz53rn2DEVzsxCExMTpwZwmov8Y7fSdA/640?wx_fmt=png&wxfrom=5&wx_lazy=1&wx_co=1)
在这种事务回滚的情况下,自增值并没有同样发生回滚!如下图所示,自增值仍然固执地从 4 增加到了 5:
![](https://mmbiz.qpic.cn/mmbiz_png/PocakShgoGEDRrKUhdJJj0j170jAhFlSTT1fZlfeSFiahUAAA6JpW9MDC9KOxPcaYjYDDkrjoGOrtQTbsqCyoFw/640?wx_fmt=png&wxfrom=5&wx_lazy=1&wx_co=1)
所以这时候我们再去插入一条数据(null, 3, 3)的时候,主键 id 就会被自动赋为 `5` 了:
![](https://mmbiz.qpic.cn/mmbiz_png/PocakShgoGEDRrKUhdJJj0j170jAhFlSSShlKlck7uekokHiblibt0bPATQwNl5v3NFjVYK1FjKLSPWJaXtGx8bQ/640?wx_fmt=png&wxfrom=5&wx_lazy=1&wx_co=1)
那么,为什么在出现唯一键冲突或者回滚的时候,MySQL 没有把表的自增值改回去呢?回退回去的话不就不会发生自增 id 不连续了吗?
事实上,这么做的主要原因是为了提高性能。
我们直接用反证法来验证:假设 MySQL 在事务回滚的时候会把自增值改回去,会发生什么?
现在有两个并行执行的事务 A 和 B,在申请自增值的时候,为了避免两个事务申请到相同的自增 id,肯定要加锁,然后顺序申请,对吧。
1. 假设事务 A 申请到了 id = 1, 事务 B 申请到 id=2,那么这时候表 t 的自增值是 3,之后继续执行。
2. 事务 B 正确提交了,但事务 A 出现了唯一键冲突,也就是 id = 1 的那行记录插入失败了,那如果允许事务 A 把自增 id 回退,也就是把表的当前自增值改回 1,那么就会出现这样的情况:表里面已经有 id = 2 的行,而当前的自增 id 值是 1。
3. 接下来,继续执行的其他事务就会申请到 id=2。这时,就会出现插入语句报错“主键冲突”。
![](https://mmbiz.qpic.cn/mmbiz_png/PocakShgoGEDRrKUhdJJj0j170jAhFlSOYOApB3cGAYCCP6Rx9AicTbUPecmQhObzhsd16EtkiadrDFYH9p0COoQ/640?wx_fmt=png&wxfrom=5&wx_lazy=1&wx_co=1)
而为了解决这个主键冲突,有两种方法:
1. 每次申请 id 之前,先判断表里面是否已经存在这个 id,如果存在,就跳过这个 id
2. 把自增 id 的锁范围扩大,必须等到一个事务执行完成并提交,下一个事务才能再申请自增 id
很显然,上述两个方法的成本都比较高,会导致性能问题。而究其原因呢,是我们假设的这个 “允许自增 id 回退”。
因此,InnoDB 放弃了这个设计,语句执行失败也不回退自增 id。也正是因为这样,所以才只保证了自增 id 是递增的,但不保证是连续的。
综上,已经分析了三种自增值不连续的场景,还有第四种场景:批量插入数据。
### 自增值不连续场景 4
对于批量插入数据的语句,MySQL 有一个批量申请自增 id 的策略:
1. 语句执行过程中,第一次申请自增 id,会分配 1 个;
2. 1 个用完以后,这个语句第二次申请自增 id,会分配 2 个;
3. 2 个用完以后,还是这个语句,第三次申请自增 id,会分配 4 个;
4. 依此类推,同一个语句去申请自增 id,每次申请到的自增 id 个数都是上一次的两倍。
注意,这里说的批量插入数据,不是在普通的 insert 语句里面包含多个 value 值!!!,因为这类语句在申请自增 id 的时候,是可以精确计算出需要多少个 id 的,然后一次性申请,申请完成后锁就可以释放了。
而对于 `insert … select`、replace … select 和 load data 这种类型的语句来说,MySQL 并不知道到底需要申请多少 id,所以就采用了这种批量申请的策略,毕竟一个一个申请的话实在太慢了。
举个例子,假设我们现在这个表有下面这些数据:
![](https://mmbiz.qpic.cn/mmbiz_png/PocakShgoGEDRrKUhdJJj0j170jAhFlSbD7VllcMdyDCv7u5uibFE8ap8oeMwAJEIdgBkgDuwJduQNBX0zs1ZTA/640?wx_fmt=png&wxfrom=5&wx_lazy=1&wx_co=1)
我们创建一个和当前表 `test_pk` 有相同结构定义的表 `test_pk2`
![](https://mmbiz.qpic.cn/mmbiz_png/PocakShgoGEDRrKUhdJJj0j170jAhFlSeBjnYFW3cvRcK1FYeCqgicPBdkvQGnbPSgvT86wAlgCFDBptIqEfYQA/640?wx_fmt=png&wxfrom=5&wx_lazy=1&wx_co=1)
然后使用 `insert...select``teset_pk2` 表中批量插入数据:
![](https://mmbiz.qpic.cn/mmbiz_png/PocakShgoGEDRrKUhdJJj0j170jAhFlSH2trqM0ibx9lc9E5ibicJWY9P4zdIdhRibYVhRfAdGg75k2gIoKasaQpEA/640?wx_fmt=png&wxfrom=5&wx_lazy=1&wx_co=1)
可以看到,成功导入了数据。
再来看下 `test_pk2` 的自增值是多少:
![](https://mmbiz.qpic.cn/mmbiz_png/PocakShgoGEDRrKUhdJJj0j170jAhFlSoibW63prO8Gice263E406BO5yLPksw8s2PO6KPAiaCdMM4KxaicoIvFGZw/640?wx_fmt=png&wxfrom=5&wx_lazy=1&wx_co=1)
如上分析,是 8 而不是 6
具体来说,insert…select 实际上往表中插入了 5 行数据 (1 1)(2 2)(3 3)(4 4)(5 5)。但是,这五行数据是分三次申请的自增 id,结合批量申请策略,每次申请到的自增 id 个数都是上一次的两倍,所以:
* 第一次申请到了一个 id:id=1
* 第二次被分配了两个 id:id=2 和 id=3
* 第三次被分配到了 4 个 id:id=4、id = 5、id = 6、id=7
由于这条语句实际只用上了 5 个 id,所以 id=6 和 id=7 就被浪费掉了。之后,再执行 `insert into test_pk2 values(null,6,6)`,实际上插入的数据就是(8,6,6):
![](https://mmbiz.qpic.cn/mmbiz_png/PocakShgoGEDRrKUhdJJj0j170jAhFlSWJhQcdACvDcD18fMz5PhdUuwp3RkTILHJkVpW2OcX6icMn1hcEvnlqA/640?wx_fmt=png&wxfrom=5&wx_lazy=1&wx_co=1)
### 小结
总结下自增值不连续的四个场景:
1. 自增初始值和自增步长设置不为 1
2. 唯一键冲突
3. 事务回滚
4. 批量插入(如 `insert...select` 语句)
----
>参考链接:[https://mp.weixin.qq.com/s/HvA4zdF4VOYrs2DQ93rfYg](https://mp.weixin.qq.com/s/HvA4zdF4VOYrs2DQ93rfYg)
---
title: 如何使学习变成一件很热血的事?
shortTitle: 如何使学习变成一件很热血的事?
description: 我有一个挺要好的朋友,在国内top3的互联网公司,做到架构师的位置。他是我生活中,唯一亲见的,“矮挫穷…
tags:
- 优质文章
author: 沈世钧
category:
- 知乎
head:
- - meta
- name: keywords
content: 学习,考研,学习方法,高效学习,教育学
---
我有一个挺要好的朋友,在国内top3的互联网公司,做到架构师的位置。他是我生活中,唯一亲见的,“矮挫穷”翻身赢取“白富美”的人。
朋友毕业于某二本院校。
大一的时候,刚开学,和所有的新生一样,迷茫,奔波于各种社团。其中认识一漂亮姑娘,特别巧,和他来自同一省、同一市、同一县。两家直线距离不超过30公里。
因此,朋友就想当然的认为,这应是一份天注定的缘分。自然,就动了追求姑娘的心。
朋友当时也挺中二,缺乏当面表白的勇气。最后,寻思了半天,竟写了一份情意绵绵的情书。不过,结果嘛,可想而知。
姑娘倒是一爽快人。没有回信,而是直接约他出来。没有套路,没有发“好人卡”,而是单刀直入的告他:
“我爸早说了,我们家三代以来,就没有出过身高低于1米七五的男人。我大学谈恋爱,他不管。但要是敢带回一小个子。到时候,别怪他给我脸色看。”
老实说,我这朋友长的不错,但就是身高不行(1米68)。其实到现在,我也没闹明白,为啥女孩子那么在乎男人的身高。但无论如何,姑娘是拒绝了朋友,甚至没给他留半点念想。
也许是受了感情挫折,也许是“顿悟”了什么。我这朋友,一下子退出了所有社团。从此,全身心的投入到学习之中。
后来,用他自己的话说。大学4年,他在学习上投入,可以用“废寝忘食”来形容。而这一点,在那所二本院校显得尤其珍贵。
大学四年。无论是他所在的班级,还是宿舍。大部分人,要么是整日打游戏,要么是忙于恋爱。甚或者是有些人,既不玩游戏,也不谈恋爱,但也不学习。就是天天躺在床上,用现在的话说,就是等死。
我这朋友,在这样的学校,甚至在大家的“嘲笑”中,他就像一个“异类”一样,拼命努力了4年。
其中,不仅学习标准课程,还自学了很多其他东西,包括web开发,移动开发等。
大学毕业,找工作的时候。他身边同学,4年来,是舒服了、是享受了,但此时却慌了。
他们中的大分部人,甚至没有勇气去面试一份开发相关的工作。少有些不甘心的人,此时,只好慌慌张张的报一个培训班。更多的人,则是收拾行装,一言不发的回老家去了。
多年以后,同学会上相遇,发现其中的大部分人,要么是进入体制内,要么是做点小生意,大都泯然与众生。虽然,个人有个人的幸福,但唯一遗憾的是,亏了大学四年所学的专业。
而我这位朋友,则根本就没有参加学校的招聘会,直接奔北京而来。
因为学校一般,所以刚开始也没拿到大公司的offer。但好歹,因为扎实的技术,中小公司的offer,到手的却不少。
但有时候,不得不承认,人不仅要有实力,运气也是不可或缺的。
就在我这朋友拿到offer,选定一家公司,入职前,最后一次回老家。在火车上,朋友遇到了他一生的第一个贵人。
火车上,邻座的小伙打开笔记本,调试一段程序。朋友看到,觉得是同道中人,于是就攀谈起来。聊得内容主要是技术相关,聊得很嗨,也很深入。
快下车前,小伙问朋友目前在哪里工作,朋友说目前还在找。小伙子一惊,说真巧,公司内部正在招人,让朋友把简历发他,内推下。
就这样因缘际会,在小伙子的内推下,朋友获得了宝贵的一次面试机会,一家中国顶级的互联网公司。
也亏得朋友4年来的辛苦学习,一路过关斩将,最后顺利拿下Offer。
接下来的5年时间,朋友在工作中自是努力异常。当然,生活也没亏待他,也攒下了不少的钱。
如果,故事到此结束,其实挺无趣,不过是另一个平常的,有关“奋斗”的故事。然而这个还有更多。
工作5年,加上大学4年,9年时间过去了。朋友竟然还对那位女神“念念不忘”,虽然她曾经残酷的拒绝过他。
工作5年,有了经济支撑,再加上理工男的精密,此时,朋友开始有条不紊的“改造”自己。
首先,就是开始系统健身,花钱请了私教。因为朋友的身材不高,所以就更需要在体型上下功夫。
同时,也不知道他从哪里获得的信息。哥们重新设计形象,包括发型,服装,甚至还留了小胡子。
这样,过了段时间,再见朋友,所有人都惊叹:哥们从原来,一个“腼腆”的理工男,摇身一变,成了“型男”一枚。
虽然,个子依然是不高,但得益于发型和服装的搭配,再加上健美的身材,以及本就不错的脸蛋。哥几个都调侃他,现在如果不做IT,绝对可以混时尚圈了!
然而,这一波操作还没有结束。没过多久,哥们竟不声不吭的提了一宝马(3系)。至此,一切到位。大家可以在脑子里,想象一下小伙的形象:顶级互联公司、多金,型男、宝马。
一切到位,朋友就开始对女神的追求。
其实,毕业这5年。朋友一直没少关注女神的动向。知道她也在北京上班,谈过一段恋爱,但目前还是单身。
至于朋友如何追求的,其中的细节,作为局外人,知道的自是不多。只记得,大概半年后,一次聚会,他带来一姑娘,手挽着手。
见了姑娘,所有的人都眼前一亮。不得不承认,真是漂亮。哥几个,说实话,不眼红,那是假的。但再看朋友的形象,酷毙的型男,俩人站一块,真心不违和。
自此之后,多年过去,朋友也已升职为架构师。即使和圈内的朋友相比,收入也是靠前的。在西二旗也买了房子,孩子也快上幼儿园了。一家人出游,煞是让人羡慕。
后来,朋友再聚会。原来的女神,他现在的老婆还调侃他。说自己眼光有多好,多旺夫。要不是她,估计朋友还是穷屌丝一枚。朋友们听了,虽然知道说笑的成分居多,但从某个角度,确实是她成就了朋友的今天。于是都连声附和:“是是,确实没错”!
最后,再回到本问题:“如何使学习成为热血的事情?”
其实,参照我朋友的经历,本已不需要太多言语,因为学习本身就是一件“热血”的事。正如宋真宗劝人读书的那首诗:
**书中自有黄金屋,书中自有颜如玉。**
**男儿欲遂平生志,五经勤向窗前读。**
古人心善,诚不我欺!
>参考链接:[https://www.zhihu.com/question/39732240/answer/541429211](https://www.zhihu.com/question/39732240/answer/541429211),整理:沉默王二
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册