剑指Java面试-Offer直通车 笔记上

只是对剑指Java面试-Offer直通车这门课程做的笔记 如有侵权 立即删除

1-1 导学必看

 

   

   

   

   

   

   

   

2-1 网络基础知识讲解

2019年8月24日

19:45

   

为什么要学习网络呢?

底层都帮我们实现好了的

   

但是一旦遇到特殊情况 例如程序为什么会变慢 是因为网络的原因还是其它的原因 数据包有没有丢失。

为什么会出现大量的链接丢失 因此还是很有必要学习网络知识的 网络知识更偏向于理论

七层协议模型

   

从底向上讲解

   

第一层

机器a 向机器b 发送比特流 机器b需要收到比特流 这就是物理层

物理层主要定义了 物理设备的标准 例如网线的类型 传输介质的类型 主要作用是传输比特流 就是0101二进制数据 将其转换成电流强弱来进行传输

网卡就是工作在这层里面的

   

第二层

在传输比特流的过程中 会产生错传 数据传输不完整的情况 因此数据链路层定义了如何格式化数据 还提供了错误检测和纠正 以确保数据传输的可靠性 将比特数据转成了帧 其中交换机工作在这一层里面

   

第三层

随着网络节点的不断增加 点对点通信的时候 是需要经过多个节点的 那么如何选择最佳路径 这就是网络层做的事了

主要作用是将 网络地址翻译成对应的物理地址 并决定如何将数据从发送方路由到接收方 路由器属于网络层 此层的数据叫做数据包 ip协议

   

第四层

随着网络需求的进一步扩大 通信过程中需要发送大量的数据 可能需要很长时间 而网络在通信的过程中 会中断很多次 所以将这些数据进行切分 切分成segment进行发送 其中一个段落丢失了 该怎么办 需不需要重新传 这个就是传输层做的事 1500的数据包 进行分割

两个传输协议 tcp/udp

   

第五层

到了第四层我们已经保证 给正确的计算机发送数据 但是给用户的体验很不好 每次都会调用tcp协议去打包数据 然后再调用ip协议去找路由吗

所以我们需要建立一个可以自动收发包 自动寻址的功能

会话层的作用就是建立和管理 应用程序之间的通讯

   

第六层

现在已经保证 可以自动收发包和自动寻找的功能 现在要linux向window发送数据 两个系统语法不同 于是需要表示层 帮我们解决不同系统之间通信语法的问题

   

第七层 应用层

虽然发送方知道 自己发送的是什么东西 转成字节数组有多长 但是接收方不知道 所以应用层的网络协议诞生了 发送方和接收方都必须使用固定长度的消息头 消息头里面必须记录 消息长度等信息 就是请求体 请求头那些信息 该层最主要的是http协议

   

osi只是规定了 一种参考模型 具体实现是 tcp/Ip

   

   

   

2-2 TCP的三次握手

2019年8月24日

21:31

   

   

   

   

   

老师这里是直接在网络上抓包 来分析三次握手的过程

   

   

防止 seq乱掉 tcp会用这个序号来拼接数据 客户端和服务端 都需要拿到对方的seq

   

   

   

   

   

   

2-4 TCP的四次挥手

2019年8月24日

22:04

   

   

   

   

   

   

   

请看上图

利用这句话 去检查是否有大量的close_wait

   

   

   

   

2-5 TCP和UDP的区别

2019年8月24日

22:41

   

比起tcp 结构简化了很多

checkSum奇偶校验值

   

   

   

   

2-6 TCP的滑窗

2019年8月25日

10:57

   

   

   

   

左边是tcp发送端的缓冲区

   

   

   

   

   

2-7 HTTP相关

2019年8月25日

11:18

   

这里的无连接是每次链接只处理一个请求 服务器处理完了用户的请求 并收到用户的应答之后就会断开链接

现在的http默认使用长连接 就是默认等待一定时间后才会断开链接 keep-alive

现在都是以http1.1 为准 因为2.0版本 跨度太大 而且现在的1.1就已经满足目前的需求 2.0升级的成本太大了

如图

   

响应报文

   

   

   

   

   

幂等性 对数据库的一次操作或者多次操作的结果是一致的

安全性 没有改变数据的操作 因为get方式一般都是查询

post请求是作用在上一级的url上的 则每一次请求 都会添加一份新资源

   

   

   

   

   

   

   

   

   

   

   

   

   

   

   

   

   

   

2-9 HTTP和HTTPS的区别

2019年8月25日

12:48

   

   

   

在http中 即使是post请求 数据也都是明文传输 及其不安全

因此我们需要用到ssl

   

   

   

在三次握手中进行加密

   

   

   

   

   

   

2-10 socket相关

2019年8月25日

15:17

 

利用ip+tcp 来唯一标识网络中的一个进程

   

   

TCP server

   

客户端

   

UDP

   

   

   

   

2-11 网络知识总结

2019年8月25日

15:30

   

   

   

   

   

   

我们还需要知道ipv4 和ipv6的区别 还有各自的定义 这里没有讲

   

   

   

3-1 数据库架构

2019年8月25日

15:40

   

   

考察了我们对数据库的认识 模块化的思想

   

存储模块 将数据存入磁盘中

但是光有存储是不行的 还需要组织 并且以后还会用到这些数据 因此还需要用到程序实例 利用逻辑结构 映射到我们的物理结构

并且提供 管理数据的方式 这就是程序实例

   

存储管理:将数据的格式和文件的分割进行统一的管理

缓存机制:为了更快 将取出来的数据快存放在缓存里面

sql解析 :为了外界指令能够操作我们的数据库

日志管理:sql操作需要记录下来 方便我们查找错误 灾难恢复

权限划分:每一个人都有自己的权限划分 dba做的事情

容灾机制:还需要考虑到异常机制 当数据库挂掉了该如何恢复

索引管理: 提供sql查询的速度

锁管理: 并发

   

   

面试的重点模块:

索引模块和锁模块

   

索引的灵感来自与字典 快速的查找到我们需要的数据

问题1

   

问题2

索引最后好建立在一定范围内的数据

   

问题3

下面几节课都是利用这几个结构 来建立索引 并找出最好的结构

   

   

3-2 优化你的索引-运用二叉查找树

2019年8月25日

16:01

   

   

二叉查找树

对于树中的每一个节点x 左边小于父亲 右边大于父亲

例如查找6 会先经过5 找到7 再找到6

时间复杂度 O(logn)

   

缺点 数据库会经过删除和插入等操作

   

因为每次都会io 从文件系统里面读取数据 每一层都会这样

但是由于二叉树只有两个节点 但是数据库里面块有很多 导致了二叉树的层次非常高 因此效率大大降低

就会想到Btree了

   

   

3-3 优化你的索引-运用B树

2019年8月25日

16:07

   

如果每一个节点最多有m个孩子 那么这样的树就是m阶b树

下面就是3阶B树

每一个存储块(树节点)尽可能存储多的信息 降低io次数

   

   

   

   

   

3-4 优化你的索引-运用B+树

2019年8月25日

17:39

   

   

B+是B树的变体

   

叶子节点才存放值 这里的Q就是具体的数据 非叶子直接只存放索引 因此非叶子节点能够存储更多的关键字了 树更矮了

叶子节点都是按照大小顺序来做排列的 链接起来的作用是方便我们直接在叶子节点里面做统计 因为我们知道下一个叶子节点的指针 而不是回到根部再去检索了

   

   

   

   

3-5 优化你的索引-运用Hash以及BitMap

2019年8月25日

18:03

   

   

   

   

数据的值 如果是固定的话 可以考虑BitMap 目前Oracle中有该索引

通常使用的索引结构 就是B+树

   

 

 

3-6 密集索引和稀疏索引的区别

2019年8月25日

18:20

   

   

密集索引的概念是 叶子节点保存的不仅仅是键值 还保存了位于同一行记录里的 其它列的信息

一个表里面只能创建一个密集索引

   

稀疏索引:叶子节点只保存了键位信息和该行的地址

   

总的来说 密集索引的叶子节点里面有键值,有数据 而稀疏索引里面只有指向数据的地址

在mysql中 主流的引擎myisam 和 innodb

   

左边是innodb 右边是myisam

   

实战演示

第一张表

第二张表

.frm是 表的结构文件

.ibd 是innodb的 就是person的数据和索引 这里person表中有很多数据 shop表中没有数据

.MYI 是myisam的 代表索引

.MYD 是数据 这里为0 因为没有数据

   

   

   

3-7 索引额外的问题之如何调优Sql

2019年8月25日

18:37

   

   

   

索引能够避免全表扫描去查找数据 提高搜索效率

由索引衍生出来的问题

第一个问题 优化sql

1.使用慢日志定位sql

下面使用一个例子来展示这个思路

慢日志就是用来记录执行比较慢的sql 分析他的原因

第一个是 10s 代表如果超过了10s就会被记录到慢日志里面 一般设置为1s钟就认为慢了

除了上面的变量 我们还需要了解系统的状态

这个就是慢查询的数量 注意这个是本次会话 慢查询的条数 一旦重启客户端 就会清空

   

先打开慢查询 还有设置慢查询时间

   

我们还可以直接修改my.ini 修改配置

重启数据库

   

制造慢查询 先插入数据 这里老师插入了两百万条数据

   

打开日志 大概花费了 6s才查询出来

   

第二步:

利用explain 去分析这条sql语句

   

最优到最差

这里的type=all 代表本次查询走的是全表扫描

   

extra

   

第三步

修改sql 尽量让sql走索引

   

因为account是唯一索引 我们可以将name替换成account

   

第二条语句虽然还是慢查询 但是速度比之前的快了很多

   

但是有时候 就是需要利用name来进行排序 这时我们就可以给name添加索引了

这一次更快了

   

这个会走account的索引 而不是id shop是myisam引擎

因为我们的查询优化器来做决定的 mysql的查询优化器的目标是尽可能的走索引 而且是最严格的索引来消除尽可能的数据行.

这里因为密集索引的叶子节点 把其它数据也存放到了叶子节点当中 因此效率要不稀疏索引要低

   

   

3-8 索引额外问题之最左匹配原则的成因

2019年8月25日

21:28

   

   

联合索引就是多个列组成的索引

   

这个就是联合索引

当我们where 两个条件的时候 走的就是这个联合索引 注意这两个条件就是索引字段

   

如果我们把title给去掉 依然走的是联合索引

   

当我们只保留title就会发现不会走索引了 走了全表扫描 这个是最差的性能

   

   

产生的原因

mysql创建复合索引的规则 是首先会对复合索引最左边的 索引字段进行排序 在第一个排序字段的基础上 再对第二个索引字段进行排序 类似order by

所以第一个字段是绝对有序的 第二个字段是无序的了 因此使用第二个字段使用条件判断是用不到索引的 这个就是联合索引最左匹配原则

   

   

   

   

3-9 索引额外问题之索引是建立越多越好吗

2019年8月25日

22:07

   

   

答案肯定不是

   

   

   

   

3-10 锁模块之MyISAM与InooDB关于锁方面的区别

2019年8月25日

22:09

   

   

   

问题一:

利用实际的例子 进行讲解

打开多个会话 模拟并发

两张表 引擎不同

   

   

先讲 myisam引擎

一边查询1-2000000

当一边正在查询大量数据 另一边进行更新时 会发现表级锁 因为我们更新的是2000001 所以是表级锁

这样可以显示的加上读锁

直到我们自己释放读锁

   

读锁又叫做 共享锁 当两边都是读操作的时候 即使加了锁 也不影响

上面都是先上读锁 再上写锁的情况 下面是先上写锁

   

会等待前面的update语句执行完成 再执行select

   

两个写锁 写锁又叫做排他锁 需要先把之前的执行了 才执行后面的

   

添加for update 就可以给select上排他锁了

   

   

innodb

innodb支持事务

我们需要先关闭 自动提交 注意这个只是在当前session里面有效

因为mysql底层对select做了优化 这样才能加共享锁 lock in share mode

先执行上面的 再执行下面的 就会发现锁住了

当commit之后 update语句才能够成功

当我们不走索引的时候innodb还是会用到表级锁 走索引的时候是利用行级锁

   

X是排他

   

   

select count的时候

myisam提供了一个变量保存表的行数 但是innodb每次都是重新扫一道表的

   

   

   

实际操作乐观锁

这个是程序1

先不执行 这时程序二 进行操作

程序二先执行了

回到程序1 就会发现未更新 这时用户程序按照自己的业务逻辑去做处理

   

   

   

   

   

   

   

   

   

   

3-12 锁模块之数据库事务的四大特性

2019年8月25日

22:30

   

   

   

持久性代表一个事务一旦提交 他对数据库的修改是持久的 当系统或者介质出现故障的时候 确保已提交事务的更新不能丢失 持久性主要在于dbms的恢复性能

innodb来讲 就会将所有的操作 写入一个专门的文件 并在数据库启动的时候从此文件进行恢复操作 这个文件就是redo log文件 保证了innodb的持久性

   

   

3-13 锁模块之事务并发访问产生的问题以及事务隔离机制

2019年8月25日

23:33

   

   

 

假设有两个事务 取款和存款

   

   

mysql tx的默认隔离级别 可重复读

设置隔离级别 为读未提交

创建一张表

   

脏读 一个事务读到另一个事务未提交的数据

   

一个session进行减少 但是未提交

另一个事务 读到了 未提交的数据

   

第二个隔离级别 读已提交 不允许事务读到其它事务未提交的数据

   

一个事务前后两次读取的数据不一致 重复读

不可重复读 使用可重复读事务隔离级别以上 来避免

   

   

   

幻读

   

当一个事务对数据库进行操作 发现只有3条记录 这个事务只想对这3条记录进行update 但是另一个事务又插入了一条数据

当第一个事务 更新之后就会发现多更新了一条 就好像出现幻觉一样

   

   

   

   

   

   

   

3-15 锁模块之当前读和快照读1

2019年8月27日

14:41

   

   

但是我们实际操作中 发现了mysql的innodb 的可重复读的事务隔离级别下就可以避免幻读

当前读就是加了锁的增删改查语句 当前读:就是读取了当前最新版本 并且读取之后还需要保证其它并发事务不能修改当前事务

   

快照读 就是不加锁 但是 不是在序列化的情况下 因为序列化会将所有语句加锁

快照读是为了提高并发性能的考虑 快照读有可能读的不是最新版本的数据

   

   

update允许实例

   

   

   

   

   

   

3-17 锁模块小结

2019年8月27日

15:20

   

   

   

   

3-18 关键语法讲解

2019年8月27日

15:21

   

   

   

创建表

   

   

   

注意这里只是一张表 所以select的列 里面只能有聚集函数和分组列

多表查询的话 就可以不止有

   

   

having

   

   

   

   

   

   

   

3-20 彩蛋之面试的三层架构

2019年8月27日

15:34

   

   

   

   

   

   

   

   

4-1 Redis简介

2019年8月27日

15:44

   

为了提升性能 都会在客户端和存储层中间添加一个缓存层

穿透就是缓存里面没有 就去存储层里面拿

key-value类型 简单的缓存就可以使用memcache

   

   

   

多路i/o复用

   

selector 监控这个文件是否可读 可写

   

   

   

4-2 Redis常用数据类型

2019年8月27日

15:59

   

   

这样就存放了一个建为name 值为redis的 string类型的值了

get name 就可以得到值了

替换成 memcache

对 数值类型进行 increment增加

   

redis里面的操作都是原子性的 我们可以不用考虑并发问题

   

现在有一个需求 记录每一个用户每天访问网站的次数 每次都会增加

redis底层是 c写的

   

第二种类型 hash

hmset 就可以添加一个对象

hget 得到该对象某个值

   

   

可以查找左边和右边 是有顺序的

lpush 插入在后面

利用 lrange进行取值 注意这里是后进先出的 是栈

使用场景 最新消息排行榜等功能 最近插入的消息 排前面显示

   

当添加重复元素 插入不了

sadd 进行插入

利用 smembers 查看元素

   

   

这个集合是有序的 从小到大 注意这个也是不允许重复

zset 前面的1代表分数 就是权重 权重越大的在后面 从小到大进行排序

   

   

   

   

   

   

   

   

   

   

   

   

   

   

   

   

4-3 从海量数据里查询某一固定前缀的key

2019年8月27日

21:19

   

   

先要问清楚面试官 数据量有多大

我们可以利用 keys parttern

老师之前插入了两千万条数据

   

这样 找到以k1大头的key 会发现卡住了 当redis里面的key非常多的时候 而且服务器上线了 所以不能用keys

   

   

   

我们可以使用scan指令

cursor就是代表上一次的游标 可以为0 就代表重新开始或者结束

scan一共返回了两个东西 第一个是游标地址

   

   

   

   

   

   

   

   

   

   

4-4 如何实现分布式锁

2019年8月27日

21:28

   

   

互斥 就是同时只有一个客户端才能拥有锁

安全 只能被持有锁的客户端删除 其它客户端不能删除

死锁 获取锁的客户端 因为出现异常而不能释放锁

容错 当部分节点出错之后 客户端还能获取锁和释放锁

   

   

当再次赋值时 就不能够被更改了

   

设置过期时间

   

上面的操作不能保证原子性 redis里面的操作大部分都是支持原子性的 违背了我们的初衷

下面的能够保证原子性

在10s内是不能改的 但在10s外就可以修改了

   

   

   

   

   

   

   

   

   

   

   

   

   

   

4-5 如何实现异步队列

2019年8月27日

22:24

   

   

   

   

   

   

如果不用sleep的话

30s 内阻塞直到队列有消息

   

   

   

如何实现一对多的消费队列 就是一个生产者多个消费者

   

利用subscribe 订阅频道

生产者 发送消息

   

如果需要解决这个问题 就需要使用专业的消息队列 例如kafaka activeMq

   

   

   

4-6 持久化方式之RDB(快照)1

2019年8月27日

22:30

   

   

   

   

来到redis服务器 修改rdb的配置

这个就是rdb持久化的策略了

900 1 代表900s内 如果1条是写入指令 就产生一次快照

当备份进程出错的时候 主进程就停止接受新的写入操作 保护持久化一致性的问题

对rdb文件的压缩

因为redis是单线程的 所以第一个方法save是不可以的 所以需要使用BGSAVE

   

   

   

自动触发rdb

   

   

写实复制

   

   

   

   

4-7 持久化方式之AOF以及混合模式

2019年8月27日

22:42

   

   

RDB是备份数据库的状态 而AOF是备份数据库的指令

AOF默认是关闭的 修改配置

   

   

先检查 AOF 再检查 RDB

RDB一般用于全量备份 AOF用于增量备份

   

   

   

   

   

4-8 Pipeline及主从同步

2019年8月27日

23:10

   

   

是否了解 redis的同步机制 是否了解主从同步

   

下面可以自己百度 老师这里只讲了 redis的主从同步原理

如何配置主从同步 如何配置哨兵 如何配置集群等

   

就是利用快照 从节点利用快照 进行同步

这里的M就是主 s代表从

会先经过全同步 然后增量同步

记住所有写操作是在master上进行 读操作是在子节点进行的

   

   

   

弊端是 不具备高可用性 当master挂掉之后 就不能支持写操作了

因此 sentinel 解决方案 就是redis的哨兵

使用流言协议 接受主服务器是否下线的信息 并使用投票协议 决定是否自动故障迁移 以及选举主服务器

区块链 就使用这个技术 去掉中心化 点对点的

   

   

   

4-9 Redis集群

2019年8月27日

23:51

   

   

就需要用到一致性hash算法了

可以用服务器的ip 或者主机名作为key 进行hash

顺时针旋转 哪个最近 选哪个

当c宕机了 只有c对象受到了影响 其它的不会受到

   

新加服务器 X 类似的

   

因为算出来的两台服务器 可能会很近的

使用虚拟节点技术

   

   

   

   

   

   

  

猜你喜欢

转载自www.cnblogs.com/alalajijun/p/12342968.html