技术全栈面试
2023-07-31 20:01:06 0 举报
AI智能生成
基本嘘唏
作者其他创作
大纲/内容
业务解决方案
党建导入系统
OA系统
cms 内容系统
四川书法家网
爱成都内容发布系统
退役军人系统
成都房地产协会
hr系统
考勤系统
组织架构同步器
scrm系统
代码生成器系统
积分发放系统
重庆城市发放系统
导出导入中心
内容转换系统
商城系统
云麦尔商城系统
BI数据展示
爬虫系统
银行缴费对接
开源技术准备
技术解决方案
ffmpeg
三方对接接口
阿里云相关接口
sms短信发送对接
cdn 加速
oss
企业微信相关接口
秒杀技术实现
sentinel 秒杀
·
genkins
cicd
技术总结
问题 = 期望 - 体验
直言有讳
第一性原理 :第一性原理就是让我们抓住事物最本质的特征原理,依据事物本身的规律,去推导、分析、演绎事物的各种变化规律,进而洞悉事物在各种具体场景下的表现形式,而不是追随事物的表面现象,生搬硬套各种所谓的规矩、经验和技巧,以至于在各种纷繁复杂的冲突和纠结中迷失了方向。
研发相关
java知识体系
map
ConcurrentHashMap
LinkedHashMap
list
string
基本类型
thread
理解
状态
1. 初始(NEW):新创建了一个线程对象,但还没有调用start()方法。
2. 运行(RUNNABLE):Java线程中将就绪(ready)和运行中(running)两种状态笼统的称为“运行”。
线程对象创建后,其他线程(比如main线程)调用了该对象的start()方法。该状态的线程位于可运行线程池中,等待被线程调度选中,获取CPU的使用权,此时处于就绪状态(ready)。就绪状态的线程在获得CPU时间片后变为运行中状态(running)。
3. 阻塞(BLOCKED):表示线程阻塞于锁。
4. 等待(WAITING):进入该状态的线程需要等待其他线程做出一些特定动作(通知或中断)。
5. 超时等待(TIMED_WAITING):该状态不同于WAITING,它可以在指定的时间后自行返回。
6. 终止(TERMINATED):表示该线程已经执行完毕。
2. 运行(RUNNABLE):Java线程中将就绪(ready)和运行中(running)两种状态笼统的称为“运行”。
线程对象创建后,其他线程(比如main线程)调用了该对象的start()方法。该状态的线程位于可运行线程池中,等待被线程调度选中,获取CPU的使用权,此时处于就绪状态(ready)。就绪状态的线程在获得CPU时间片后变为运行中状态(running)。
3. 阻塞(BLOCKED):表示线程阻塞于锁。
4. 等待(WAITING):进入该状态的线程需要等待其他线程做出一些特定动作(通知或中断)。
5. 超时等待(TIMED_WAITING):该状态不同于WAITING,它可以在指定的时间后自行返回。
6. 终止(TERMINATED):表示该线程已经执行完毕。
提供了比 synchronized 更加高级的各种同步结构,包括 CountDownLatch、CyclicBarrier、Semaphore 等,可以实现更加丰富的多线程操作,比如利用 Semaphore 作为资源控制器,限制同时进行工作的线程数量。各种线程安全的容器,比如最常见的 ConcurrentHashMap、有序的 ConcurrentSkipListMap,或者通过类似快照机制,实现线程安全的动态数组 CopyOnWriteArrayList 等。各种并发队列实现,如各种 BlockingQueue 实现,比较典型的 ArrayBlockingQueue、 SynchronousQueue 或针对特定场景的 PriorityBlockingQueue 等。强大的 Executor 框架,可以创建各种不同类型的线程池,调度任务运行等,绝大部分情况下,不再需要自己从头实现线程池和任务调度器。
CountDownLatch
只能执行一次
CyclicBarrier
线程休眠的方式有哪几种
Thread.sleep
TimeUnit 底层就是sleep
wait
Condition
LockSupport
TimeUnit 底层就是sleep
wait
Condition
LockSupport
在多线程状态下同步访问统一资源 要不资源本身是 线程安全的 ,要不然访问的资源上面是加了锁的
如何判断线程池是否已经执行完成
使用 isTerminated 方法判断。
使用 getCompletedTaskCount 方法判断。 getcount 是近似
使用 CountDownLatch 判断。
使用 CyclicBarrier 判断。
使用 getCompletedTaskCount 方法判断。 getcount 是近似
使用 CountDownLatch 判断。
使用 CyclicBarrier 判断。
线程池
五个状态
线程池总共包含以下 5 种状态:
RUNNING:运行状态。
SHUTDOWN:关闭状态。
STOP:阻断状态。
TIDYING:整理状态。
TERMINATED:终止状态。
RUNNING:运行状态。
SHUTDOWN:关闭状态。
STOP:阻断状态。
TIDYING:整理状态。
TERMINATED:终止状态。
corePoolSize 核心线程数 最小活跃数目
maximumPoolSize 最大线程数目
keepAliveTime 空闲时间
workQueue 任务队列
threadFactory 线程工程
handler 拒绝策略
maximumPoolSize 最大线程数目
keepAliveTime 空闲时间
workQueue 任务队列
threadFactory 线程工程
handler 拒绝策略
线程可以配置的队列有哪些
LinkedBlockingQueue 无界队列
ArrayBlockingQueue 有界队列
SynchronousQueue 同步队列
PriorityBlockingQueue 优先队列
LinkedTransferQueue:一个由链表结构组成的无界阻塞队列。与SynchronousQueue类似,还含有非阻塞方法。
LinkedBlockingDeque:一个由链表结构组成的双向阻塞队列。
LinkedBlockingQueue 无界队列
ArrayBlockingQueue 有界队列
SynchronousQueue 同步队列
PriorityBlockingQueue 优先队列
LinkedTransferQueue:一个由链表结构组成的无界阻塞队列。与SynchronousQueue类似,还含有非阻塞方法。
LinkedBlockingDeque:一个由链表结构组成的双向阻塞队列。
方法
ThreadPoolExecutor 核心方法
execute 加入线程池中
submit (一个Callable 返回一个任务结果future 对象)
shutdown 等待线程池执行完毕
shutdownNow 直接执行失败
awaitTermination 等待多少秒 看线程是否关闭
execute 加入线程池中
submit (一个Callable 返回一个任务结果future 对象)
shutdown 等待线程池执行完毕
shutdownNow 直接执行失败
awaitTermination 等待多少秒 看线程是否关闭
构造方法
ThreadFactory threadFactory, RejectedExecutionHandler handler 线程工厂和拒绝策略
分类
newCachedThreadPool 创建一个可缓存线程池,适用于执行大量短期任务的场景。
newFixedThreadPool 创建一个固定大小的线程池,适用于执行长期任务的场景。
newSingleThreadExecutor 创建一个单线程的线程池,适用于需要保证任务顺序执行的场景。
newScheduledThreadPool 创建一个定时任务的线程池,适用于需要定时执行任务的场景。
newFixedThreadPool 创建一个固定大小的线程池,适用于执行长期任务的场景。
newSingleThreadExecutor 创建一个单线程的线程池,适用于需要保证任务顺序执行的场景。
newScheduledThreadPool 创建一个定时任务的线程池,适用于需要定时执行任务的场景。
为何要池化
们应该尽量复用已有的类,以确保程序的高效运行,当然如果能够提前创建这些类就再好不过了,而这些功能的实现依靠的就是池化技术。
线程池、内存池、数据库连接池、HttpClient 连接池等
如何使用线程池执行定时任务
ScheduledThreadPool 和 SingleThreadScheduledExecutor
schedule
第 1 个参数:传递一个任务,Runnable 或 Callable 对象;
第 2 个参数:添加定时任务后,再过多久开始执行定时任务;
第 3 个参数:时间单位,配合参数 2 一起使用
第 2 个参数:添加定时任务后,再过多久开始执行定时任务;
第 3 个参数:时间单位,配合参数 2 一起使用
scheduleAtFixedRate
第 1 个参数:传递一个任务,Runnable 或 Callable 对象;
第 2 个参数:添加定时任务后,再过多久开始执行定时任务;
第 3 个参数:定时任务执行的时间间隔;
第 4 个参数:时间单位,配合参数 2 和参数 3 一起使用。
第 2 个参数:添加定时任务后,再过多久开始执行定时任务;
第 3 个参数:定时任务执行的时间间隔;
第 4 个参数:时间单位,配合参数 2 和参数 3 一起使用。
scheduleWithFixedDelay
scheduleWithFixedDelay 方法是在方法执行完成之后,再隔 N 秒执行下一个定时任务 计算执行任务的时间
守护线程
会随着主线程解决而结束
如何中断线程
自定义中断标识符
juc
子主题
io
nio
AbstractQueuedSynchronizer
bio
nio
同步非阻塞 IO 模型 不是nio
子主题
jvm
gc
gc理解
java框架
mybatis
springmvc
spring
spring 核心
spring 扩展点
netty
spring boot
spring security
auth 2.0
网站
spring shiro
fegin
sentinel
beetl
官网
jmaster
设计模式
自我理解
排查问题
jstack
jconsole
锁
synchronized
ReentrantLock
基础
抽象嘞与接口
接口和抽象类都是用来定义对象的公共行为的,但二者有以下 7 点不同:
定义的关键字不同。子类继承或实现关键字不同。类型扩展不同:抽象类是单继承,而接口是多继承。方法访问控制符:
抽象类无限制,只是抽象类中的抽象方法不能被 private 修饰;而接口有限制,接口默认的是 public 控制符。
属性方法控制符:抽象类无限制,而接口有限制,接口默认的是 public 控制符。
方法实现不同:抽象类中的普通方法必须有实现,抽象方法必须没有实现;而接口中普通方法不能有实现,但在 JDK 8 中的 static 和 defualt 方法必须有实现。静态代码块的使用不同:抽象类可以有静态代码块,而接口不能有
定义的关键字不同。子类继承或实现关键字不同。类型扩展不同:抽象类是单继承,而接口是多继承。方法访问控制符:
抽象类无限制,只是抽象类中的抽象方法不能被 private 修饰;而接口有限制,接口默认的是 public 控制符。
属性方法控制符:抽象类无限制,而接口有限制,接口默认的是 public 控制符。
方法实现不同:抽象类中的普通方法必须有实现,抽象方法必须没有实现;而接口中普通方法不能有实现,但在 JDK 8 中的 static 和 defualt 方法必须有实现。静态代码块的使用不同:抽象类可以有静态代码块,而接口不能有
golong知识体系
defer
map
不可以是函数类型、字典类型和切片类型
map为匿名函数时候不可以使用== 比较编译器会报错
子主题
数组与切片
slice
移除操作使用append 拼接前后数据
array
context
1:上下文控制,2:多个 goroutine 之间的数据交互等,3:超时控制:到某个时间点超时,过多久超时
模型
CSP(CommunicatingSequentiall Process)并发模型,就是通过goroutine和channel来实现的
携程池
panjf2000/ants
参数比较
reflect.DeepEqual 和等于号进行比较
init
tag
json序列化或反序列化时字段的名称
db: sqlx模块中对应的数据库字段名
form: gin框架中对应的前端的数据字段名
binding: 搭配 form 使用, 默认如果没查找到结构体中的某个字段则不报错值为空, binding为 required 代表没找到返回错误给前端
db: sqlx模块中对应的数据库字段名
form: gin框架中对应的前端的数据字段名
binding: 搭配 form 使用, 默认如果没查找到结构体中的某个字段则不报错值为空, binding为 required 代表没找到返回错误给前端
打印信息
%v输出结构体各成员的值;
%+v输出结构体各成员的名称和值;
%#v输出结构体名称和结构体各成员的名称和值
启动执行顺序 执行顺序:import –> const –> var –>init()–>main()
垃圾回收
标记清除
context
Gin、Gorm、Wire、Viper、Zap、Golang-jwt、Go-redis、Testify、Sonyflake、robfig-cron
flag
internal
internal代码包中声明的公开程序实体仅能被该代码包的直接父包及其子包中的代码引用。当然,引用前需要先导入这个internal包
基础
Go 语言中的程序实体包括变量、常量、函数、结构体和接口
类型推断
请记住,一对不包裹任何东西的花括号,除了可以代表空的代码块之外,还可以用于表示不包含任何内容的数据结构(或者说数据类型)。比如你今后肯定会遇到的struct{},它就代表了不包含任何字段和方法的、空的结构体类型。而空接口interface{}则代表了不包含任何方法定义的、空的接口类型。
数据转换
Don’t communicate by sharing memory; share memory by communicating. (不要通过共享内存来通信,而应该通过通信来共享内存。)
别名类型
Go 语言内建的基本类型中就存在两个别名类型。byte是uint8的别名类型,而rune是int32的别名类型。
container/list
1. 列表(List):列表是一个双向链表,适用于需要频繁在列表的头部或尾部进行插入、删除操作的场景。例如,实现一个任务队列,可以使用列表来管理任务的顺序和执行。
2. 环形链表(Ring):环形链表是一个循环的双向链表,适用于需要循环遍历的场景。例如,实现一个轮询调度器,可以使用环形链表来管理任务的调度顺序。
3. 堆(Heap):堆是一种优先队列的数据结构,适用于需要按照优先级进行元素插入和删除的场景。例如,实现一个任务调度器,可以使用堆来管理任务的优先级和执行顺序。
2. 环形链表(Ring):环形链表是一个循环的双向链表,适用于需要循环遍历的场景。例如,实现一个轮询调度器,可以使用环形链表来管理任务的调度顺序。
3. 堆(Heap):堆是一种优先队列的数据结构,适用于需要按照优先级进行元素插入和删除的场景。例如,实现一个任务调度器,可以使用堆来管理任务的优先级和执行顺序。
channel
并发安全
一个环形的队列 先入先出 有一个读写锁进行数据控制
异步
接口组合
select 通过使用 select 语句,我们可以实现对多个通道的并发操作,并根据就绪的通道执行相应的操作。这在处理并发任务时非常有用
泛型
泛型编程的中心思想是对具体的、高效的算法进行抽象,以获得通用的算法,然后这些算法可以与不同的数据表示法结合起来,产生各种各样有用的软件
切片的底层数据结构
1. 指针(Pointer):指向底层数组的第一个元素的指针。
2. 长度(Length):表示切片的长度,即切片中元素的个数。
3. 容量(Capacity):表示底层数组中可供切片使用的元素个数。
2. 长度(Length):表示切片的长度,即切片中元素的个数。
3. 容量(Capacity):表示底层数组中可供切片使用的元素个数。
扩容之后会指向新的数组 一般扩容会是原来的两倍
分布式
spring cloud
脑图
spring cloud alibaba
分布式事务
seata
本地事务表
tcc柔性事务
gateway
nacos
etcd
raft
中间件
zookeeper
redis
redisTemple
redis为什么快
redis单线程模型 redis6.0 使用的是多线程
链接
redis 底层数据sds 和 ziplist intlist
内存分配
内存回收
异步删除
数据替换
LRU、LFU 等经典算法。这部分的代码实现在了 evict.c 中
扩容 渐进式
sorted set
跳表
多层有序链表
二分查找
zslRandomLevel
hash表
quicklist
多个 ziplist
链表中关联了多个ziplist
listpack
从右向左反向查询 listpack。
Stream
Radix Tree
sever启动
主要配置
数据恢复
选择AOF还是RDB持久化取决于具体的应用场景和需求。一般来说,如果对数据的安全性要求较高,可以选择AOF持久化;如果对数据的恢复速度要求较高,可以选择RDB持久化;也可以同时使用AOF和RDB持久化来提供更高的数据保护和恢复能力。
Reactor 模型
redis 是单线程么 后端会启动守护线程
Redis 还启动了 3 个线程来执行文件关闭、AOF 同步写和惰性删除等操作
6.0 多线程处理
多 IO 线程本身并不会执行命令,它们只是利用多核并行地读取数据和解析命令,或是将 server 数据写回(下节课我还会结合分布式锁的原子性保证,来给你介绍这一部分的源码实现。)。所以,Redis 执行命令的线程还是主 IO 线程
,多 IO 线程实际并不会加快命令的执行,而是只会将读取解析命令并行化执行,以及写回结果并行化执行,并且读取解析命令还是针对收到的第一条命令。
AB 客户端并发加锁操作其实是不能知道AB谁成功了在多线程,但客户端发送的命令是可以保证顺序的多客户端不能保证
执行流程
set流程
redis 缓存设计
LFU
最近次数最少
近似 LRU 算法的执行可以分成三大步骤,分别是判断当前内存使用情况、更新待淘汰的候选键值对集合、选择被淘汰的键值对并删除
访问频率衰减
LRU
最近最少
链表结构
持久化
主从复制
全量复制、增量复制和长连接同
集群方式
主重复制
手动恢复
哨兵模式
子障转移需要一定的时间,可能会导致服务的短暂不可用;不支持自动分片,存储容量受限于单个节点。
集群模式
水平扩容
消息中间件
elasearch
es-sql
pulsar
消息队列
kafka
顺序消费一个topic 对应一个patition
rocketmq
大数据
前端
js
jquery
css
html
mui
vue
vue3
数据库
mysql
搜索引擎
索引优化
慢sql定位
命名规范
mysql 事务
隔离级别
innodb
行锁
删除 如果想删除表,当然用 drop;如果想保留表而将所有数据删除,如果和事务无关,用 truncate 即可;
事务 # 开启一个事务
START TRANSACTION;
# 多条 SQL 语句
SQL1,SQL2...
## 提交事务
COMMIT;
START TRANSACTION;
# 多条 SQL 语句
SQL1,SQL2...
## 提交事务
COMMIT;
网络
tcp
http
http 1.0
http 2.0
http 3.0
https
ssl
udp
session
cookies
进程、线程、协程有什么区别?
进程:是应用程序的启动实例,每个进程都有独立的内存空间,不同的进程通过进程间的通信方式来通信。
线程:从属于进程,每个进程至少包含一个线程,线程是 CPU 调度的基本单位,多个线程之间可以共享进程的资源并通过共享内存等线程间的通信方式来通信。
协程:为轻量级线程,与线程相比,协程不受操作系统的调度,协程的调度器由用户应用程序提供,协程调度器按照调度策略把协程调度到线程中运行
线程:从属于进程,每个进程至少包含一个线程,线程是 CPU 调度的基本单位,多个线程之间可以共享进程的资源并通过共享内存等线程间的通信方式来通信。
协程:为轻量级线程,与线程相比,协程不受操作系统的调度,协程的调度器由用户应用程序提供,协程调度器按照调度策略把协程调度到线程中运行
socket
负载均衡
轮训
随机
最小链接
加权随机
加权轮询
iphash
最短响应时间
自适应
运维
linux
linux 连接模型
fd
select
int select (int __nfds, fd_set *__readfds, fd_set *__writefds, fd_set *__exceptfds, struct timeval *__timeout)
分别是读数据事件(对应__readfds集合)、写数据事件(对应__writefds集合)和异常事件(对应__exceptfds集合)。
只能1024
poll
需要遍历就绪
epoll
可以通过函数监听文件是否就绪
epoll使用红黑树和队列,红黑树存放需要检测的节点,队列存放就绪的节点。
网卡到进程会有上下文切换
nginx
为什么快
查看命令
od -A x -t x1c -v dump.rdb
字节 = 8位
128
int8
int32
int64
unicode
什么是进程 分配资源的最小单位
线程 发送启动一个线程发送消息 操作系统最小调度单元
当前最优解决方案
常用命令集合
常用中间件安装
第一版技术解决方案
方案
zheng 开源解决方案
技术指标
各种中间件QPS
0 条评论
下一页