java知识体系
list
string
基本类型
thread
理解
状态
1. 初始(NEW):新创建了一个线程对象,但还没有调用start()方法。<br>2. 运行(RUNNABLE):Java线程中将就绪(ready)和运行中(running)两种状态笼统的称为“运行”。<br>线程对象创建后,其他线程(比如main线程)调用了该对象的start()方法。该状态的线程位于可运行线程池中,等待被线程调度选中,获取CPU的使用权,此时处于就绪状态(ready)。就绪状态的线程在获得CPU时间片后变为运行中状态(running)。<br>3. 阻塞(BLOCKED):表示线程阻塞于锁。<br>4. 等待(WAITING):进入该状态的线程需要等待其他线程做出一些特定动作(通知或中断)。<br>5. 超时等待(TIMED_WAITING):该状态不同于WAITING,它可以在指定的时间后自行返回。<br>6. 终止(TERMINATED):表示该线程已经执行完毕。
提供了比 synchronized 更加高级的各种同步结构,包括 CountDownLatch、CyclicBarrier、Semaphore 等,可以实现更加丰富的多线程操作,比如利用 Semaphore 作为资源控制器,限制同时进行工作的线程数量。各种线程安全的容器,比如最常见的 ConcurrentHashMap、有序的 ConcurrentSkipListMap,或者通过类似快照机制,实现线程安全的动态数组 CopyOnWriteArrayList 等。各种并发队列实现,如各种 BlockingQueue 实现,比较典型的 ArrayBlockingQueue、 SynchronousQueue 或针对特定场景的 PriorityBlockingQueue 等。强大的 Executor 框架,可以创建各种不同类型的线程池,调度任务运行等,绝大部分情况下,不再需要自己从头实现线程池和任务调度器。
CyclicBarrier
线程休眠的方式有哪几种
Thread.sleep<br>TimeUnit 底层就是sleep<br>wait<br>Condition<br>LockSupport
在多线程状态下同步访问统一资源 要不资源本身是 线程安全的 ,要不然访问的资源上面是加了锁的
如何判断线程池是否已经执行完成
使用 isTerminated 方法判断。<br>使用 getCompletedTaskCount 方法判断。 getcount 是近似<br>使用 CountDownLatch 判断。<br>使用 CyclicBarrier 判断。<br>
线程池
五个状态
线程池总共包含以下 5 种状态:<br><br>RUNNING:运行状态。<br>SHUTDOWN:关闭状态。<br>STOP:阻断状态。<br>TIDYING:整理状态。<br>TERMINATED:终止状态。
corePoolSize 核心线程数 最小活跃数目<br>maximumPoolSize 最大线程数目<br>keepAliveTime 空闲时间<br>workQueue 任务队列<br>threadFactory 线程工程<br>handler 拒绝策略
线程可以配置的队列有哪些<br>LinkedBlockingQueue 无界队列<br>ArrayBlockingQueue 有界队列<br>SynchronousQueue 同步队列<br>PriorityBlockingQueue 优先队列<br>LinkedTransferQueue:一个由链表结构组成的无界阻塞队列。与SynchronousQueue类似,还含有非阻塞方法。<br>LinkedBlockingDeque:一个由链表结构组成的双向阻塞队列。<br>
方法
ThreadPoolExecutor 核心方法<br>execute 加入线程池中<br>submit (一个Callable 返回一个任务结果future 对象)<br>shutdown 等待线程池执行完毕<br>shutdownNow 直接执行失败<br>awaitTermination 等待多少秒 看线程是否关闭
构造方法
ThreadFactory threadFactory, RejectedExecutionHandler handler 线程工厂和拒绝策略
分类
newCachedThreadPool 创建一个可缓存线程池,适用于执行大量短期任务的场景。<br>newFixedThreadPool 创建一个固定大小的线程池,适用于执行长期任务的场景。<br>newSingleThreadExecutor 创建一个单线程的线程池,适用于需要保证任务顺序执行的场景。<br>newScheduledThreadPool 创建一个定时任务的线程池,适用于需要定时执行任务的场景。<br>
为何要池化
们应该尽量复用已有的类,以确保程序的高效运行,当然如果能够提前创建这些类就再好不过了,而这些功能的实现依靠的就是池化技术。
线程池、内存池、数据库连接池、HttpClient 连接池等
如何使用线程池执行定时任务
ScheduledThreadPool 和 SingleThreadScheduledExecutor
schedule
第 1 个参数:传递一个任务,Runnable 或 Callable 对象;<br>第 2 个参数:添加定时任务后,再过多久开始执行定时任务;<br>第 3 个参数:时间单位,配合参数 2 一起使用
scheduleAtFixedRate
第 1 个参数:传递一个任务,Runnable 或 Callable 对象;<br>第 2 个参数:添加定时任务后,再过多久开始执行定时任务;<br>第 3 个参数:定时任务执行的时间间隔;<br>第 4 个参数:时间单位,配合参数 2 和参数 3 一起使用。
scheduleWithFixedDelay
scheduleWithFixedDelay 方法是在方法执行完成之后,再隔 N 秒执行下一个定时任务 计算执行任务的时间
io
nio
AbstractQueuedSynchronizer
nio
同步非阻塞 IO 模型 不是nio
子主题
java框架
mybatis
springmvc
spring
spring 核心
spring 扩展点
netty
spring boot
spring security
auth 2.0
网站
spring shiro
fegin
jmaster
基础
抽象嘞与接口
接口和抽象类都是用来定义对象的公共行为的,但二者有以下 7 点不同:<br>定义的关键字不同。子类继承或实现关键字不同。类型扩展不同:抽象类是单继承,而接口是多继承。方法访问控制符:<br>抽象类无限制,只是抽象类中的抽象方法不能被 private 修饰;而接口有限制,接口默认的是 public 控制符。<br>属性方法控制符:抽象类无限制,而接口有限制,接口默认的是 public 控制符。<br>方法实现不同:抽象类中的普通方法必须有实现,抽象方法必须没有实现;而接口中普通方法不能有实现,但在 JDK 8 中的 static 和 defualt 方法必须有实现。静态代码块的使用不同:抽象类可以有静态代码块,而接口不能有<br>
golong知识体系
defer
map
不可以是函数类型、字典类型和切片类型
map为匿名函数时候不可以使用== 比较编译器会报错
子主题
数组与切片
slice
移除操作使用append 拼接前后数据
array
context
1:上下文控制,2:多个 goroutine 之间的数据交互等,3:超时控制:到某个时间点超时,过多久超时
模型
CSP(CommunicatingSequentiall Process)并发模型,就是通过goroutine和channel来实现的
参数比较
reflect.DeepEqual 和等于号进行比较
init
tag
json序列化或反序列化时字段的名称<br>db: sqlx模块中对应的数据库字段名<br>form: gin框架中对应的前端的数据字段名<br>binding: 搭配 form 使用, 默认如果没查找到结构体中的某个字段则不报错值为空, binding为 required 代表没找到返回错误给前端
打印信息
%v输出结构体各成员的值;
%+v输出结构体各成员的名称和值;
%#v输出结构体名称和结构体各成员的名称和值
启动执行顺序 执行顺序:import –> const –> var –>init()–>main()<br>
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):列表是一个双向链表,适用于需要频繁在列表的头部或尾部进行插入、删除操作的场景。例如,实现一个任务队列,可以使用列表来管理任务的顺序和执行。 <br> <br>2. 环形链表(Ring):环形链表是一个循环的双向链表,适用于需要循环遍历的场景。例如,实现一个轮询调度器,可以使用环形链表来管理任务的调度顺序。 <br> <br>3. 堆(Heap):堆是一种优先队列的数据结构,适用于需要按照优先级进行元素插入和删除的场景。例如,实现一个任务调度器,可以使用堆来管理任务的优先级和执行顺序。
channel
并发安全
一个环形的队列 先入先出 有一个读写锁进行数据控制
异步
接口组合
select 通过使用 select 语句,我们可以实现对多个通道的并发操作,并根据就绪的通道执行相应的操作。这在处理并发任务时非常有用<br>
泛型
泛型编程的中心思想是对具体的、高效的算法进行抽象,以获得通用的算法,然后这些算法可以与不同的数据表示法结合起来,产生各种各样有用的软件
切片的底层数据结构
<span style="color: rgb(255, 255, 255); font-family: "Public Sans", sans-serif; white-space: break-spaces; background-color: rgb(68, 72, 74);">1. 指针(Pointer):指向底层数组的第一个元素的指针。 <br>2. 长度(Length):表示切片的长度,即切片中元素的个数。 <br>3. 容量(Capacity):表示底层数组中可供切片使用的元素个数。 </span>
扩容之后会指向新的数组 一般扩容会是原来的两倍
数据库
mysql
搜索引擎
索引优化
慢sql定位
mysql 事务
隔离级别
删除 如果想删除表,当然用 drop;如果想保留表而将所有数据删除,如果和事务无关,用 truncate 即可;<br>
事务 # 开启一个事务<br>START TRANSACTION;<br># 多条 SQL 语句<br>SQL1,SQL2...<br>## 提交事务<br>COMMIT;
网络
tcp
http
http 1.0
http 2.0
http 3.0
udp
session
cookies
进程、线程、协程有什么区别?
进程:是应用程序的启动实例,每个进程都有独立的内存空间,不同的进程通过进程间的通信方式来通信。<br><br>线程:从属于进程,每个进程至少包含一个线程,线程是 CPU 调度的基本单位,多个线程之间可以共享进程的资源并通过共享内存等线程间的通信方式来通信。<br><br>协程:为轻量级线程,与线程相比,协程不受操作系统的调度,协程的调度器由用户应用程序提供,协程调度器按照调度策略把协程调度到线程中运行
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集合)。
epoll
可以通过函数监听文件是否就绪
epoll使用红黑树和队列,红黑树存放需要检测的节点,队列存放就绪的节点。<br>
网卡到进程会有上下文切换
查看命令
od -A x -t x1c -v dump.rdb
什么是进程 分配资源的最小单位
线程 发送启动一个线程发送消息 操作系统最小调度单元