速记大纲呀

计算机网络

@OSI:物理层、数据链路层、网络层、运输层、会话层、表示层、应用层
@五层简化:物理层、数据链路层、网络层、运输层、应用层
@DNS在应用层

@IP协议
IP数据报头(20字节):版本、首部长度、区分服务、总长度、生存时间、协议、首部校验和、标识、片偏移
网络层协议:ARP、ICMP(Ping、Traceroute)、IGMP、NAT
路由协议:距离向量算法(基于BF,包括RIP、BGP等),链路状态算法(基于Dij,OFPF)

@TCP的手
三次握手:TCP 需要 seq 序列号来做可靠重传或接收,而避免连接复用时无法分辨出 seq 是延迟或者是旧链接的 seq,因此需要三次握手来约定确定双方的 ISN
SYN_SENT/LISTEN/SYN_RCVD/ESTABLISHED
SYN / SYN ACK / ACK
FIN / ACK / FIN / ACK
四次挥手:任何一方都可以在数据传送结束后发出连接释放的通知,待对方确认后进入半关闭状态。当另一方也没有数据再发送的时候,则发出连接释放通知,对方确认后就完全关闭了TCP连接
TIME_WAIT状态:确保ACK报文到达服务端、等待当前失效序号过期
端故障处理:定时器 + 超时重试机制
FIN_WAIT_1/CLOSE_WAIT/FIN_WAIT_2/LAST_ACK/TIME_WAIT

@TCP传输协议
检验和、序列号及确认、超时重传、滑动窗口、拥塞控制、流量控制
停止等待ARQ(超时重传)
连续ARQ(超时重传、发送窗口、累积确认)
流量控制:接收窗口window
拥塞控制:拥塞窗口cwnd、窗口上限ssthresh
慢启动(每个rtt有cwnd*=2)
拥塞避免(每个rtt有cwnd++)
拥塞发生(ssthresh = cwnd / 2)->(超时:cwnd = 1;快速重传:cwnd = ssthresh)
->快速恢复(cwnd = ssthresh + 3)
重传机制:回退N 、SACK选择确认(选择重传)
RTO计算:
SRTT = ( α * SRTT ) + ((1- α) * RTT)(加权移动平均)
Jacobson/Karels算法(考虑平滑差距作因子计算)
TCP报头:校验和、端口号、Seq号、Ack号、TCP Flag、Window

@UDP传输协议
DNS、TFTP、SNMP、NFS、音视频流

@HTTP
HTTP状态码
2xx 成功状态:200
3xx 重定向:301 永久移动 304 未修改
4xx 客户端错误:400 请求语法错误 401 要求认证 403 拒绝执行 404 未找到
5xx 服务器错误:500 服务器内部错误 501 不支持 502 远端无效响应
HTTP短连接(HTTP请求– TCP连接)与长链接(Session – TCP连接)(keep-alive)
HTTP无状态:Session保存在服务端内存、数据库中(redis),SessionID放在Cookie

@网络安全
HTTPS:SSL/TLS运行在TCP之上,采用非对称加密认证证书,对称加密具体传输内容
HTTPS过程:验证CA,生成随机码KEY作为对称密钥,从CA取出公钥加密KEY并发送给服务器,然后二者用KEY进行对称加密通信
CSRF跨域请求伪造:借用cookie伪造请求 //HTTP Referer、在请求中加入随机数、验证码
XSS攻击:反射型、存储型、DOM型 //编码、校验、http-only

@HTTP/2.0
将报文分为HEADERS帧和DATA帧,采用二进制格式,多路复用,只有一个TCP存在
首部压缩,客户端和服务器同时维护一个首部字段表
服务端推送,服务端可以主动推送内容

@分布式session方案:
反向代理固定映射到某服务器
session同步复制到其他服务器
利用中间件(如redis等)共享Session

操作系统

@内核 = 进程管理系统 + 内存管理系统 + IO管理系统 + 文件管理系统

@进程线程协程
进程通常作为分配资源的基本单位,有独立的堆栈,创建切换开销大
线程通常作为独立运行和独立调度的基本单位,只有独立的栈,创建切换开销小
协程是一种用户级的轻量级线程,线程按时间分片取执行协程代码段(只能串行,异步IO)
进程线程切换的区别主要在于虚拟地址空间(TLB表失效),进程信息表和文件表的切换
进程状态:创建状态、就绪状态、运行状态、阻塞状态、结束状态
孤儿进程(其父进程退出)、僵尸进程(未被父进程wait而占用进程号)

@ 进程间通信方式:
管道(环形队列):速度慢,容量有限
消息队列(消息队列)
信号量(计数器、锁机制):常用于同步
共享内存(最快IPC):需要保持同步
套接字(不同主机)(效率较高)
信号(异步通知)

@ 线程同步方式:
临界区:同一时间只支持一个线程进行访问
互斥量:只能为0/1,只能同一线程加解锁
信号量(PV操作):为非负整数,多个线程对资源的取放
事件:通知与唤醒

@ 锁机制(自旋锁、互斥锁、读写锁、条件锁/条件变量、两阶段锁)
自旋锁:非阻塞锁,不断消耗CPU时间,适合等待时间短或不常加锁的场景,单核不建议
互斥锁:阻塞所,进程直接挂起,适合等待时间长的场景
信号量:

@ 生产者消费者模型、哲学家就餐问题、读者写者问题

@ 权限管理
用户态:用户态运行的进程不能执行特权操作,不能读写内核区代码和数据
内核态:内核态运行的进程(操作系统或内核)可以访问计算机的任何资源,不受限制
用户态到内核态:
系统调用(主动请求)(同步或异步)(软中断、系统调用号eax、int 0x80、栈切换、syscall)(中断向量表->系统调用表)(场景:进程控制、文件操作、系统控制)
异常(被迫触发)(同步)(错误、陷阱、终止)
中断(外部内部事件引起)(软硬)(异步)(中断向量表IOT)

@ 中断处理过程:保护现场、开中断、中断处理、关中断、恢复现场

@ 进程调度算法:
先到先服务(FCS)(护航问题)
短作业优先(SJF)(理论周转时间最优、不实际)
最短完成时间优先(STCF)(抢占式)(周转时间最优)
时间片轮转调度(RR)(响应时间最优)
多级反馈队列调度(MLFQ)(兼顾二者)
(主动放弃CPU优先级不变)(时间配额用完即降级)(周期全体返回最高优先级)

@ 内核如何进程间切换
协作方式:等待程序进行系统调用主动交还控制权
非协作方式:利用时钟发出时钟中断,进入中断处理程序进入内核态进行调度

@ 死锁四条件:互斥条件、请求与保持条件、不剥夺条件、循环等待条件
破坏死锁条件:一次性申请所有资源、申请不到主动释放、顺序申请锁、超时放弃锁

@ 局部性原理:时间局部性、空间局部性

@ 内存管理
内存管理机制:块式管理(连续存储)、页式管理(离散存储)、段式管理、段页式管理
页式管理:静态/动态页面管理、地址变换、页表、快表(TLB)
虚拟地址(由内存管理单元MMU虚拟寻址)(系统安全,进程隔离,方便内存分配管理)
多级页表:PT1(10) / PT2(10) / Offset(12)(节省内存,只给真正有用的页提供索引)
页大小为4K(32位)或2M(64位),因为2*log2(X/4) + log2(X) = 32/64(两级页表)
分段:二维地址(段号+段内地址),需要显式进行分配,需要段表,大小可变

@ 虚拟存储器
请求分页存储管理:请求调页功能、页面置换功能、缺页中断
页面置换算法:最佳置换算法(OPT)、先进先出算法(FIFO)、最近最久未使用置换算法(LRU)、最少使用置换算法(LFU)
其他:请求分段存储管理、请求段页式存储管理
交换空间:在内存空间不足时把某些页内容转移到磁盘空间上

@ 直接内存访问(DMA)
在IO设备和内存进行数据传输的时候,数据搬运工作交给DMA控制器,CPU不需要参与

@ 零拷贝(不允许对文件进一步加工,应用于Kafka和Nginx等)
普通:硬盘->内核缓存区->用户缓存区->socket缓冲区->网卡(4次上下文,4次复制)
mmap + write:磁盘->内核缓存区->socket缓冲区->网卡(4次上下文,3次复制)
sendfile:同上3次复制,但仅需2次上下文
SG-DMA网卡:磁盘->内核缓存区->网卡(2次上下文,2次复制,无cpu搬运)

#C语言相关
@ 内存结构
代码区:可执行代码、常量字符串
静态区:全局变量和静态变量
栈区:局部变量、函数形参(从右往左入栈),地址从高往低,容量小
堆区:手动malloc分配和free释放,容量大

@ 函数库
静态库:在连接阶段目标文件将和库一起链接打包到可执行文件中,加载及运行速度快
动态库:在程序运行时动态载入,资源共享,减少磁盘及内存浪费,便于程序更新和开发

@ 堆和栈
堆内存由低向高增长,由程序动态分配
栈内存由高向低增长,调用函数时自动分配

Linux

@文件系统
目录项(dentry):文件名字、索引节点指针、其他目录项间的层级关联关系
超级块:文件系统详细信息、块个数、块大小、空闲块等
索引节点区:索引节点(inode)树,包括inode编号、数据在磁盘位置、文件大小等
数据块区:存储文件数据或目录数据
(目录inode指向的block记录该目录下所有文件的inode编号及文件名)

@文件存储
被占用数据块:数组方式、链表方式、索引方式(Unix采用多级索引方式)
空闲数据块:空闲表法、空闲链表法、位图法(Unix采用位图)

@IO方式(包括网络IO)
同步IO:BIO、NIO(IO多路复用,Netty框架)
异步IO:AIO(订阅通知)

@多路复用IO
select、poll:使用时把关注的Socket集合通过select/poll系统调用从用户态拷贝到内核态,当有IO事件发生时内核遍历该集合并设置状态,然后再拷贝回用户态供进程遍历使用;其中select与poll的区别在于分别用位图和链表来表示该集合
epoll:内核使用红黑树跟踪集合,用户向内核注册待监听的fd事件,内核向用户进程返回就绪链表,有水平/边缘触发
方式选择:连接数少但活跃用select,连接数多用poll,大量不活跃选边缘触发
Reactor事件驱动模型:接收器Acceptor接收连接并交由管理器Reactor管理, Reactor收到请求后调度具体的事件处理器handler,由handler对发生的事件作出处理(可以用多线程进行业务分离提高效率)

@Linux启动过程
主板上电,加载BIOS -> BIOS自检 -> BIOS加载硬盘上的引导程序 ->引导加载程序(例如,grub)可以访问文件系统,加载操作系统内核 ->操作系统内核程序启动并确定运行级别 ->操作系统初始化 ->用户登录

@ 硬链接:指通过索引节点inode进行连接(ln)
软连接(符号连接):保存路径名(ln -s)

@ 多进程编程:getpid、fork(返回0表示子进程)、wait、exec

@ 常用指令
man、who、sync、touch、chmod (421)、ln、od、which、where、locate、find、gzip、
tar (-cvf file dir) (-xvf file dir)、cut、sort、uniq、tr、grep、awk
进程相关:ps、top、pstree、netstat

@ 数据流重定向:使用文件代替标准输入输出、覆盖>>、追加>
管道:用一个命令的标准IO当做另一个命令的标准IO

Java常规

@ 面向对象:易维护、易复用、易拓展,效率相对低一些

@ 访问修饰符
default(即不写):同一包内可见
private:同一类内可见
public:所有类可见
protected:同一包内及所有子类可见
final:修饰变量表示不可变对象,修饰方法表示不可被重写,修饰类表示不可被继承

@ 多态
编译时多态(静态绑定,重载)
运行时多态(动态绑定,方法表和偏移量,重写)

@ 抽象类和接口
接口只能存在public abstract方法,成员变量只能是public static final类型
一个类只能继承一个抽象类,但一个类可以实现多个接口
final不能修饰抽象类

@ 创建对象的四种方式
new创建对象、反射机制、采用clone机制、序列化机制

@ == 和 equals、hashCode
前者比较对象(常量)在内存中的地址,后者为类制定者覆盖的方法
规范:对象equals则hashCode一定相等,对象hashCode不相等则一定不equals
因此如果重写equals则需要重写hashCode保证上述为真

@ 深拷贝和浅拷贝

@String、StringBuffer、StringBuilder
String为不可变(常量),其余为可变
String不变便于池化、多线程安全、避免安全问题、缓存加快处理速度(HashMap)
StringBuilder为非线程安全,其余为线程安全
StringBuffer、StringBuilder底层为数组

@ 反射
运行状态中可以通过反射动态获得、使用类的所有属性和方法
反射需要解析字节码,性能较低,可以关闭JDK安全检查来提速
获得Class对象:Class.forName()、T.class、object.getClass()
常用:Class、Field、Method、Constructor
场景:代理、JDBC连接、xml配置bean

@ 泛型
本质:类型擦除,只存在于编译阶段
好处:减少类型转换、类型安全、更好性能
有界类型: extends(包括接口)、super
区别:T是参数类型,常用于定义泛型类或方法;?是通配符,一般用于调用泛型代码或作泛型方法的形参

@ 序列化与反序列化
serialVersionUID类的版本号,用于校验版本一致性
实现Serializable接口(系统自动)或Externalizable接口(需要重写read/writeExternal)
不想序列化的字段可以加transient修饰

@ 异常与错误
异常为程序本身可处理,错误为程序不可处理(不可catch)
运行时异常不受JVM检查(空指针、数组越界、类转换),一般异常受JVM检查(IO、SQL)
try-catch-finally中,try和catch的return会先保存return的结果再执行finally
finally的return会覆盖try和catch的 return

@ IO流
字节读:InputStream、FileInputStream、BufferedInputStream、ObjectInputStream
字符读:Reader、FileReader、BufferedReader、StringReader(装饰器模式)
字符转字节:InputStreamReader(适配器模式)

@ 常用集合及其底层实现
ArrayList:Object[]数组,随机访问,空间浪费,线程不安全
LinkedList:双向链表,顺序访问,线程不安全
Vector:Object[]数组,synchronized保证线程安全
Hashtable:内部经过synchronized修饰,线程安全但效率低(危)
HashMap:数组+链表/红黑树,数组扩容或者转树(保证初始插入性能),非线程安全
KEY:一般以不可变类(比如包装类)作为key(hashcode不变保证了正常存取覆盖、可缓存、equal和hashcode关系规范)
扩容:链表长度>8且数组容量<64,扩容后旧元素不需要重新哈希,根据新高位移oldCap
哈希方式:hashCode高16位异或低16位(减少哈希碰撞)再取模(%即&(length – 1))运算(幂2扩容)
ConcurrentHashMap:volatile读不加锁,CAS加入头节点,synchronize锁定哈希桶节,key和value不能为null是为了避免二义性
LinkedHashMap:在hash基础上增加了双向链表(保持插入顺序)
TreeMap:红黑树(自平衡的排序二叉树)
HashSet:线程不安全,可存储null值
LinkedHashSet:可按顺序遍历
TreeSet:红黑树,可定制排序

@ 迭代器
Iterator<>、hasNext()、next()
遍历删除推荐使用迭代器iterator.remove()

@ Java事务

JVM

@内存区域
线程私有:
程序计数器
虚拟机栈(栈帧:局部变量表、操作数栈、动态链接、方法返回地址)
本地方法栈(非java的Native方法)
线程共享:
堆(存放对象实例)(年轻代(Eden、S0、S1)、老生代)(GC)
方法区(即永久代)(元空间存储类的类型信息、字段、方法、常量(本地内存),静态变量和常量池等并入堆中)
本地内存
逃逸分析(栈上分配、同步省略、分离对象)
移除永久代:空间大小难确定、经常OOM、调优困难

@垃圾回收
判断对象可否被回收:引用计数算法、可达性分析算法(GC Roots)、
方法区:方法区的回收主要表现为对常量池的回收和对类的卸载(无示例、无加载、无Class)
引用类型:强引用、软引用、弱引用、虚引用
垃圾回收算法:标记-清除、标记-整理、标记-复制(Eden、S ->另一块S)
分代收集:新生代(复制)、老生代(标记清除、整理)
垃圾收集器:Serial/Serial Old、ParNew、Parallel cavenge/Parallel Old(吞吐量)、
CMS(初始标记、并发标记、重新标记、并发清除)(低停顿、无法处理浮动垃圾、碎片)
G1(初始标记、并发标记、最终标记、筛选回收)(以region为基本单位)(根据标记整理的空间整合、根据回收价值排序的可预测停顿)
内存分配策略:优先Eden、大对象大年龄老生代、动态对象年龄判断、空间分配担保
缩短停顿时间则新生代空间变小,垃圾回收变得频繁,导致吞吐量下降

@ 类加载过程:
加载:加载二进制流、转换为方法区数据结构、创建访问入口
验证:文件格式、元数据、字节码、符号引用
准备:在方法区分配内存、设置默认零值
解析:符合引用转变为直接引用
初始化:为类静态变量赋予初始值
双亲委派机制:防止出现多份同样字节码、保证安全稳定运行

@ 对象创建过程:
类加载检查(检查常量池的符号引用看该类是否被加载过,没有则需要加载)
分配内存(指针碰撞(无内存碎片)、空闲列表(有内存碎片))(CAS、TLAB)
初始化零值
设置对象头(哈希码、GC分代年龄、锁状态)
执行init方法

Spring

@ IoC控制反转:依赖注入/依赖倒置原则、容器自动装配bean(注解、反射技术)
@ AOP面向切面编程:抽象通用功能、简化代码量(日志、事务管理)
@ AspectJ(编译时增强,字节码,快)、spring AOP(JDK Proxy,运行时增强,动态代理,慢)

@ BeanFactory和ApplicationContext:前者是基础IoC容器,后者是完整容器
@ FactoryBean是工厂bean接口,可自己创建bean实例(实现getObject方法)

@ bean:作用域(singleton、prototype、request、session、global-session)、多线程问题
@bean配置方式:基于xml、基于注解、基于Java类
@ 生命周期:实例化(构造器)、填充属性(依赖属性)、初始化(init)、销毁
@循环依赖:构造器循环依赖、field循环依赖,后者解决方法:三级缓存

@Component 组件
@ComponentScan 自动扫描
@Bean 实例(一般是单例)
@Configuration 配置组件
@Repository 持久层组件
@Service 服务层组件
@Controller 控制层组件

@Transational事务
主要基于数据库的事务支持
编程式事务管理(TransactionTemplate)、声明式事务管理(基于xml、基于注解)
事务传播行为:事务调用事务时的处理方式
事务隔离级别:库默认、读未提交、读已提交、可重复读、串行化

@ springMVC
处理流程:DispatcherServlet前端处理器,请求HandlerMapping找出容器中的@Controller及@RequestMapping,生成Handler和HandlerInterceptor并返回HandlerExcutionChain处理器执行链。然后DispatcherServlet调用Handler(即Controller)返回ModelAndView,再将MV放到视图解析器渲染最终返回。

JUC

@并发编程:原子性(分时复用引起)、可见性(缓存引起)、有序性(重排序引起)

@线程安全实现方法:互斥同步(synchronized、ReentrantLock)、非阻塞同步(CAS、AtomicInteger)、无同步(虚拟机栈、ThreadLocal)

@CAS:乐观锁、ABA问题(版本号)、自旋循环开销(pause)

@一些线程相关
Runnable、Callable、Future、call()
wait释放了锁(需要被notify唤醒),sleep没有释放锁
synchronized:常对对象/类加锁、修饰方法或代码块、双锁单例模式、原子性
ReentrantLock:等待可中断、公平锁、选择性通知
volatile:主要保证线程间的可见性(内存值同步,防指令重排,只能保证单次读写原子性)
AtomicInteger原子类

@ synchronized原理
每个对象有ObjectMonitor,在执行monitorenter时会尝试获取对象的锁,如果计数器为0则成功并设为1,执行monitorexit会释放锁。获取失败则放进同步队列中阻塞等待
锁的单向升级:无锁->偏向锁->轻量级锁->重量级锁
其他优化:锁消除、锁粗化、偏向锁

@两种锁
悲观锁:底层为自旋锁或互斥锁,典型有synchronized、ReentrantLock,适合多写场景
乐观锁:底层为版本号机制或CAS算法,典型为atomic、MVCC,适合高读、高吞吐场景

@ThreadLocal:线程本地变量,变量在线程中ThreadLocalMap,需要注意的是线程池中可能会对Thread进行复用(因此应该对本地变量进行清理)!!!

@ThreadPoolExecutor线程池:降低资源消耗、提高响应速度、提高线程可管理性
execute没有返回值、submit有返回值Future
核心线程数、最大线程数、等待时间、任务队列、饱和策略
CPU密集型配置少线程(提高吞吐),IO密集型配置多线程(提高响应)
流程:尝试核心线程->尝试放队列->尝试非核心线程->执行饱和策略

@spring框架中bean为单例模式,其中的非静态变量可能会有并发问题,解决方法:(1)无状态,改为参数传递(2)使用ThreadLocal(3)取消单例模式

@ Semaphore
信号量可以指定多个线程同时访问有限的某个资源,PV操作(acquire()、release())

@ CountDownLatch
倒计时器常用于等待n个线程执行完毕或开始执行任务的最大并行性(countDown()、await())

@ CyclicBarrier

@ AQS
AQS 核心思想是,如果被请求的共享资源空闲,则将当前请求资源的线程设置为有效的工作线程,并且将共享资源设置为锁定状态。如果被请求的共享资源被占用,那么就需要一套线程阻塞等待以及被唤醒时锁分配的机制,这个机制 AQS 是用 CLH 队列锁实现的,即将暂时获取不到锁的线程加入到队列中。

mysql

@ 存储引擎
InnoDB:行级锁和表级锁、事务支持(提交、回滚)、支持外键、数据库异常崩溃后的安全恢复(redo log)、MVCC
MyISAM:适用于只读数据、或者表比较小、支持压缩表、空间数据索引等、不支持事务、只有表锁

@ 事务四大特性ACID:
原子性(回滚日志 undo log)、持久性(重做日志 redo log)、隔离性(锁机制、MVCC)、一致性

@ 并发事务问题:
脏读脏写、丢失修改、不可重复读、幻读
隔离级别:读取未提交、读取已提交、可重复读(mysql默认)、可串行化(分布式事务)

@日志文件
错误日志:运行错误、警告信息,用来优化参数配置
慢查询日志:记录长运行时间的SQL语句来做SQL优化
回滚日志undolog:提供回滚和MVCC,逻辑日志
重做日志redolog:保证持久性,物理日志
日志binlog:记录修改行为,用于数据库的主从复制、恢复、增量备份

@两阶段提交机制(2PC)(WAL):
1、记录redolog,同时更新数据到内存,redolog记为prepare状态
2、空闲时生成binlog,写入磁盘
3、执行提交事务接口,将redolog改为commit状态(可以重用)

@数据恢复:从上一个全量备份开始根据redolog、binlog逐步恢复到指定时刻

@锁机制:
表级锁(粒度大、并发低、开销小、加锁快、无死锁):意向共享锁(IS)、意向排他锁(IX)
行级锁(粒度小、并发高、开销大、加锁慢、可能死锁):共享锁(S)、排他锁(X)
行锁(精确匹配索引)、间隙锁(防止幻读、封住索引区间)、Next-key锁(行锁+间隙锁)

@ MVCC
快照读:不加锁的非阻塞读,只能工作在非串行级别,一般select
当前读(锁定读):读取最新记录,保证其他事务不能修改当前事务,加共享锁或排他锁,如手动加锁(select … for update/lock in share mode)、修改表数据(update…)
每行保存创建版本和删除版本号,保证仅能查询到之前更新的行,版本号在操作时进行更新

@组成结构:
Server层:连接器、分析器(词法分析+语法分析)、优化器(索引选择、关联顺序等)、执行器、binlog逻辑日志
存储引擎(InnoDB、redolog物理日志)

@索引
数据结构:平衡多路查找树(B+Tree)、高效、稳定的效率、数据有序、更新开销大
主键索引:唯一性,聚集索引,innoDB的索引结构和数据一起存放。
推荐自增主键:插入性能提高、顺序位置填充、减少移动和碎片、减少维护开销
二级索引:非聚集索引。二级索引的叶子节点存储的数据为主键,因此查询非索引数据需要二次查询(回表),覆盖索引则不需要。二级索引包括唯一索引、普通索引、前缀索引和全文索引。每个二级索引都是一棵B+树。
索引规则:最左前缀匹配原则、=和in可乱序、区分度高原则、计算过程不能使用索引、OR前面为非索引列失效、范围查询之后失效、Like仅“T%”时可用
为什么选择B+树:B树可能需要跨层访问,底层有序链表,支持随机检索和顺序检索,查询性能稳定

SQL执行顺序:from、join、on、where、group by、avg/sum/count、having、select、distinct、order by、limit

order by (desc)、limit n、like、union (all)、explain
alter table ‘tname’ add primary key (‘cname’)
alter table ‘tname’ add index iname(‘cname’,’cname2’,’cname3’)
select s1.name,s1.id,s3.id,s3.job from s1 join s3 on s3.job like “s%” order by s1.id,s3.id desc limit 20;

数据库redis

@ 读写性能高、持久化、支持事务、数据结构丰富、主从复制、其他特性(内存危机)

@ 数据类型:
string:简单动态字符串(SDS)
list:双向链表,常用于消息队列、慢查询
hash:哈希表(数组 + 链表),常用于存储对象
set:无序集合
sorted set:排序集合(跳表),常用于需要排序的场景
bitmap:位图,常用于状态信息

@ 实现原理:
直接在内存中存储数据,节省了硬盘IO开销,数据存于内存中类似于HashMap
底层构筑VM机制,减少系统调用,冷数据放磁盘,实现冷热数据分离
单线程IO多路复用(Reactor模式) + 事件处理模型
为什么单线程:易维护、性能瓶颈不在CPU、避免上下文及同步开销

@ Redis的过期数据删除策略:
惰性删除:在取出key时进行检查(cpu友好)
定期删除:每一段时间抽取一批key进行检查(内存友好)

@ Redis数据淘汰策略:
volatitle-lru、volatitle-lfu、volatitle-ttl、volatitle-random
allkeys-lru、allkeys-lfu、allkeys-random

@ Redis持久化机制:
快照持久化(RDB):获得并存储某时间点上数据的副本并储存,由子进程负责
只追加文件持久化(AOF):追加写入修改命令,一般是每秒/修改写入、AOF重写
混合持久化(RDB + AOF)

@ Redis事务:顺序性排他性地执行多条命令
MULTI、EXEC、DISCARD、WATCH
Redis事务不支持回滚,因此不满足原子性

@ 实现分布式锁
setnx + expire、set(key, id, time_exp, NX)

@ 缓存穿透问题:大量未命中缓存的请求直接落在后端数据库上
解决方法:缓存无效key、布隆过滤器

@ 缓存雪崩问题:缓存在同一时间大面积失效(超时、bug等),请求直接落在后端数据库上
解决方法:集群、限流、随机失效时间、永不失效

@ 缓存一致性问题
懒加载 + 延迟双删(删cache ->更新DB ->删cache)
旁路缓存模式(更新DB ->删cache)(不一致概率很低:写cache比写db快)
上述二者可以把待删除key放进消息队列或者订阅数据库的binlog来解决删除失败问题
由cache负责同步读写db:同步读写穿透、异步缓存写入(都少见)

@ 分库分表
垂直切分、水平切分

你可能感兴趣的:(tcp/ip,udp)