参考自:链接
过期策略:
过期策略 | 解释 |
---|---|
定时删除 | 设置某个Key的过期时间的同事,创建一个定时器,到时间就删除该key |
惰性删除 | 设置key的过期时间后,再次使用该key时检查该key是否过期 |
定期删除 | 定期检查一些key,过期则删除 |
内存淘汰策略
淘汰策略 | 解释 |
---|---|
Volatile-ttl | 移除即将过期的Key |
Volatile-Lru | LRU移除设置了过期时间的Key |
Volatile-Random | 随机移除设置了过期时间的Key |
AllKeys-random | 随机移除Key |
allkeys-lru | Lru随机移除一个key |
noeviction | 不移除任何Key,返回一个错误码 |
http:应用层协议,在socket之上
TCP:传输层协议,对IP网络层的封装,可靠,面向连接
TCP四次挥手中存在以下两种概念
TIME_WAIT: 主动发送FIN端,等待2MSL后会自动断开连接,防止上一次连接中的包重新出现以影响本连接;大量的请求来到机器上,而服务方的socket资源已经消耗殆尽,因此就需要等socket的TIME_WAIT阶段结束才能够再次得到新的socket去处理请求;
CLOSE_WAIT:被动关闭端传送未传输完成的数据,未发送FIN信号;Server端未调用closesocket()方法;有可能是server端父进程将FIN信号交给子进程处理,处理完成后,子进程关闭了自身的socket,将引用计数器减1,但父进程依旧在运行,这样就多了一个处于CLOSE_WAIT状态的socket;
首先,为什么要有索引呢,假设我们需要查询一条记录
如果没有索引,我们就需要全表遍历,时间复杂度为O(n)
若加上二叉搜索树,时间复杂度就变成了 O(nlogn)
因此就需要上二叉树存储索引,但若id自增,二叉搜索树总会将我们的索引添加到右侧,就退化成了一条链表;
紧接着就有了二叉平衡红黑树的概念,在原有的二叉搜索树的基础上,解决上述退化成链表的行为,会自动左旋,右旋对结构进行调整,始终保证左子节点数目< 父节点数 < 右子节点数,但他根本上还是二叉树,数据量一大树的高度就会变大;
最后就有了B树,即多叉平衡红黑树,左右节点有相同的深度,叶节点为空,但在范围查找时,B树结构每次都需要从根节点查一遍,效率较低;
因此最后的最后,就有了B+树,仅有叶子节点存储记录,上层叶子节点仅存放索引信息,且叶子节点通过指针连接在一起;
联合索引是每个树节点中包含多个索引值,在通过索引查找记录时,会先将联合索引中的第一个索引列与节点中第一个索引值进行匹配,匹配成功继续匹配第二个索引以及索引值,直到联合索引的所有索引列都匹配完成;
思路:
解决方案:
表示查询中执行select子句或操作表的顺序。
id值越大优先级越高,越先被执行;
1)simple
简单select查询
2)primary
最外层的select查询
3)subquery
子查询中首个select
4)union
5)uncacheable
6)derived
查询出的结果集放到内联视图中;
被使用的表名
1)system
表仅有一行
2)const
使用唯一索引或主键
3)eq_ref
唯一索引和主键是多列时,只有所有的列都用作比较时才会出现eq_ref
4)ref
只要使用相等条件检索时就可能出现;
5)fulltext
全文索引检索
6)ref_or_null
在初次查找的结果里找出null条目,然后进行二次查找
7)index_merge
表示查询使用了2个以上的索引
8)unique_subquery
用于where的in形式子查询,子查询返回不重复值唯一值;
9)index_subquery
用于in形式子查询使用到了辅助索引或in常数列表
10)range
索引范围扫描
11) index
索引全表扫描
12) all
全表扫描数据文件
指出该表中使用哪些索引有助于查询
显示索引那一列被使用了;
需要扫描的行数
B+树本质上是多叉平衡B树,叶子节点存放所有数据,中间节点存放索引记录,有较低的树高,在范围查找以及精确查找上具有优势;
哈希索引会对要插入的数据进行哈希,但这样会使得原本有序的数据变得无序,因此对范围查找不太友好,但对精确查找十分友好;相比之下,哈希索引无法使用到索引,不支持多列联合索引的最左匹配原则,且存在哈希碰撞问题;
特性 | 解释 |
---|---|
A | 原子性,事务中的全部操作要么全部成功,要么全部失败 |
C | 一致性,所有事务对同一个数据的读取结果都是相同的; |
I | 隔离性,不同事务之间互不影响; |
D | 持久性,事务提交对数据的修改是持久的; |
隔离级别 | 解释 |
---|---|
读未提交 | 事务中的修改,即使未提交,对其他事务也是可见的 |
读已提交 | 事务仅能读取已经提交的事务所做的修改 |
可重复读 | 保证在同一个事务中多次读取结果一致 |
串行化 | 强制事务以串行的方式执行 |
策略 | 解释 |
---|---|
随机 | 随机选一个服务提供者 |
LRU | 选出最近最少使用的服务提供方 |
LFU | 选出最近使用次数最少的服务提供方 |
哈希环 | 对请求的ip进行哈希处理,将得出的值放置在哈希环上,选出顺时针遇到的第一个服务提供者 |
命令 | 解释 |
---|---|
top | 整体进程消耗(虚拟内存,CPU利用率,内存消耗,pid,用户) |
free | 内存 |
df -h | 硬盘 |
IO | iostat, ifstat |
聚簇索引:按照每张表的主键构造一颗B+树,同时叶子节点中存放的是行记录
非聚簇索引:在非聚簇索引上创建的索引称为辅助索引,非聚簇索引,叶子节点并不包含行记录的全部数据,叶子节点包含键值以及相应行的聚簇索引主键值;
校验和
序列号
确认应答机制
三次握手机制
超时重传机制
http1.1:
流水线
长连接
虚拟主机
多个TCP连接
http2:
二进制分帧层,分为首部帧以及内容帧;
首部压缩
多路复用一个TCP连接
服务端推送
i.浏览器请求服务器
ii.服务器发送公钥给浏览器
iii.浏览器生成秘钥并使用公钥加密传输给服务端
iv.服务器私钥接触秘钥
v.双方进行对称加密通信
使用redis的setnx实现,服务器A setnx进行上锁,服务器B就无法再获取这个锁,直到释放了锁或者超时;
写扩散:为每个用户维护一个订阅列表,记录该用户订阅的消息索引,用户发布消息时,都会去更新其follower的订阅列表;
读扩散:为每个用户维护一个发送列表,记录用户发送过的所有消息,假设用户订阅了1000个用户,则每次用户登录时均需要拉取这1000个用户的消息;
协程(轻量级线程) = 线程+ 分时
无内核态的切换
同一线程多次获取锁;
IO多路复用,同时监听多个socket,任一个socket变为可读就去处理它;
select, poll 同时监听多个socket直到任一个socket变为可读
查询顺序,先查内存,再查外存;
组建 | 解释 |
---|---|
Etcd | 存储集群中各资源对象信息 |
apiserver | 资源操作唯一入口 |
scheduler | 集群资源调度,将Pod调度到指定节点 |
ControllerManager | 维护集群状态,自动扩展,故障检测,自动更新 |
node | 为Pod提供运行环境 |
kubelet | 维护集群生命周期 |
kubeproxy | 提供集群内部发现以及负载均衡 |
kubectl apply -f xxx.yaml
kubectl get pods -n liyuan
kubectl describe -n liyuan xxx
docker pull xxx
docker run \ -itd xxx
docker ps -a
docker exec xxx /bin/bash
docker rm xxx
docker stop xxx
docker build
存储引擎 | 解释 |
---|---|
InnoDb | 支持事务,支持外键,支持索引,聚簇索引,支持行级锁(锁索引) |
MyISAM | 仅支持表级锁 |
package main
import "fmt"
type TreeNode struct {
Left *TreeNode
Right *TreeNode
Val interface{}
}
func NewTree(nums []interface{}) *TreeNode {
return construct(nums, 0)
}
func construct(nums []interface{}, index int) *TreeNode {
var n *TreeNode = nil
if index < len(nums) && nums[index] != nil {
n = &TreeNode{nil, nil, nums[index].(int)}
n.Left = construct(nums, 2*index+1)
n.Right = construct(nums, 2*index+2)
}
return n
}
func main() {
tree := NewTree([]interface{}{1, 2, 3, 4, nil, nil, 5})
ret := travsel(tree)
fmt.Println(ret)
}
func travsel(tree *TreeNode) []interface{} {
list := []interface{}{}
list = append(list, tree)
ret := []interface{}{}
for len(list) > 0 {
size := len(list)
for i := 0; i < size; i++ {
e := list[i]
//fmt.Println(e.(*TreeNode).Val)
ret = append(ret, e.(*TreeNode).Val)
if e.(*TreeNode).Left != nil {
list = append(list, e.(*TreeNode).Left)
}
if e.(*TreeNode).Right != nil {
list = append(list, e.(*TreeNode).Right)
}
}
list = list[size:]
}
return ret
}
func isSymmetric(tree *datastruct.TreeNode) bool {
return Symmetric(tree.Left,tree.Right)
}
func Symmetric(left *datastruct.TreeNode, right *datastruct.TreeNode) bool {
if left==nil&& right==nil{
return true
}else if left==nil||right==nil{
return false
}else if left.Val!=right.Val{
return false
} else {
return Symmetric(left.Left,right.Right) && Symmetric(left.Right,right.Left)
}
}
func QuickSort(nums *[]int) {
Quick(nums, 0, len(*nums)-1)
}
func Quick(nums *[]int, lo int, hi int) {
if lo >= hi {
return
}
par := par(nums, lo, hi)
Quick(nums, lo, par-1)
Quick(nums, par+1, hi)
}
func par(nums *[]int, lo int, hi int) int {
i := lo
j := hi
num := (*nums)[lo]
for true {
for i != hi && num >= (*nums)[i] {
i++
}
for j != lo && num <= (*nums)[j] {
j--
}
if i >= j {
break
}
swap(nums, i, j)
}
swap(nums, j, lo)
return j
}
func swap(nums *[]int, j int, i int) {
tmp := (*nums)[i]
(*nums)[i] = (*nums)[j]
(*nums)[j] = tmp
}
Mongodb: B-树,每个key和data在一起,无法使用区间查找,单次查询快;
Mysql: B+树,所有数据都存储在叶子节点,范围查询快;
func sortList(head *datastruct.ListNode) *datastruct.ListNode {
nums := make([]int, 0)
p := head
for p != nil {
nums = append(nums, p.Val)
p = p.Next
}
datastruct.QuickSort(&nums)
p = head
index := 0
for p != nil {
p.Val = nums[index]
p = p.Next
index++
}
return head
}
mysql引擎 | 描述 |
---|---|
InnoDb | 事务,外键,B+树索引 |
MyISAM | 不支持事务,B+树索引 |
Memory | 将表中数据存储到内存中 |
持续监听一组socket,每当有一个socket有数据过来时便去处理;
方法 | 描述 |
---|---|
select | 数组实现,长度为1024 |
poll | 链表实现 |
epoll | 已注册的描述符会在内核中被维护在一颗红黑树上 |
http | 描述 |
---|---|
http/1.0 | tcp短连接 |
http/1.1 | tcp长连接,Connection:keep-alive |
/**
* Definition for a binary tree node.
* type TreeNode struct {
* Val int
* Left *TreeNode
* Right *TreeNode
* }
*/
var sum int
func sumOfLeftLeaves(treeNode *TreeNode) int {
sum = 0
sumLeft(treeNode)
return sum
}
func sumLeft(treeNode *TreeNode) {
if treeNode == nil {
return
}
if treeNode.Left != nil && treeNode.Left.Left == nil && treeNode.Left.Right == nil {
sum += treeNode.Left.Val
}
//fmt.Println(treeNode.Val)
sumLeft(treeNode.Left)
sumLeft(treeNode.Right)
}
G:Goroutines,每个Goroutine对应一个G结构体,G保存Goroutine的运行堆栈,即并发任务状态;
M:Machine,寻找任务,负责任务调度
P:分配任务
协程是轻量级线程,为线程的分时复用;
为限制不同程序之间的访问能力,防止他们获取到其他程序的内部数据;所有用户的程序都运行在用户态,因此有时需要调用内核态时,如从硬盘读取数据,从键盘读取数据,会发生系统调用,CPU会陷入内核态,会使用内核的堆栈,因此需要将处理结果复制到用户程序中;
1)先淘汰缓存,再写数据库
2)先写数据库,再淘汰缓存
拉链法:将相同哈希值的数据存储在一个链表上;
开放地址法:以冲突的hash值作为起点,沿此序列逐个单元地查找给定的关键字,直到找到一个开放的地址;
拉链法(红黑树法)
头部
思路:快慢指针,slow一次走一步,fast一次走2步,当fast==nil时,slow即为中间节点;
给定一个二叉树和其中的一个结点,请找出中序遍历顺序的下一个结点并且返回。注意,树中的结点不仅包含左右子结点,同时包含指向父结点的指针
Thread.sleep()不会释放锁
虚拟机:在宿主机器,宿主机器操作系统的基础上创建虚拟层,虚拟化的操作系统,虚拟化的仓库;
Docker:在操作系统基础上创建docker引擎,直接在宿主机的操作系统上调用硬件资源,所以操作速度快;
inode table主要记录文件的属性以及该文件实际数据是放置在哪些block中;一个文件即一个inode
data block 放置文件内容数据的地方;
A:应用层
P:展示层
S:会话层
T:传输层
N:网络层
D:数据链路层
P:物理层
A:应用层
T:传输层
N:网络层
D:数据链路层
P:物理层
最左匹配原则:按照建立索引的顺序使用索引;
为了更好地使用索引,加快查询速度;
DNS 域名-> ip
TCP三次握手
HTTPS 交换秘钥
发起HTTP请求
返回HTTP响应报文
浏览器渲染
1)先更新数据库,再更新缓存
2)先更新缓存,在更新数据库
3)先删除缓存,再更新数据库
流量控制:控制收发双方速率,使得接收方速率可以跟上发送方速率;
拥塞控制:控制整个网络的拥塞程度
慢开始:一开始将窗口大小设置为1,每当收到一个ACK确认信号时,窗口大小*2直至到一个门限阈值,进入拥塞避免状态,若此时出现了超时情况,则将门限大小减半,并将窗口大小置为1;
快重传:接收方会对每次接收报文的最后一个已收到的有序报文进行确认,在发送方,如果收到三个重复确认,那就说明发生了丢包,此时执行快重传,立即重传下一报文段,且此时仅是丢失个别报文段,而不是网络拥塞,因此执行快恢复,令门限大小变为原来的一半,进入拥塞避免;
客户端发送SYN包,服务端收到后回复SYN+ACK,服务端进入SYN_RCVD态度,此时socket被放到半连接队列;
全连接队列:在上述基础上,服务端收到客户端ACK信号,socket会从半连接队列中移出到全连接队列;
参考 CLOSE_WAIT状态,服务端将数据发送完毕
二分法
package main
import "fmt"
type LRU struct {
head *Node
tail *Node
m map[interface{}]*Node
maxSize int
}
func NewLru(maxSize int) *LRU {
h := &Node{}
t := &Node{}
h.Next = t
t.Pre = h
ret := &LRU{maxSize: maxSize, head: h, tail: t, m: make(map[interface{}]*Node)}
return ret
}
func (self *LRU) Get(val interface{}) interface{} {
node, ok := self.m[val]
if !ok {
return nil
}
self.unlink(node)
self.appendHead(node)
return node.V
}
func (self *LRU) appendHead(n *Node) {
next := self.head.Next
n.Next = next
next.Pre = n
n.Pre = self.head
self.head.Next = n
}
func (self *LRU) unlink(n *Node) {
pre := n.Pre
next := n.Next
pre.Next = next
next.Pre = pre
n.Next = nil
n.Pre = nil
}
func (self *LRU) Put(K interface{}, V interface{}) {
if self.m[K] != nil {
self.unlink(self.m[K])
}
node := &Node{K: K, V: V}
self.m[K] = node
self.appendHead(node)
if len(self.m) > self.maxSize {
n := self.removeTail()
delete(self.m, n.K)
}
}
func (self *LRU) removeTail() *Node {
ret := self.tail
t := self.tail.Pre
self.tail.Pre = nil
t.Next = nil
self.tail = t
return ret
}
type Node struct {
Next *Node
Pre *Node
K interface{}
V interface{}
}
func main() {
lru := NewLru(3)
lru.Put(1, "111")
lru.Put(2, "222")
lru.Put(3, "333")
lru.Get(2)
lru.Get(3)
lru.Get(1)
fmt.Println()
}
接收方通过TCP报文段中的窗口字段高数发送方自己的窗口大小,发送方根据这个值和其他信息设置自己的窗口大小;
发送窗口内的字节都允许被发送,接收窗口内的字节都允许被接收,
若发送窗口左部的字节都已经发送且收到确认状态,则将发送窗口向右滑动一定距离,直到左部第一个字节不是已发送且已确认的状态;
若接收窗口左部字节都已经发送且确认交付主机,则向右滑动窗口;
写操作更新最新的版本快照
读操作去读旧版本快照
修改数据的操作会为数据行新增一个版本快照
MVCC规定只能读取已经提交的快照
MVCC的多版本指的是多个版本的快照,快照存储在Undo日志中,该日志通过回滚指针ROLL_PTR把一个数据行的所有快照连接起来;快照中除了记录事务版本号TRX_ID和操作之外,还会记录一位的DEL字段,用于标记是否被删除;
MVCC维护了一个ReadView结构,主要包括了当前系统未提交的事务列表TRX_IDs,还有该列表的最小值TRX_ID_MIN和TRX_ID_MAX;
进行select操作时,会根据数据行快照的TRX_ID_MIN和TRX_ID_MAX之间的关系,从而判断数据行快照是否可用;
含义 | 解释 |
---|---|
A | 原子性,事务被视为不可分割的最小单元,事务所有操作要么全成功,要么全部回滚失败 |
C | 一致性,数据库事务执行前后都保持一致性状态 |
I | 隔离性,一个事务所做的修改在最终提交以前,对其他事务是不可见的 |
D | 持久性,一旦事务提交,其所做的修改将会永远保存到数据库中 |
MYSQL默认AUTOCOMMIT,采用自动提交模式;
场景 | 解释 |
---|---|
缓存一致性 | 保证缓存中的数据与数据库中的保持一致 |
缓存并发 | 缓存过期或正在更新,此时有大量并发请求该key |
缓存雪崩 | 大量缓存同时失效,导致大量请求落到数据库中 |
缓存击穿 | 缓存key不存在,数据库中存在,直接访问数据库 |
问题 | 解决方案 |
---|---|
缓存击穿 | 设置热点数据永不过期;设置互斥锁 |
缓存雪崩 | 设置缓存数据过期时间随机,将热点数据均匀地分布在不同的缓存数据库中;设置缓存数据永不过期 |
缓存穿透 | 缓存和数据库中都没有的数据 |
1)ps -ef |grep xxx ;获取到应用的pid
2) top -p pid ;查看该进程的cpu,内存占有率
3)top -Hp pid查看当前哪个线程的使用率最高
优点:
1)可靠性:一台服务器的崩溃不会影响其余服务器;
2)可扩展性:动态添加更多的机器
3)资源共享:统一资源配置中心Apollo
4)更高的性能:计算机网络集群提供更高的性能
缺点:
1)故障排除
2)网络
3)安全性
元素 | 解释 |
---|---|
C | 一致性,多个数据副本是否能保持一致的特性 |
A | 可用性,系统一致都能提供服务 |
P | 分区容忍性,分布式系统中的节点被划分为多个区域,各个区域间可以相互通信 |
如何保证一致性
1)每次数据的修改都立即同步
2)异步,对于数据的修改,以异步的方式同步数据
雪花算法:id = 时间戳 + 工作机器id + 序列号
//TODO
线上开启slowlog,提取慢查询,然后仔细分析explain中tye字段以及extra字段,发生的具体场景及mysql是怎么做的
隔离级别/问题 | 脏读 | 不可重复读 | 幻读 |
---|---|---|---|
未提交读 | x | x | x |
提交读 | ok | x | x |
可重复读 | ok | ok | x |
可串行化 | ok | ok | ok |
SQL慢查询:
//开启慢查询
SET GLOBAL slow_query_log = ON;
explain 分析sql语句,查看type走索引的情况
修改SQL语句让其尽量走索引;
数据量较小的表无需建立索引
数据变化需要维护索引
slice,len,cap,共享,扩容
见linkedhashMap
分治策略
1)将大文件切分成n个
2)将每个文件内部进行排序
3)获取小文件中的最小值并写入结果集中
4)若干个index记录不同每一个文件到了那个下标,瑕疵再比较时就采取index所代表的数字;
alter table xxx add index©;
协议 | 描述 |
---|---|
tcp | 可靠,连接 |
upd | 不可靠,无链接(对实时性要求较高,但对质量要求不大高,直播) |
分布式一致性算法
/**
* Definition for a binary tree node.
* type TreeNode struct {
* Val int
* Left *TreeNode
* Right *TreeNode
* }
*/
func preorderTraversal(root *TreeNode) []int {
if root==nil{return nil}
stack := &Stack{}
stack.Push(root)
ret := make([]int, 0)
for !stack.IsEmpty() {
n := stack.Pop()
ret = append(ret, n.(*TreeNode).Val)
if n.(*TreeNode).Right != nil {
stack.Push(n.(*TreeNode).Right)
}
if n.(*TreeNode).Left != nil {
stack.Push(n.(*TreeNode).Left)
}
}
return ret
}
type stack interface {
Push(val int)
Pop() int
IsEmpty() int
Peek() int
}
type Stack struct {
data []interface{}
}
func (self *Stack) Push(node interface{}) {
self.data = append(self.data, node)
}
func (self *Stack) Pop() interface{} {
ret := self.data[len(self.data)-1]
self.data = self.data[:len(self.data)-1]
return ret
}
func (self *Stack) IsEmpty() bool {
return len(self.data) == 0
}
func (self *Stack) Peek() interface{} {
return self.data[len(self.data)-1]
}
//func main() {
// s := Stack{}
// s.Push(1)
// s.Push(2)
// s.Push(3)
// println(s.Pop())
// println(s.Pop())
// println(s.Pop())
// println(s.Pop())
//}
分布式基础上
使用多个发号器
发号器1:发3的倍数
发号器2:发4的倍数
…
并将该号码以及映射的长连接存储在数据库中
链路追踪功能:
Spring Cloud Sleuth: Spring Cloud的分布式跟踪解决方案。
top
ps -ef|grep xxx
free -h
cat
vim
cp
ssh
netstat -ntlp
df -h
\r\n
标记-清除
1)开始标记(STW)
2)清除未标记对象
三色标记法:
最开始所有对象都是白色,并将全局变量和栈中的对象置为灰色;接着将灰色的对象全部置为黑色并将之前灰色指向的变量也变为灰色;可异步执行;
抽取出共同行为
apiVersion: apps/v1
kind: Deployment
metadata:
name: nacos
namespace: liyuan
labels:
app: nacos
spec;
selector:
matchLabels:
app: nacos
template:
metadata:
labels:
app: nacos
spec:
volumes:
- name: application-conf
configMap:
name: nacos-application-conf
container:
- name: application-conf
configMap:
name: nacos-application-conf
containers:
- name: nacos
image: nacos/nacos-server
imagePullPolicy: IfNotPresent
ports:
- containerPort: 8848
name: nacos-port
env:
# 此处写成脱机版就可以使用内置的数据源,无需远程连接数据源
- name: MODE
value: "standalone"
resources:
requests:
cpu: "0.5"
memory: "1024Mi"
limits:
cpu: "0.5"
memory: "1024Mi"
列出当前操作系统已经打开的文件;
df
top
iostat
ifstat
一致性非锁定锁:一致性读不会给它所访问的表添加任何形式的锁,因此其他事务可以并发地修改他们;
悲观锁:处理过程中将数据加锁;
乐观锁:只有在提交更新的时候去检查数据库的状态;
记录锁:在索引记录上加锁;
间隙锁:在索引记录之间加锁
Next-Key Locks:在索引记录上加锁,并在索引记录之前的间隙加锁。
CAP:
C: 一致性,各个节点的数据需要保持同一时刻都一致;
A:可用性,任意一个节点挂掉不影响整个系统;
P:分区容忍性,允许系统通过网络协同工作;
二阶段提交:
(1)参与者将操作成败通知协调者,再由协调者根据所有参与者的反馈情况决定各参与者是否要提交操作还是终止操作;
AOF:记录下服务器处理的每一个写,删除操作;
RDB:在指定的时间间隔内将内存中的数据集快照写入磁盘;
对数据库的修改操作会写入binlog中,该binlog会发送到从数据库中,从数据库会执行binlog中的序列化操作,将数据写入到从数据库中;
(1)数据同步
master会启动一个线程2,生成RDB快照,并将新的修改请求都缓存在内存中;之后master会将RDB发送给slave,salve拿到RDB后会将该文件保存起来并将内存中缓存的那些命令都发送给slave;
(2)哨兵模式
集群监控:负责监控redis master和slave进程是否正常工作;
消息通知:若某个redis实例有故障,则哨兵负责发送消息给管理员;
故障转移,若master node挂掉了,会自动选出master节点;
胚子中心:若故障转移发生了,通知客户端新的master地址;
string
set
zset
hash
list
跳表
struct sdshdr {
// buf 中已占用空间的长度
int len;
// buf 中剩余可用空间的长度
int free;
// 数据空间
char buf[];
};
延长四次挥手时间,降低取消链接的速度;
为什么没有选择开源ELK体系,后续有了解吗?为什么要做重复造轮子的事情
goroutine在项目里面主要承担了什么责任
channel在项目里面是什么作用?
项目中正则处理火焰图是如何评估的?
有对比过其他库吗?
go开发多长时间了?
数组和切片的关系和区别
内存申请上有什么区别
函数传递有什么区别
切片底层的架构
如何把数组转化成一个切片
gmp模型说一下
服务能开多少个m由什么决定
开多少个p由什么决定
m和p是什么样的关系
同时启了一万个g,如何调度的?
go里面channel是什么样的概念
channel和共享内存有什么优劣势?
channel的底层有了解过吗
go里面interface是什么概念
相比于javac++interface有什么区别吗?
docker是基于什么来实现的
docker分层打包了解吗
docker怎么看日志
容器的cpu和内存占比
docker端口映射怎么看?
后续的技术规划是怎样的?
反问
你是这边项目的leader吗?
团队情况是什么样的?
面试的岗位是不确定的是吗?
会有月度谈话之类的吗?
您能说下您的工作经历吗?
京东云
实现lru,大概写下思路
自我介绍
项目介绍:问的比较细
devops相关
介绍下k8s的基础组件
k8s组件的职责
介绍下和k8s有关的项目
项目优化流程怎么做的?
问了很多项目细节
实时报警怎么做的
性能优化怎么做的?怎么发现问题的?怎么修复的?
项目里面你的职责主要是什么?
对linux常用命令熟悉吗
数组和切片的区别
线程和协程的区别
一个进程能创建多少线程受哪些因素的限制
golang用到哪些框架
反转单链表如何实现,口述一下
说一下上面lru算法的实现思路
你觉得java和golang有什么优势劣势?
旷视科技
快排
对docker和k8s使用多吗?使用到什么程度?
定制化开发了哪些功能?
监听pod状态变化是怎么实现的
对k8s使用了解到什么程度,组件这些
如果有一个节点不可用了,如何把pod驱逐到其他节点
kubectlapply和create有什么区别
如何更新一个k8s服务
pod里面可以有多个容器吗
pod内容器是相互隔离的吗
你们怎么去监控一个服务是否故障
容器日志是如何采集的,流程是怎么走的
dockerfile经常写,有什么常用命令
cmd和entrypoint有什么区别
介绍下在线上课的项目
对redis作为缓存使用熟悉吗?
雪崩、穿透、击穿说下以及如何解决预防
缓存淘汰机制了解吗,lru说下
golangwait.group用过吗?
go里面map是并发安全的吗?不是并发安全该如何使用?
读写锁说下
defer用的多吗?有哪些应用
异常捕获是如何做的?
常用的数据结构说下
redis跳表知道吗?
跳表和二叉检索树优劣
数组是如何实现用下标访问任意元素的
浏览器浏览网页前进后退如何实现?
如何查找一个无序数组的第K大元素
滴滴
写个二分查找
自我介绍
挑一个项目具体说下
怎么理解“不要用共享内存来通信,而是用通信来共享内存”
用过什么缓存?
redis是单线程还是多线程?
redis作为单线程,是怎么支持高并发的?
对内存操作更深入的了解过吗?
有没有想过内存操作为什么很快?
redis内存操作很快?有没有IO读写
IO读写什么时候会发生?
IO什么时候会做写入?
redis写入通信协议是什么?
redis写入操作IO操作快是因为异步
用go协程的时候也是要走IO的,go是如何处理的?
IO多路复用有看过吗?
redis的数据结构了解哪些?深入说下内部实现
跳表是一种什么结构?
扩展类型说下
hyperloglog详细说下
数据库用过哪些?
数据库引擎用什么?
怎么理解ACID这个概念
innoDB支持事务,他为什么支持事务?
看过B树B+树这些数据结构吗?理解不理解这些树的构造,是要解决什么问题?
说下对docker的理解,是解决什么问题的?
工作的时候用过什么消息中间件?
版本控制用的什么?
平时是怎么学习的?
自我介绍
你个人更偏好业务方向和基础架构方向?
挑一个对你来说有挑战的项目,说下其中的难点,是怎么解决的?
用redis在服务里面解决什么样的问题?
nodejs和go是基于什么样的考虑是用这两种语言的?
限制用户评论过去一个小时内只能评论三次,用redis实现?
mysql的存储引擎了解哪些?
mysql索引用过哪些?
了解过聚簇索引和非聚簇索引吗?
覆盖查询和回表查询了解吗?
分析sql性能好坏如何分析?
explain里面其他字段关注过吗?type字段关注过吗?
B+树和哈希索引区别是什么?
锁的类型用过哪些
什么叫悲观锁、什么叫乐观锁
乐观锁如何保证最终一致性?
事务的基本特性?解释一下
事务隔离级别有哪些?解释一下
分库分表分区有哪些差别?
分表遇到联表查询怎么分页?
shardingjdbc如何实现分页查询的?其内部偏移如何实现的?
除了用jdbc和中间件方式之外,分库分表下联表查询还有别的解决方案吗?
nginx用过吗?
大致了解nginx的哪些功能?
nginx的负载均衡是在第几层?
除了nginx的负载均衡还了解过其他负载均衡吗?
反向代理和正向代理有什么差别吗?
linux熟悉吗?
如何统计nginx日志里面的访问量最多的十个IP地址?
es用过吗?使用过哪些功能?
了解其内部实现吗?
es写入数据如何保证两边数据一致性,两边数据同时写入会越来越大?
自我介绍
对新的机会主要看哪些方面?
挑一个个人感觉比较满意,存在技术挑战的事情,说一下细节
在基础架构服务稳定性方面有什么总结吗?
如何保证服务高并发的?
细节的优化点有哪些?
golang垃圾回收机制了解吗?
mysql主键索引和非主键索引在搜索和检索过程中有什么区别吗?
事务的隔离级别有哪些?
脏读幻读说一下
mysql如何实现事务的?
mysql主从同步过程了解吗?
分库分表常用模式
一开始一个项目数据比较多,后来需要分库分表,有什么思路在不停服务的情况下做到平滑切换?
设计一个短链接服务
学而思
自我介绍
在第一家公司主要做些什么?
后端核心开发的项目是什么?
权限系统如何做?
接口权限如何做?
在线消息服务讲下
如何避免redis故障
日志监控怎么做的?如何设计的?
写入ES想过如何降低压力吗?
火焰图怎么来寻找瓶颈的?
gpm模型
如何实现一个线程安全的map
创建一个数组底层扩容
make一个slice参数怎么写?
mysql的索引结构
对b+树了解吗?
什么会影响联合索引查询效率
用栈实现队列
用栈能实现双向队列吗?
主要做哪些基础架构工作呢?
网易
自我介绍
未来的主要方向
介绍下之前的项目用到的优化点、难点
为什么不要大量使用goroutine
gpm模型
go里面goroutine创建数量有限制吗?
线程和协程有什么区别
golang支持哪些并发机制
go利用channel通信的方式
有缓冲和无缓冲channel的区别
channel实现原理
被close的channel会有什么问题
分布式锁知道哪些?用channel如何实现?
集群用channel如何实现分布式锁
并行goroutine如何实现
go用共享内存的方式实现并发如何保证安全?
go的锁是可重入的吗?
获取不到锁会一直等待吗?
那如何实现一个timeout的锁?
go切片是如何实现的
主要用redis实现哪些功能
缓存穿透如何解决
常用限流算法
令牌桶和漏桶有什么区别
不同服务之间通信有哪些方式
一次rpc要经过哪些过程
rpc框架如何做性能调优
用过哪些rpc框架
说下熔断、限流、降级、雪崩
熔断降级知道哪些开源框架吗?
docker和虚拟机有什么区别
serviceMash用来解决什么问题的?
devops相关技术有哪些
美团
自我介绍
监控软件用的什么?
为什么没用开源监控软件
现在的监控体系是什么流程?
为什么没用logstash?
非递归方式实现前序遍历二叉树
腾讯
算法lru
项目相关
go语言如何实现服务不重启热部署
go性能分析工具
tcp如何实现稳定性
http和http2区别
https如何实现的,证书是怎么获取的?
如何实现分布式锁
gpm模型
为什么gpm模型会更快?
线程协程区别
redis如何做到高可用
redis故障转移策略
kafka如何做到高可用
mysql事务的隔离级别
格步科技
自我介绍
用k8s主要做哪些功能?
链表和数组的区别,以及各种操作上的复杂度
谈下对散列表的理解,深入
对lru算法了解吗?在上面场景下使用呢?
说下你知道的排序算法
说下快排的大概的操作过程
快排的平均的时间复杂度
快排什么情况下是最慢的?
常用的数据库有哪些?
mysql的事务四个特性
mysql事务的隔离级别,分别解决了什么问题?
一条sql语句比较慢用什么方式去优化?
从浏览器上输入一个网址到浏览器加载内容,中间过程中发生了哪些事情?尽可能说知道的
nginx负载均衡策略
服务器上有大量time_wait状态,如何分析一下为什么会这样?
算法:一个奇怪的没听明白的问题
算法:括号匹配问题,说下思路
知乎
实现一个函数,有两个参数分别是升序的整数数组a和b,返回合并后的升序整数数组
待优化SQL
SELECTa,b,c,dFROMtb
WHEREc=4
ORDERBYa,b
索引
©
待优化SQL
SELECTa,b,c,dFROMtb
WHEREa=9ANDc=4
ORDERBYa,b
索引
(a,c)
待优化SQL
SELECTa,b,c,dFROMtb
WHEREb=9ANDa>4
ORDERBYa,b
索引
(a,b)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
说下项目
视频是如何做的?
展开讲下技术点和收获
知道mysqlinnodb是什么数据结构吗?
用基础数据结构实现一个map
map会遇到一些并发安全的问题,为什么就并发不安全了?
为什么给变量一个基础类型没有并发安全问题?
如何解决这个问题?
rpc底层实现
是如何做到和本地调用一样的?
rpc服务是如何找到其他目标服务的?
redis数据结构有哪些?
了解redis数据结构底层实现吗?
跳表是怎样的数据结构
为什么跳表查询复杂度很低
redis应用场景还有哪些?
httprestful的定义规范
常见的http状态码
golang介绍下gmp模型
自我介绍
说一个觉得不错的项目
说一下项目的业务场景
命令的时间差如何保证,命令混乱了怎么办(时间戳记录在服务器可以吗?)
最近在学习什么?
你个人最近感兴趣的点是什么?
docker是解决什么问题?
k8s是解决什么问题?
为什么现在考虑换工作
你想找什么样新的工作?
下一份工作看重什么?
如果说你现在定一个目标三到五年之后想要成为什么样子?
技术和业务方面的要求是什么?
如果让你选择只做技术和只做业务你选择哪个?
网易
自我介绍
有挑战性的项目介绍下
项目优化点说一下
tcp和udp有什么区别,在基础时间和传输层有什么区别
http和tcp有什么区别
用操作系统接口写过网络接口客户端
linux一般常用哪些命令
用netstat看tcp连接的时候有关注过time_wait和close_wait吗?
fork的底层实现方式
redis如何实现事务
复杂一点的条件,比如说判断一个数字大于多少如何实现事务?
如果要从redis里面删除大量的数据要怎么做?
list里面有大量数据,删除大量数据要注意什么
go语言的时候垃圾回收,写代码的时候如何减少小对象分配
string和byte数组有什么区别?
channel有缓冲和无缓冲在使用上有什么区别?
关闭channel有什么作用?
如果一个包要依赖另一个包,这个时候如何写单元测试
知道浮点数在机器上面怎么存储的
用go实现一个协程池,大概用什么实现
lru如何实现
反问:
这是交叉面试吗?
传媒部这边主要负责网易那块儿业务
技术部这边是往go这边切吗?
往go这边切的原因是什么?
百度
自我介绍
详细说下公司里面大的系统遇到的技术难点
消息转发用的什么技术
线上流量多大?
为什么不用一些更稳定的消息队列
go里面为什么需要多协程?
知道processor大小是多少吗?
goroutine为什么会存在,为什么不使用线程?
算法:二维矩阵顺时针原地旋转90度
算法:找出字符串中不包含重复子串的最大长度
redis的存储结构?
redis单线程为什么快?
k8s里面调度的关键步骤
猿辅导
自我介绍
说一下代表你技术能力的项目
你在项目里面的职责是什么?
cicddevops做了什么说一下
redis这边做了什么?
个人对mysql和redis细节了解吗?
redis的string是怎么存储的?
了解过redis的存储方式吗?
系统日志监控怎么做的?
已经上了k8s为什么不用推荐的开源体系?
有没有什么我没有问到你想说的技术点
算法:实现lru,不考虑线程安全,可以使用所有标准库
解释下你写的算法
算法:两个数组,求两个数组的交集
为什么map是O(1)的时间复杂度
实现map的方法除了哈希还有哪些?
高德
自我介绍
选一个比较熟悉的项目讲讲
筛选日志的时候,日志格式是不一样的,你们是如何处理的?
处理日志的时候如果日志量比较大会堆积吗?怎么处理的?
日志落盘到机器上,是如何采集的?
采集服务有问题的话可能会影响报警的及时性吗?
处理日志的时候如果发现突然量变大,该如何扩容让以前堆积的日志可以消耗掉?
调研的正则库内部是怎么实现的?
go里面比较成熟的日志框架了解过没有
redis发布订阅怎么实现的?你自己要怎么实现?
redis高可用怎么做?
了解redis主从复制机制吗?
分布式锁有哪些实现方式
redis的setnx底层怎么实现的?
go协程线程进程区别
详细讲下gmp模型
了解的gc算法有哪些?
go的gc原理了解吗?
go的init函数是什么时候执行的?
多个init函数执行顺序能保证吗?
gin框架的路由是怎么处理的?
mysql索引结构
B+树和B树有什么区别
快排
新浪
自我介绍
挑一个项目介绍下亮点和难点
说下websocket是哪一层协议?
osit层
常见http状态码
各种项目问题
进程阻塞怎么处理?就是进程完全不运行了,但是pid还在
CICD主要做了什么?
用火焰图的优势?
cgo了解过引入的风险点吗?
为什么不要频繁创建和停止goroutine
channel底层是用什么实现的?
数据库加密算法是怎么设计的?设计这种东西通用规范是怎么设计的?
在第一个公司为什么离开了
时间同步问题?
ntp协议
小米
自我介绍
算法:二分查找
sql索引优化问题
mysql数据库引擎
tcp三次握手四次挥手
项目用redis的原因
go的切片扩容机制
linux里面线程和进程的区别
go使用中遇到的问题
一个update语句的执行过程
websocket请求头
消息队列这些用过吗?
微服务注册发现说一下
说一下从浏览器按下一个搜索的完整过程
gomap的底层实现
说一下同步阻塞和异步非阻塞
go的profile工具?
字节
自我介绍
forrange坑输出
gmp模型
遇到过什么语法问题
对比下node和go
为什么用redis没有用成熟的kafka这些消息队列
redis的基础数据结构和底层实现
网关层限流,限流策略
消息重试,消息幂等问题
实现一个Promise.all
go实现一个并发限制爬虫
自我介绍
服务需要做迁移的原因是什么?
迁移主要写哪些服务?
自己做的定制化功能相对于开源的有哪些优势?
用过哪些开源的配置中心?
定时任务是一个什么场景?
日志扫描和处理怎么做的?
日志采集有哪些开源方案看过吗?
前端这边接触哪些?
前端这边用什么什么框架知道吗?
nodejs什么场景下用的?
给自己未来发展的定位是什么?
从技术角度讲对自己的要求是什么?
服务打日志的时候涉及过哪些中间件?
借助第三方自己产出的中间件有哪些?
参数检查中间件核心功能有哪些?
业务的npm包有哪些例子吗?
cicd做了哪些?
es存储日志的时长是多久?
es数据有做一些聚合吗?
说说火焰图?如何分析的?
写一个东西:一个字符串json,转成一个直接可用的map,字符串可能是任何形式
算法题:给一个字符串,从里面找到最长的回文字符串(先说思路)
挑一个比较突出的技术成就聊一下
websocket的稳定性是如何做的?
海外机器的延迟如何保证
为什么会选用websocket?
websocket兼容性是如何做的?
兼容性如何保证的?
如果现在选型的话会如何选?
能对比一下websocket、长连接、EventSource的优缺点吗
在前端如何处理websocket兼容性问题?
如何去设计兼容这一层?
你对前端这边了解到什么程度?
js原型链原型继承了解吗?
js变量提升作用域问题?
算法题:n*n的矩阵,按圈顺时针打印这个矩阵
写完之后做一些testcase,把需要的case都列一下
好未来
自我介绍
说一个项目的架构
go主要用搜框架
对go的中间件和工作机制有了解吗?
对数据库操作有什么了解吗
对连接池有了解吗?
go的垃圾回收机制
gmp模型
go的sync.Map了解吗
channel主要做什么事情
数据库这块儿mysql用的多吗?
存储引擎了解哪些?
对mysql索引了解哪些
redis的过期策略是什么?
微服务这边用到哪些?
算法:两个无序数组找到他们的交集
算法:分层遍历二叉树
常见的http状态码
tcp和udp区别
tcp三次握手四次挥手
业务迭代遇到过晚上上线的事情吗?
上线的时候业务中断有什么方式去规避吗?
k8spod切换策略
自我介绍
做过的项目说一下
怎么检查go问题
未来技术方向怎么选
gmp模型
切片的底层实现
go和node的差别
自我介绍
k8s如何找到一个节点上的所有pod
如何通过goclient写代码获取
日志监控怎么做的?
dockerfilecmd和entrypoint有什么区别
项目里面有自己独立负责的吗?
说下在线教室
如何保证连接的均衡?不至于所有连接连到一个地方?
调研的ocr识别是做什么?
做个题,看下这个这么写有什么问题
写个channel相关的题,并发模型,爬虫url,控制并发量
context包内部如何实现的?
自我介绍
你在第一家公司服务的用户是谁?
素质教育还是应试教育?
你在里面用技术解决什么问题?
这里面有什么你觉得做得比较好的项目?
视频用的什么服务?
信令用wss还是ws?
调度哪个用户连接哪个机器?
如果业务量大,如何让客户端能够均衡的连接服务器
wss是基于tcp的,tcp有个半连接队列,有没有遇到发了信令但是服务器没收到的情况?
自习和用户增长?
题拍拍主要做拍搜服务的,题拍拍主要做增长,后面会做微服务架构k8s等
考虑问题的时候从用户角度去考虑?用户是谁?为谁服务?
自我介绍
devops是怎么做的?
会保留一些tag、镜像之类的东西吗?
服务的属性配置用的什么?
docker是怎么做隔离的?
docker和宿主机有几种网络通信方式
k8s和pod什么关系?
k8s定义了什么标准来操纵docker
k8s有几种service类型
报警这边怎么做的?
为什么没有用ELK
go怎么实现封装继承多态
为什么go的变量申请类型是为了什么?