面试八股学习手册
网络
1.既然有HTTP协议,为什么还要有RPC
个人总结:
二者在服务发现、底层连接形式(TCP长连接,长连接池)上没有太大区别。
RPC定制化程度更高,可以采用体积更小的protobuf或其他序列化协议去保存结构体数据,同时也不需要像HTTP那样考虑各种浏览器行为,因此不需要复杂的请求头。因此性能也会更好一些,这也是在公司内部微服务中抛弃HTTP,选择使用RPC的最主要原因。
原文:
-
纯裸TCP是能收发数据,但它是个无边界的数据流,上层需要定义消息格式用于定义消息边界。于是就有了各种协议,HTTP和各类RPC协议就是在TCP之上定义的应用层协议。
-
RPC本质上不算是协议,而是一种调用方式,而像gRPC和thrift这样的具体实现,才是协议,它们是实现了RPC调用的协议。目的是希望程序员能像调用本地方法那样去调用远端的服务方法。同时RPC有很多种实现方式,不一定非得基于TCP协议。
-
从发展历史来说,HTTP主要用于b/s架构,而RPC更多用于c/s架构。但现在其实已经没分那么清了,b/s和c/s在慢慢融合。 很多软件同时支持多端,所以对外一般用HTTP协议,而内部集群的微服务之间则采用RPC协议进行通讯。
-
RPC其实比HTTP出现的要早,且比目前主流的HTTP1.1性能要更好,所以大部分公司内部都还在使用RPC。
-
HTTP2.0在HTTP1.1的基础上做了优化,性能可能比很多RPC协议都要好,甚至连
gRPC底层都直接用的HTTP2,但由于是这几年才出来的,所以也不太可能取代掉RPC。
2.SSL和TLS相关
TLS最常使用1.2版本 协议详解:blog.csdn.net/dream_caoyu…
3.从输入 URL 到页面展示到底发生了什么
zhuanlan.zhihu.com/p/133906695
4.网络传输中的粘包问题
看大家回答普遍认为粘包并不是个问题
5.TCP首部格式
6..tcp和udp能否共用一个端口号
可以,您可以对TCP和UDP使用相同的端口号。 许多协议已经这样做了,例如DNS在udp/53和tcp/53上工作。 从技术上讲,每个协议的端口池是完全独立的,但对于可以使用TCP或UDP的高级协议,它们的默认端口号是相同的。
数据结构
1.对数复杂度的数据结构
详解B树与B+树
(重点):为什么大家说mysql数据库单表最大两千万?依据是啥?
(重点):mysql的索引为什么使用B+树而不使用跳表?
面试|简单描述MySQL中,索引,主键,唯一索引,联合索引 的区别,对数据库的性能有什么影响(从读写两方面)
为什么mysql索引不用哈希表?
- hash索引无法进行范围查询,因为上述的hash结构是没有顺序的,hash索引只能实现等于、In等查询
- hash值是针对元数据的一种散列运算。hash值得大小并不能反应元数据的大小。元数据a 、b对应的hash值有可能是3333、2222,而实际上上a<b . 所以我们无法通过hash值进行排序,从而hash索引无法进行排序
- 对于组合索引来说,在B+Tree中我们有最左匹配原则,但是在hash索引中是不支持的。因为组合索引整个映射成hash值,我们通过联合索引中部分值进行hash运算得带的值与hash索引中是没有关系的
- hash索引在查询时是需要遍历整个hash表的。这点我们Java中的HashMap一样
- hash索引在数据量少的情况下比BTree快。但是当hash冲突比较多的时候定位就会比B+Tree慢很多了。
数据库
1.innodb页大小为什么16k(重点)
在操作系统的文件管理系统中进行一次io读写,默认读取的大小为4kb(一页)。 又因为局部性原理,操作系统会将命中的页周围的三块页一同加载进innodb的缓存池中,因此innnodb缓存池中页的大小为16kb
局部性原理是指CPU访问存储器时,无论是存取指令还是存取数据,所访问的存储单元都趋于聚集在一个较小的连续区域中。
2.MySQL事务隔离级别(重点)
juejin.cn/post/711449…
四个隔离级别是怎么实现的
3.15个必知的Mysql索引失效场景,别再踩坑了!
4.数据库查询习题
操作系统
1.堆和栈的区别
2.进程、线程、协程的区别
- 线程拥有自己独立的栈和共享的堆,共享堆,不共享栈。线程的切换一般也由操作系统调度。线程具有5种状态:初始化、可运行、运行中、阻塞、销毁。
- 对操作系统而言,线程是最小的执行单元,进程是最小的资源管理单元。无论是进程还是线 程,都是由操作系统所管理的。
线程的栈里有什么
线程的栈是一个比较“奇怪”的产物,一方面线程的栈是线程独有,里面保存了线程运行状态、局部变量、函数调用等信息。 另外一方面,从资源管理的角度而言,所有线程的栈都属于进程的内存资源,线程和父进程共享资源,进程中其它线程自然可以修改任意线程的栈内存
3.进程和线程间通信方式(大致看下)
juejin.cn/post/696912…
go提倡使用Channal通信,保留了共享内存+互斥量加锁的方式
4.linux查看cpu状态相关命令
5.Linux下查看占用CPU与内存最高的进程
项目
1.minio分布式部署的优势/为什么用nginx反向代理minio
参考:www.cnblogs.com/lvzhenjiang…
使用minio集群可以保证minio服务高可用,弹性扩展存储
使用nginx反向代理可以对外统一入口,配置负载均衡策略
2.鉴权相关
傻傻分不清之 Cookie、Session、Token、JWT
Go
1.哈希表原理
哈希函数:SipHash/ FNV
处理冲突的几种方法
主要有四类处理冲突的方法:
- 外部拉链法(常用):相同哈希值的键值对用链表来存
- 开放定址法(常用):找下一个空的地址,根据增量序列取法不同有线性探测、平方探测、伪随机探测等(注意,探测不会再次计算哈希)
- 公共溢出区(不常用):建立一个独立的公共区,把冲突的键值对都放在其中
- 再Hash法(不常用):换另外一个Hash函数来算Hash值
go的哈希表实现 Go 语言中使用拉链法来解决哈希碰撞的问题实现了哈希表,访问、写入和删除等操作都在编译期间被转换成了对应的运行时函数或者方法。
哈希在每一个桶中存储键对应哈希的前 8 位,当对哈希进行操作时,这些 tophash 就成为了一级缓存帮助哈希快速遍历桶中元素,每一个桶都只能存储 8 个键值对,一旦当前哈希的某个桶超出 8 个,新的键值对就会被存储到哈希的溢出桶中。
随着键值对数量的增加,溢出桶的数量和哈希的装载因子也会逐渐升高,超过一定范围时就会触发扩容操作,扩容时会将桶的数量分配,元素分流。元素再分配的过程也是在调用写操作时增量进行的,不会造成性能的瞬时巨大波动。oldbucket指向旧桶,bucket指向新桶,如果一个元素已经被evacuate拷贝到新桶,则在新桶中查询,否则在旧桶中查询。
2.golang new和make的区别(重点)
juejin.cn/post/714862…
我们使用new函数分配内存后,只有数组在初始化后可以直接使用,slice、map、chan初始化后还是不能使用,会触发panic,这是因为slice、map、chan基本数据结构是一个struct,也就是说他里面的成员变量仍未进行初始化,所以他们初始化要使用make来进行,make会初始化他们的内部结构
3. 整理Golang面试第二篇干货13问
cloud.tencent.com/developer/a…
4.GMP模型
缓存
(Redis面试问题)juejin.cn/post/684490…
1.什么是缓存雪崩、缓存穿透、缓存击穿、缓存预热(重点)
2.Redis优缺点和持久化方式
消息队列
1.kafka如何保证消费顺序
2.RocketMQ如何保证消费不重复不丢失
Kubernetes,云原生,RabbitMQ,nosql,raft一致性算法
一些算法
分解质因子
快速排序
本人面经
字节本地生活一面
- 介绍项目,技术选型及原因
- 了解哪些数据库索引,索引的数据结构(B+树),事务隔离级别
- 了解GMP模型吗
- golang的并发工具
携程酒店一面
由于携程主java,本人主go,就没问java上的东西
- 二叉树前序遍历(递归方法、栈方法 两种写法写一遍,快速排序,大致对就行不要求跑起来
- 数据库索引数据结构,事务隔离级别,隔离级别的实现方法
- 问项目,发布视频是否用到多线程,发布大视频怎么办
- 多线程是否了解?
- 场景题:酒店有很多房型,比如一亿个,很多房型的数据是重复的(对象的很多字段数据相同),如何优化存储
- 对相同的字段数据合并做哈希,生成的哈希值为键,值为对象 面试官nice,给了很多建议,指出我多线程方面知识需要加强