学习总结
- C++
- 1.C++面向对象三大特性
- 2.C++11特性
- 3.智能指针
- 4.进程地址空间
- 5.网络7层模型
- 6.五种io模型
- 7.reactor proactor
- 8.ET LT
- 9.内存泄露
- 10.tcp和udp区别
- 11.cookie 和session
- 12.vector底层实现
- 13.http get和post区别
- 14.孤儿进程和僵尸进程
- 15.在我们写程序的时候,为什么从来不用考虑寻址的空间大小?
- 16.什么是缺页中断
- 17.fork函数做了什么,写时复制
- 18.进程间通讯方式
- 19.http和https区别
- 20.io对路复用,三种方式区别
- 21.深拷贝和浅拷贝
- 22.TCP可靠传输原因
- 23.为什么要有 TIME_WAIT
- 24.悲观锁和乐观锁
- 25.死锁
- 26.3握4挥
- 27.指针和引用的区别
- 28.C++类中数据成员初始化顺序
- 29.const static用法
- 30.map和unorder_map底层实现
- 31.虚函数表实现原理
- 32.public private protected继承的区别
- Redis
- MySql
- 1.什么时候不走索引
- 2.为什么使用B+树
- 3.mysql事务回滚原理
- 4.mysql ACID
- 5.事务隔离级别
- 6.MCVV(多版本并行控制)
- 7.分库分表
- 8.跨库join
- 9.分布式系统事务一致性解决方案
- 10.主从复制保证数据一致性
- 11.mysql两种存储引擎及区别,底层实现
- 12.mysql索引,为啥要用B+树,红黑树为什么不行
- 13.怎么排查慢查询
- 14.explain字段
- 15.单库单表,如何平滑过度到分库分表?
- 16.数据库常见面试题
- 17.mysql io过高
- 18.回表与覆盖索引,索引下推
- 19.MySQL 行级锁,表级锁。意向锁 加锁时机是什么?
- 20.mysql主从复制
- 21.nosql
- 22.mysql怎么加锁
- 23.update 没加索引会锁全表
- 24.MySQL 记录锁+间隙锁可以防止删除操作而导致的幻读吗
- 25.mysql死锁
- 26.分表
- 27.mysql 强制走索引的方法
- 28.索引失效
- 29.mysql扫描怎么解决
- 30.mysql的索引中整数索引快还是字符串快
- 计算机基础
- 1.同步io,异步io,阻塞io,非阻塞io
- 2.阻塞和自旋
- 3.SOA架构与微服务架构
- 4.短链接服务
- 5.设计系统,Q币和礼物系统,如果出现支付延迟怎么办,考验分布式强一致性
- 6.进程,线程,协程区别
- 7.分布式系统理解
- 8.cap理论
- 9.最终一致性和实时一致性
- 10.实时统计每天pv uv
- 11.多数据源,数据同步出现问题怎么办
- 12.物理内存与虚拟内存
- 13.nginx负载均衡
- 14.cpu调度算法
- 15.代码上线后发现CPU使用率过高,怎么排查
- 16.堆和栈在内存中的区别是什么
- 17.死锁四个条件
- 18.什么导致线程阻塞
- 19.如何解决高并发减库存问题
- 20.一致性hash
- 21.进程间通信
- 22.接口调用保证幂等性
- 23.不使用中间变量交换两个数的值
- 24.设计一个排队系统
- 25.统计一个亿用户的日活
- 26.抢红包设计
- 27.2PC 3PC TCC
- 27.cap为什么只能满足两个
- 28.限流算法
- 29.进程间通信
- 30.怎么查看Linux服务器的负载
- 31.微博架构设计
- 32.守护进程
- 33.io多路复用
- 34.阻塞队列
- 35.分布式锁实现
- 36.父进程与子进程区别和联系
- 37.LNMP
- 38.倒排索引
- 39.设计模式原则 solid原则
- 40.安全漏洞XSS、CSRF、SQL注入以及DDOS攻击
- 41.cookie、session、token
- 42.零拷贝原理
- 43.用户\内核态切换
- 44.hash表时间复杂度
- 45.linux查看负载及端口
- 46.堆和栈的区别
- 47.场景设计
- 48.redis分布式锁,锁过期了,业务还没处理完,怎么办
- 49.服务容灾
- 容器
- 消息中间件
- 网络
- go
- 算法
- 映客
- 头条
- 一点咨询
- 探探
- 高德
- 牵手
- 搜狐
- minimax
- 虾皮
- 美篇
- 百川
- 百车宝
- 快手
- 米可
- 作业帮
- 滴滴
- 知乎
- 水印相机
- 腾讯会议
- 头条
C++
1.C++面向对象三大特性
2.C++11特性
3.智能指针
4.进程地址空间
5.网络7层模型
6.五种io模型
7.reactor proactor
8.ET LT
9.内存泄露
10.tcp和udp区别
11.cookie 和session
12.vector底层实现
13.http get和post区别
14.孤儿进程和僵尸进程
15.在我们写程序的时候,为什么从来不用考虑寻址的空间大小?
16.什么是缺页中断
17.fork函数做了什么,写时复制
18.进程间通讯方式
19.http和https区别
20.io对路复用,三种方式区别
21.深拷贝和浅拷贝
22.TCP可靠传输原因
23.为什么要有 TIME_WAIT
24.悲观锁和乐观锁
25.死锁
26.3握4挥
27.指针和引用的区别
指针是地址分配内存,引用是别名,指针可以换指向,引用从一而终,引用必须初始化而且不可以为空,指针可以多级,const,自增意义不一样。
28.C++类中数据成员初始化顺序
1 基类的静态变量或全局变量
2 派生类的静态变量或全局变量
3 基类的成员变量
4 派生类的成员变量
29.const static用法
30.map和unorder_map底层实现
31.虚函数表实现原理
32.public private protected继承的区别
Redis
1.Redis为什么快
1、完全基于内存,绝大部分请求是纯粹的内存操作,非常快速。数据存在内存中,类似于HashMap,HashMap的优势就是查找和操作的时间复杂度都是O(1);
2、采用单线程,避免了不必要的上下文切换和竞争条件,也不存在多进程或者多线程导致的切换而消耗 CPU,不用去考虑各种锁的问题,不存在加锁释放锁操作,没有因为可能出现死锁而导致的性能消耗;
3、使用多路I/O复用模型,非阻塞IO;
4、数据结构也帮了不少忙,Redis全程使用hash结构,读取速度快,还有一些特殊的数据结构,对数据存储进行了优化,如压缩表,对短数据进行压缩存储,再如,跳表,使用有序的数据结构加快读取的速度。
2.Redis五种数据结构
对外的数据类型:
String 整数,浮点数或者字符串,可以由简单动态字符串实现
Set 集合 可以由整数集合和字典实现
Zset 有序集合 可以有跳表和字典 或 压缩列表实现
Hash 散列表 可以由压缩列表和字典实现
List 列表 可以由压缩列表和双端联表
内部数据结构:
简单动态字符串(SDS),链表,字典,跳跃表,整数集合,压缩列表
3.Redis常用场景
1.利用List结构以及发布/订阅方式实现消息队列
2.利用zset实现排行榜
3.利用set nx ex 实现分布式锁
4.利用redis原子自增属性实现计数和限流
5.利用set结构的差并集实现共同关注和好友等功能
4.Redis内存淘汰策略
volatile-lru
从已设置过期时间的数据集(server.db[i].expires)中挑选最近最少使用的数据淘汰
allkeys-lru
从数据集(server.db[i].dict)中挑选最近最少使用的数据淘汰
volatile-ttl
从已设置过期时间的数据集(server.db[i].expires)中挑选将要过期的数据淘汰
volatile-random
从已设置过期时间的数据集(server.db[i].expires)中任意选择数据淘汰
allkeys-random
从数据集(server.db[i].dict)中任意选择数据淘汰
no-enviction
禁止驱逐数据,永远不过期,仅对写操作返回一个错误,默认为该项
5.持久化
1.RDB
2.AOF
参考
6.大Key删除
7.缓存穿透
客户持续向服务器发起对不存在服务器中数据的请求。客户先在Redis中查询,查询不到后去数据库中查询。
解决办法:
1.接口层增加校验,对传参进行个校验,比如说我们的id是从1开始的,那么id<=0的直接拦截;
2.缓存中取不到的数据,在数据库中也没有取到,这时可以将key-value对写为key-null,这样可以防止攻击用户反复用同一个id暴力攻击
3.利用布隆过滤器过滤不存在的数据
8.缓存击穿
一个很热门的数据,突然失效,大量请求到服务器数据库中
解决办法:
参考
9.缓存雪崩
大量数据同一时间失效
解决办法:
1.缓存数据的过期时间设置随机,防止同一时间大量数据过期现象发生,利用消息队列削峰。
2.保证缓存服务高可用,设置多个分片
10.redis主从同步
11.hash扩容
12.Redis 的key过期 怎么删除的 ?主动删除 和被动删除;
13.bgsave发生了什么
14.RedLock
MySql
1.什么时候不走索引
1、条件字段选择性弱,查出的结果集较大,不走索引;
2、where条件等号两边字段类型不同,不走索引;
3、优化器分析的统计信息陈旧也可能导致不走索引;
4、索引字段 is null 不走索引;
5、对于count(*)当索引字段有not null约束时走索引,否则不走索引;
6、like 后面的字符当首位为通配符时不走索引;
7、使用不等于操作符如:<>、!= 等不走索引;
8、索引字段前加了函数或参加了运算不走索引;
9、联合索引最左前缀原则,mysql会一直向右匹配直到遇到范围查询(>、<、between、like)就停止匹配;
2.为什么使用B+树
3.mysql事务回滚原理
undo redo
参考
4.mysql ACID
原子性:同一事务内的操作要么都成功,要么都失败,由undo日志保证原子性
一致性:一致性是指事务执行结束后,数据库的完整性约束没有被破坏,事务执行的前后都是合法的数据状态。数据库的完整性约束包括但不限于:实体完整性(如行的主键存在且唯一)、列完整性(如字段的类型、大小、长度要符合要求)、外键约束、用户自定义完整性(如转账前后,两个账户余额的和应该不变)。
隔离性:隔离性研究的是不同事务之间的相互影响。隔离性是指,事务内部的操作与其他事务是隔离的,并发执行的各个事务之间不能互相干扰。严格的隔离性,对应了事务隔离级别中的Serializable (可串行化),但实际应用中出于性能方面的考虑很少会使用可串行化。由MVCC保证。
持久性:事务一旦提交,其所做的修改会永久保存到数据库中,此时即使系统崩溃修改的数据也不会丢失。由redo日志保证。
5.事务隔离级别
读未提交:脏读,不可重复读,幻读
读已提交:不可重复读,幻读
可重复读:幻读
串行化:
脏读:事务A可以读取事务B未提交的数据
不可重复读:在事务A中先后两次读取同一个数据,两次读取的结果不一样,这种现象称为不可重复读。脏读与不可重复读的区别在于:前者读到的是其他事务未提交的数据,后者读到的是其他事务已提交的数据。
幻读:在事务A中按照某个条件先后两次查询数据库,两次查询结果的条数不同,这种现象称为幻读。不可重复读与幻读的区别可以通俗的理解为:前者是数据变了,后者是数据的行数变了。
6.MCVV(多版本并行控制)
7.分库分表
参考
垂直分表应用场景,利用消息队列数据解耦
8.跨库join
1.全局表
9.分布式系统事务一致性解决方案
10.主从复制保证数据一致性
11.mysql两种存储引擎及区别,底层实现
12.mysql索引,为啥要用B+树,红黑树为什么不行
13.怎么排查慢查询
14.explain字段
15.单库单表,如何平滑过度到分库分表?
16.数据库常见面试题
17.mysql io过高
18.回表与覆盖索引,索引下推
19.MySQL 行级锁,表级锁。意向锁 加锁时机是什么?
20.mysql主从复制
21.nosql
22.mysql怎么加锁
23.update 没加索引会锁全表
24.MySQL 记录锁+间隙锁可以防止删除操作而导致的幻读吗
25.mysql死锁
26.分表
27.mysql 强制走索引的方法
28.索引失效
29.mysql扫描怎么解决
30.mysql的索引中整数索引快还是字符串快
计算机基础
1.同步io,异步io,阻塞io,非阻塞io
2.阻塞和自旋
阻塞,线程被挂起,进入阻塞状态
自旋,不放弃CPU,一直重试
3.SOA架构与微服务架构
4.短链接服务
5.设计系统,Q币和礼物系统,如果出现支付延迟怎么办,考验分布式强一致性
6.进程,线程,协程区别
7.分布式系统理解
8.cap理论
9.最终一致性和实时一致性
参考
最终一致性可以依赖消息队列重试机制
实时一致性利用分布式事务框架
添加链接描述
10.实时统计每天pv uv
11.多数据源,数据同步出现问题怎么办
12.物理内存与虚拟内存
13.nginx负载均衡
14.cpu调度算法
15.代码上线后发现CPU使用率过高,怎么排查
16.堆和栈在内存中的区别是什么
17.死锁四个条件
1、互斥条件:一个资源每次只能被一个进程使用;
2、请求与保持条件:一个进程因请求资源而阻塞时,对已获得的资源保持不放;
3、不剥夺条件:进程已获得的资源,在末使用完之前,不能强行剥夺;
4、循环等待条件:若干进程之间形成一种头尾相接的循环等待资源关系;
18.什么导致线程阻塞
19.如何解决高并发减库存问题
20.一致性hash
21.进程间通信
22.接口调用保证幂等性
23.不使用中间变量交换两个数的值
a=a^b;
b=a^b;
a=a^b;
24.设计一个排队系统
25.统计一个亿用户的日活
26.抢红包设计
27.2PC 3PC TCC
27.cap为什么只能满足两个
28.限流算法
29.进程间通信
30.怎么查看Linux服务器的负载
31.微博架构设计
32.守护进程
33.io多路复用
34.阻塞队列
35.分布式锁实现
36.父进程与子进程区别和联系
37.LNMP
38.倒排索引
39.设计模式原则 solid原则
40.安全漏洞XSS、CSRF、SQL注入以及DDOS攻击
41.cookie、session、token
42.零拷贝原理
43.用户\内核态切换
44.hash表时间复杂度
45.linux查看负载及端口
46.堆和栈的区别
47.场景设计
TopK + LRU
48.redis分布式锁,锁过期了,业务还没处理完,怎么办
49.服务容灾
容器
1.docker实现原理
消息中间件
1.消息队列的用途、优缺点、技术选型
2.如何保证消息队列高可用
3.如何保证消息不重复消费
4.如何保证消息不丢失
5.如何保证消息按顺序执行
6.消息积压在消息队列里怎么办
7.什么是Zookeeper
8.zookeeper选举机制
9.zookeeper注册中心
10.Kafka 的ISR是什么,HW呢?怎么保证可靠性, Kafka 怎么实现顺序消息?为什么Kafka的broker上topic越多 效率越慢?
11.Kafka 讲一下,offset存储原理
12.kafka复制原理
13.kafka性能优化
14.kafka零拷贝和senffile
15.kafka PageCache
16.kafka11问
网络
1.tcp黏包
2.tcp三次握手
3.tcp半连接队列
4.http断点续传
5.dns除了域名解析还能干什么
6.tcp与udp
7.浏览器地址栏输入网址到看到页面的过程中都发生了什么
8.Time_Wait
9.HTTPS和HTTP区别
10.xss攻击
11.csrf攻击
12.502可能的原因有哪些
13.http状态码详解
14.拥塞控制
15.ddos攻击
16.rpc和rest
17.tcp标志位
18.为什么浏览器要限制跨域访问
19.https过程
20.http 1.0 1.1 2.0
go
1.go的调度
go的调度原理是基于GMP模型,G代表一个goroutine,不限制数量;M=machine,代表一个线程,最大1万,所有G任务还是在M上执行;P=processor代表一个处理器,每一个允许的M都会绑定一个G,默认与逻辑CPU数量相等(通过runtime.GOMAXPROCS(runtime.NumCPU())设置)。
go调用过程:
创建一个G对象
如果还有空闲的的P,创建一个M
M会启动一个底层线程,循环执行能找到的G
G的执行顺序是先从本地队列找,本地没找到从全局队列找。一次性转移(全局G个数/P个数)个,再去其它P中找(一次性转移一半)
以上的G任务是按照队列顺序执行(也就是go函数的调用顺序)。
另外在启动时会有一个专门的sysmon来监控和管理,记录所有P的G任务计数schedtick。如果某个P的schedtick一直没有递增,说明这个P一直在执行一个G任务,如果超过一定时间就会为G增加标记,并且该G执行非内联函数时中断自己并把自己加到队尾。
2.go struct能不能比较
可以能,也可以不能。
因为go存在不能使用==判断类型:map、slice,如果struct包含这些类型的字段,则不能比较。
这两种类型也不能作为map的key。
参考
3.Go struct/interface 最佳实践
4.defer+panic+recover
5.select用法
6.闭包
7.go类型转换
8.字符串拼接
9.slice
10.垃圾回收
11.Go语言中new与make的区别
12.map
13.channel
14.context
15.timer ticker
16.sync包
17.csp模型
18.goroutine
19.go是怎么运行的
20.go深拷贝与浅拷贝
21.M:N模型
22.Go的 channel和Unix 管道
23.sync.map底层实现
24.go map遍历顺序
25.init 工作流程
算法
1.LRU
最近最少使用淘汰策略
go实现
package lru
import "container/list"
type LRUCache struct {
capacity int
cache map[int]*list.Element
list *list.List
}
type Pair struct {
key int
value int
}
func Constructor(capacity int) LRUCache {
return LRUCache{
capacity: capacity,
list: list.New(),
cache: make(map[int]*list.Element),
}
}
func (this *LRUCache) Get(key int) int {
if elem, ok := this.cache[key]; ok {
this.list.MoveToFront(elem)
return elem.Value.(Pair).value
}
return -1
}
func (this *LRUCache) Put(key int, value int) {
if elem, ok := this.cache[key]; ok {
this.list.MoveToFront(elem)
elem.Value = Pair{key, value}
} else {
if this.list.Len() >= this.capacity {
delete(this.cache,this.list.Back().Value.(Pair).key)
this.list.Remove(this.list.Back())
}
this.list.PushFront(Pair{key, value})
this.cache[key] = this.list.Front()
}
}
2.leetcode402 移掉k位数字(字节
3.leetcode662 二叉树最大宽度
应该是用队列,类似层次遍历
4.查找最近公共节点
5.leetcode300 最长递增子序列
6.二叉树直径
7. 稳定排序和非稳定排序
选择排序、快速排序、希尔排序、堆排序不是稳定的排序算法,而冒泡排序、插入排序、归并排序和基数排序是稳定的排序算法
参考
8.大数据处理
9.快速排序
func partition(array []int, i int, j int) int {
//第一次调用使用数组的第一个元素当作基准元素
pivot := array[i]
for i < j {
for j > i && array[j] >= pivot {
j--
}
array[i] = array[j]
for i < j && array[i] <= pivot {
i++
}
array[j] = array[i]
}
array[i] = pivot
return i
}
func quicksort(array []int, low int, high int) {
var pivotPos int //划分基准元素索引
if low < high {
pivotPos = partition(array, low, high)
quicksort(array, low, pivotPos-1)
quicksort(array, pivotPos+1, high)
}
}
10.归并排序
func mergeSort(arr []int, start, end int) {
if start >= end {
return
}
mid:=(start + end) / 2
mergeSort(arr, start, mid)
mergeSort(arr, mid+1, end)
merge(arr, start, mid, end)
}
func merge(arr []int, start, mid, end int) {
var tmparr = []int{}
var s1, s2 = start, mid+1
for s1<= mid && s2<= end{
if arr[s1] > arr[s2] {
tmparr = append(tmparr, arr[s2])
s2++
} else {
tmparr = append(tmparr, arr[s1])
s1++
}
}
if s1<=mid {
tmparr = append(tmparr, arr[s1: mid+1]...)
}
if s2<=end {
tmparr = append(tmparr, arr[s2: end+1]...)
}
for pos,item:=range tmparr{
arr[start + pos] = item
}
}
11.heap包
func (h IntHeap) Len() int { return len(h) }
func (h IntHeap) Less(i, j int) bool { return h[i] < h[j] }
func (h IntHeap) Swap(i, j int) { h[i], h[j] = h[j], h[i] }
func (h *IntHeap) Push(x interface{}) {
*h = append(*h, x.(int))
}
func (h *IntHeap) Pop() interface{} {
old := *h
n := len(old)
x := old[n-1]
*h = old[0 : n-1]
return x
}
12.句子单词反转-微软
先翻转句子,再翻转单词
13.树的左右视图
层序遍历
14.手撕旋转打印矩阵
15.树里两个节点的最近公共父节点
映客
1.进程,线程,协程区别
2.用户态和内核态
3.线程不安全是什么
4.为什么要加锁
5.tcp和udp区别
6.面向字节流和面向报文区别
7.http和https区别
8.对称加密和非对称加密
9.MVCC是什么,解决什么问题
10.事务隔离级别
11.间隙锁
12.channel有缓冲和无缓冲区别
13.线程通讯方式
14.new和make区别
15.gmp模型
16.mysql索引
17.时间复杂度是什么,干什么用的
18.实现atoi itoa
头条
1.数据库慢查询
2.RR 可重复读
3.联合索引
4.kafka怎么保证不丢消息
见上
5.怎么保证数据库和es数据一致
可以利用消息队列的最终一致性
或者使用脚本进行同步拉齐
6.kafka怎么保证顺序消费
见上
7.用户打卡存数redis数据结构
hash
8.redis怎么防止单点故障
参考
master-slave模式,命令同步
一点咨询
1.项目
2.发号器
3.服务注册与发现
4.etcd
5.raft算法
6.负载均衡策略
7.一致性hash
探探
1.会员业务
2.线索平台迁移
3.发号器
4.分表,跨表查询
5.打卡功能实现
6.控制协程并发
7.gmp模型
8.goroutine生命周期
9.协程打印1-100
10.从数组中找翻倍的数
高德
1.排查线上负载
2.uuid应用场景
3.协程泄露
4.channel泄露?
5.mysql非唯一索引 delete加锁
6.抽奖无用请求怎么过滤 布隆过滤器
7.设计个协程请求服务超时处理
避免goroutine泄露,超时,优雅关闭
8.项目难点亮点
9.分布式任务调度
分布式锁
10.redis批量写入
11.统计uv
redis多个set或者bitmap或者hyperlog
参考
12.mysql索引怎么设计
13.channel结构和使用
14.网卡数据怎么读取
15.网络io
16.软中断硬中断
17.怎么查看进程打开的文件
牵手
1.select xxx from xxx where a = xx and b = xx order by c desc 怎么建索引
2.redis分布式锁
3.发号器实现 uuid 雪花算法
4.雪花算法是递增的吗
5.队列下游挂了怎么办
6.ab两路数据流合并成一路数据流,每次间隔x个a的数据,插入一个b的数据,x有10%、30%、60%的概率生成0、1、2,返回合并后的数据流,使用go代码实现
package main
import (
"fmt"
"math/rand"
"time"
)
/*ab两路数据流合并成一路数据流,每次间隔x个a的数据,
插入一个b的数据,x有10%、30%、60%的概率生成0、1、2,
返回合并后的数据流,使用go代码实现。*/
func main() {
a := []int{1, 2, 3, 4, 5}
b := []int{6, 7, 8, 9, 10}
fmt.Println(merge(a, b))
}
func merge(a, b []int) []int {
la, lb := len(a), len(b)
res := make([]int, 0)
i, j := 0, 0
for i < la && j < lb {
for x := getX(); x > 0 && i < la; x-- {
fmt.Println(x)
res = append(res, a[i])
i++
}
res = append(res, b[j])
j++
}
if i == la && j == lb {
return res
}
if i == la {
res = append(res, b[j:]...)
}
if j == lb {
res = append(res, a[i:]...)
}
return res
}
func getX() int {
// 设置随机数种子,确保每次运行生成的随机数不同
rand.Seed(time.Now().UnixNano())
// 生成一个范围在 0 到 100 之间的随机整数
randomNumber := rand.Intn(10)
if randomNumber < 1 {
return 0
} else if randomNumber < 4 {
return 1
} else {
return 2
}
}
搜狐
1.csp
2.sync.map底层
3.sync.map和map使用场景
4.数组和切片
5.怎么控制并发
waitgroup channel context
6.反向代理
7.nginx php扩展
8.数据迁移
9.分库分表怎么做
10.缓存服务设计
11.redis集群模式
12.rpc使用的协议
13.一致性hash
14.消息队列使用场景
15.消息队列怎么保证可靠性
16.消息队列怎么不丢消息
17.http2.0
minimax
1.goroutine泄露排查
2.goroutine泄露影响什么负载指标
3.gmp模型
4.分布式id几种实现方式和优劣
5.mysql慢查询排查
6.缓存强一致性怎么保证
7.消息队列解决一致性问题的优劣
8.缓存优化
9.缓存穿透
10.pprof接入
11.雪花算法时钟问题解决方案
雪花算法(Snowflake Algorithm)是Twitter开发的一种用于生成唯一ID的算法,主要解决在分布式系统中生成唯一标识符的问题。雪花算法生成的ID是一个64位的长整型(Long),包含了时间戳、数据中心ID、机器ID和序列号等信息。但是,雪花算法在系统时钟回拨的情况下会遇到问题,因为它依赖于系统时间来保证生成的ID的唯一性和顺序性。一旦系统时间回拨,就有可能生成重复的ID。
解决雪花算法时钟回拨问题的方法主要有以下几种:
阻塞直到回拨结束:当检测到时钟回拨时,可以简单地让生成ID的过程阻塞,直到系统时钟追上之前的时间点。这种方法简单直接,但在时钟回拨时间较长的情况下,会严重影响服务的可用性。
使用逻辑时钟:引入逻辑时钟的概念,逻辑时钟不会回拨。每次生成ID时,都将当前的逻辑时钟与系统时钟对比,如果系统时钟向前走,就更新逻辑时钟;如果系统时钟回拨,则逻辑时钟保持不变,并继续使用逻辑时钟生成ID。这种方法可以有效避免时钟回拨问题,但需要维护额外的逻辑时钟状态。
记录并使用最后一次的时间戳:在生成ID时,记录下最后一次使用的时间戳。如果检测到当前时间戳小于最后一次的时间戳(即出现了时钟回拨),则使用最后一次的时间戳加1来生成ID,并更新最后一次的时间戳。这种方法也可以在一定程度上避免时钟回拨导致的ID冲突问题。
异常处理和报警:在检测到时钟回拨时,立即记录日志、报警并采取一定的异常处理措施,如暂停服务或切换到备用策略等。虽然这不能解决时钟回拨问题,但是可以最大程度地减少其带来的影响。
使用其他ID生成策略:在对ID生成的实时性和顺序性要求不是非常高的场景下,可以考虑使用其他不依赖于系统时间的ID生成策略,如UUID等。
12.消息队列解耦和异步的区别
13.不可重复读和幻读区别
14.算法:蛇形矩阵
15.索引失效的场景
16.设计一个大模型交互的服务
虾皮
1.倒排索引原理
2.b+树增删改查
3.goroutine对比线程
4.GMP
5.Buffer Pool
6.课程表
7.熔断,降级,限流
binlog有几种格式
美篇
1.切片结构
2.切片是并发安全的吗
3.map遍历过程
4.map查找过程
5.设计一个并发安全的map
6.未初始化channel读写
7.怎么解决多路召回的数据写入
8.sync.pool
9.协程池
10.主键索引存储
11.数据页查找
12.m个n节点的链表合并,以及时间复杂度
13.二分查找
14.发号器(怎么支持高qps)
15.分布式锁(续锁,锁释放)
16.zookeeper,临时节点永久节点,znode,选举,怎么保证强一致性
17.慢查询(执行计划怎么看,字段,type排序)
18.索引下推
19.go内存分配器
20.runtime
21.raft协议
22.buffer.pool
23.b+高度,几次io
百川
1.公司内部消息队列
2.公司内部mysql有什么封装和改造
3.项目
4.索引优化
5.算法:码盘子
[1,2,3,2] => [2,2,2,2]
百车宝
1.es字段类型更改
在Elasticsearch中,直接修改现有字段的类型可能会导致错误,并且这种操作通常是不被允许的。但是,你可以在不影响线上服务的情况下使用以下步骤来修改字段类型:
创建一个新的索引,新索引的映射应该包含正确的字段类型。
将旧索引中的数据重新索引(reindex)到新索引中。Elasticsearch提供了一个内置的_reindex API,可以用来进行这种操作。
在数据重新索引完成后,你可以将旧索引删除。
更新你的应用程序,使其开始使用新的索引。
请注意,这个过程可能需要一些时间,具体取决于你的数据量。在此过程中,你的应用程序应该能够处理旧索引和新索引之间的切换。
再者,这种做法的一个缺点是,如果你的数据正在不断变化,你可能需要处理那些在重新索引过程中新增的数据。这可能需要你的应用程序有能力在两个索引之间同时写入数据,或者你需要暂停数据写入操作,直到重新索引过程完成。
2.延时队列实现
Redis 提供了一种数据结构叫 Sorted Set,可以用来实现延时队列。Sorted Set 可以为每个成员关联一个分数,我们可以利用这个分数来表示任务的执行时间。
创建延时队列的步骤如下:
1将需要延迟的任务序列化成一个字符串。
2将这个字符串添加到 Sorted Set 中,分数设置为任务的执行时间。Redis 提供了一个命令 ZADD 可以实现这个操作。
3另启一个线程,使用 ZRANGEBYSCORE 命令获取所有可以执行的任务(即那些分数小于当前时间的成员),并使用 ZREM 命令将这些任务从 Sorted Set 中删除。
4执行这些任务。
注意:这个过程可能会有并发问题。如果有多个线程都在获取和执行任务,可能会出现同一个任务被多次执行的情况。为了避免这个问题,我们需要在获取任务和删除任务这两个操作之间加一个事务。
另外,Redis 可能会因为故障导致数据丢失,如果任务的执行十分重要,可能需要在其他地方做持久化处理。
3.缓存实现
4.go内存分配
5.数据库索引变更不影响线上业务
数据库索引的变更可能会对线上业务产生影响,因为它可能会锁定表,导致对该表的读写操作被阻塞。为了避免这种影响,可以采取以下策略:
在线DDL:一些数据库支持在线DDL(Data Definition Language)操作。例如,在MySQL 5.6及更高版本中,可以使用ALGORITHM=INPLACE选项来创建或修改索引,这样可以在不锁定表的情况下进行索引变更。但是需要注意的是,不是所有的DDL操作都支持这个选项。
创建副本表:另一种策略是创建一个副本表,然后在副本表上进行索引变更。在副本表上创建好索引后,可以通过原子性的重命名操作将原表和副本表进行替换。这种方法的缺点是需要额外的存储空间。
分阶段操作:如果索引变更涉及到大量数据的修改,可以考虑分阶段进行。例如,可以先创建一个新的索引,然后逐步将查询语句改为使用新的索引。等所有的查询语句都改为使用新的索引后,再删除旧的索引。
使用工具:有一些工具可以帮助进行在线索引变更,例如,pt-online-schema-change是一个非常流行的工具,它可以在不锁定表的情况下进行索引变更。
请注意,任何索引变更都需要在测试环境中进行充分的测试,以确保不会对线上业务产生负面影响。
6.切片扩容原理
7.goroutine泄露排查
8.gin中间件实现原理
9.gin路由实现
压缩前缀树
10.切片排序实现
11.缓存容量不够怎么解决
冷热数据分离,增加建立缓存门槛
12.go 检测协程泄露
13.联合索引结构
快手
1.301 302区别
2.405
3.http 1.1->http2.0
4.头部压缩具体怎么做的
5.网络的io多路复用
6.et lt触发方式区别
7.redis string结构
8.秒杀系统分布式锁
9.怎么保证扣库存不出错
10.http1.1切换到http2.0
11.分表依据什么
12.最近的k个点
米可
1.gmp
2.为什么要有p这层
3.go垃圾回收
4.写屏障
5.channel有无缓冲区别
6.无缓冲区channel使用
7.关闭的channel读写
8.php和go区别
9.redis zset数据结构
10.跳表插入实现
11.hash结构
12.渐进式hash
13.rehash进度
14.mysql隔离级别怎么实现的
15.主从延迟怎么解决
16.缓存策略
17.聚簇索引和非聚簇索引
18.怎么减少回表
覆盖索引和索引下推
19.read view结构
20.time_wait过多是什么原因,有什么危害,怎么解决
21.服务注册发现
作业帮
1.设计树状结构存储,读多or写多场景
2.慢查询处理
3.优化器索引选择
4.算法:山峰数组排序
5.算法:abcdefg全排列
6.怎么去建设一个推荐服务
7.推荐内容去重
8.分布式锁实现方式
9.算法:最大的k个数组和,要求次序不变怎么实现
滴滴
1.gmp
2.一个协程发生系统调用时
3.kafka怎么保证顺序消费
4.算法:左视图
5.写sql
乘客表:乘客ID,乘客姓名
活动表:活动ID,活动名称,活动规则
参与活动表:乘客ID,活动ID,奖励金额
查询所有乘客(姓名)参与的活动名称以及获得的奖励
6.订单延时结算实现,以及问题
7.gmp handoff机制
知乎
1.gmp
2.垃圾回收
3.io多路复用
4.select为什么是1024个限制
进程的文件描述符上限默认是1024,数组写死