Linux
Java相关命令
列出所有包含 “java” 的进程
ps aux | grep java
通过进程名搜索
ps aux | grep 进程名
```
强制终止进程id为PID的程序
``` Bash
kill -9 <PID>
```
运行时指定 JVM 参数:
``` Bash
java -Xmx1024m -Xms512m -jar MyApp.jar
常见 JVM 参数:
-Xmx: 最大堆内存(如 -Xmx4g)
-Xms: 初始堆内存
-XX:+UseG1GC: 使用 G1 垃圾回收器
-XX:+HeapDumpOnOutOfMemoryError: OOM 时自动生成堆转储文件
- 查看 CPU、内存、磁盘、负载
查看 CPU / 负载:top、htop
查看内存:free -h
查看磁盘:df -h
查看目录大小:du -sh 目录
系统负载:uptime
查看端口占用
netstat -tulpn | grep 端口
lsof -i:端口
杀死进程
kill -9 PID
查看日志常用命令
实时看日志:
tail -f xxx.log
看最后 N 行:
tail -n 200 xxx.log
搜索日志:
grep '关键字' xxx.log
grep -C 10 '关键字' xxx.log # 前后10行
翻页查看:
less xxx.log
文件查找
按文件名查找:
find /path -name "xxx.jar"
按内容查找:
grep -r "内容" /path
进程相关
查看 Java 进程:
运行
ps -ef | grep java
优雅停止:kill PID
强制杀死:kill -9 PID
磁盘满了怎么排查?
df -h 看哪个盘满
du -sh /* 看大目录
重点清理:
日志文件 .log
临时文件 /tmp
大文件无用备份
CPU 高怎么排查?
top 找到高 CPU 进程 PID
top -Hp PID 找到高耗 CPU 线程
将线程 ID 转 16 进制
jstack PID 导出栈,定位代码块
内存溢出 / 泄漏怎么定位?
看内存:free -h、top
导出堆 dump:
bash
运行
jmap -dump:format=b,file=heap.hprof PID
用 MAT/JProfiler 分析泄漏点
软链接、硬链接区别
硬链接:同一个 inode,删原文件不影响
软链接:类似快捷方式,原文件删了失效
创建:
bash
运行
ln 源文件 目标 # 硬
ln -s 源文件 目标 # 软
权限问题(rwx)
r=4,w=2,x=1
755:所有者读写执行,其他读执行
777:所有权限(不推荐生产)
修改:
bash
运行
chmod 755 文件
chown 用户:组 文件
定时任务
bash
运行
crontab -e
示例:每天凌晨 2 点执行
plaintext
0 2 * * * /脚本.sh
网络问题
测试连通性:ping IP
测试端口通不通:telnet IP 端口、nc -zv IP 端口
查看路由:route -n
消息队列
消息队列的话,它主要是一种用于异步通信的中间件,核心就是异步通信和解耦
网络通信相关
TCP与UDP的区别;
TCP 是面向连接的(需三次握手建立连接),UDP 是无连接的(直接发送数据)
TCP 保证数据可靠传输(确认、重传、排序),UDP 不保证(可能丢包、乱序)
适用场景
TCP 用于文件传输、网页浏览等可靠场景;UDP 用于视频流、在线游戏等实时性要求高的场景。
TCP 的三次握手(建立连接)
目的:确保双方能正常通信,并同步初始序列号(ISN)。
TCP协议的三次握手,四次挥手
过程
第一次握手
客户端发送 (请求连接),进入 SYN_SENT 状态。
第二次握手
服务器回复 (收到客户端请求),进入 SYN_RCVD 状态。
第三次握手
客户端发送 连接建立
TCP 的四次挥手(断开连接)
目的:确保双方数据完全传输完毕后再释放连接。
过程
第一次挥手(FIN)
主动方(如客户端)发送(请求断开)
第二次挥手(ACK)
被动方(如服务器)回复 (收到断开请求)
第三次挥手(FIN)
被动方发送 (确认自己数据已发送完毕)
第四次挥手(ACK)
主动方回复 (确认被动方断开),被动方收到后直接关闭。
网络通信的三要素
IP,端口,传输协议
Quartz
Quartz的 Cron 表达式
Cron 表达式用于定义复杂的定时任务调度规则
字段顺序:秒(0-59) 分(0-59) 时(0-23) 日(1-31) 月(1-12) 周(1-7) [年(可选)]
特殊符号:
* : 任意值(如秒=*)
? : 不指定值(仅用于日和周字段,避免冲突)
- : 范围(如日=1-5)
, : 列表(如周=1,3,5)
/ : 步长(如秒=0/15 表示每15秒:0,15,30,45)
L : 最后(如日=L 表示月末)
W : 最近工作日(如日=15W 表示离15号最近的工作日)
# : 第几个(如周=6#3 表示每月第三个星期五)
集群与分布式
集群(Cluster)
概念:一组通过高速网络互联的物理或虚拟服务器,协同工作以提升系统的性能、可靠性或扩展性。
目标:通过资源聚合(如计算、存储、网络)实现高可用性或高性能。
特点:
节点通常位于同一数据中心或相近网络环境。
节点间共享负载(如负载均衡集群)或共同完成任务(如高性能计算集群)。
分布式系统(Distributed System)
概念:由多个独立计算机节点通过网络连接组成的系统,节点协同完成统一任务,对外表现为单一系统。
目标:通过跨节点协作实现资源共享、容错性和地理分布支持。
特点:
节点可分布在不同地理位置,甚至异构环境(不同硬件、操作系统)。
强调数据一致性(如分布式数据库)或任务协调(如区块链)。
容器和虚拟机的区别
容器和虚拟机都是虚拟化技术
容器是“轻量级进程隔离”,适合敏捷开发和云原生;虚拟机是“完整的系统虚拟化”,适合强隔离和异构环境
Docker和Kubernetes(k8s)
Docker 是容器化技术,负责打包和运行单个容器
Kubernetes 是容器编排工具,负责管理多个容器(尤其是跨主机集群)的生命周期,提供高可用性、弹性伸缩等能力
你们这个项目如何部署的
我们这个项目就是所里边的人用,更新的时候就说一下,然后就是直接打成jar包传到服务器
启动的时候用的是nohup命令nohup java -jar jar包
服务器用的是
nginx
设计模式
单例模式的实现方式?懒汉式和饿汉式区别?
饿汉式:类加载时创建实例,线程安全,缺点:启动慢、浪费内存;
懒汉式:使用时创建,线程不安全(加 synchronized / 双重检查锁解决);
推荐:双重校验锁的懒汉式实现、枚举(防止反射破坏)。
场景:工具类、配置类、线程池、数据库连接池
开发里常用双重校验锁的懒汉式实现,
项目里的库存统计工具类、全局配置读取类都用了,保证全项目一个实例,避免重复创建浪费资源,还兼顾了懒加载和线程安全。
双重校验锁的懒汉式实现:核心是把构造器私有,通过全局静态方法获取唯一实例,避免重复创建对象浪费资源,同时保证多线程场景下调用不出问题
工厂模式
简单工厂:一个工厂造一类产品。
工厂方法:每个产品对应一个工厂。
抽象工厂:造一 “家族” 的产品。
好处:解耦,调用方不用关心对象怎么创建,以后换实现不用改代码。
核心是工厂方法模式:
- 定义统一的数据源解析接口:抽离所有数据源解析的公共方法,比如(数据接入)、(数据解析)、(解析后数据校验)
- 为每个数据源写专属的解析实现类:比如wos解析类、IEEE 解析类、
- 封装简单工厂做解析对象的统一创建:写一个数据源解析工厂类,里面根据传入的「数据源类型标识」(比如配置里的 WOS、IEEE、ZIP),动态创建对应解析实现类的对象
设计核心思路:是用接口定标准、实现类做差异化、工厂做对象创建,核心就是把「对象创建」和「业务使用」解耦,适配多数据源的扩展需求。
代理模式
核心是对方法做前置 / 后置增强,Spring AOP 底层就是这个。
比如后台管理系统的操作日志,
第一步:自定义日志注解,标记需要记录日志的方法
第二步:编写切面类,定义日志的核心处理逻辑
方法执行前:获取操作用户,记录操作开始时间
方法执行后:获取方法执行结果、返回值,;
异常处理:记录异常信息,
第三步:日志持久化与异步优化
把封装好的日志实体类通过Spring 的 @Async 注解交给异步线程池处理,异步将日志写入MySQL 日志表
第四步:全局配置,实现日志的统一管控
在 Nacos 里配置日志记录的开关和日志级别,比如测试环境关闭部分高频操作的日志,生产环境开启全量日志;同时在切面里做了日志过滤,比如忽略一些测试类方法、空数据批次的操作,避免无效日志产生,让日志记录更精准
核心业务代码里完全没有日志相关代码,保证了核心逻辑的纯净性,后期排查问题时,能通过日志表快速追溯每一次数据处理的全链路信息
Java常见数据结构及特点
数组(Array)
数组是通过连续的内存空间存储元素,每个元素位置由索引直接定位
- 特点:连续内存、索引直接访问速度快、大小固定。
- 适用:频繁随机访问、内存敏感场景。
- 扩容成本高:需创建新数组并复制旧数据
数组是内存效率最高、访问最快的结构,但灵活性差;适合静态数据或已知大小的场景,动态场景优先用ArrayList
队列
队列是先进先出的结构,核心操作:入列、出列、判空。
- 类似于单向管道,先进去的先出来
- 顺序性:元素按加入顺序排列,先进入的先被移除。
- 两端操作:仅在队首(Head)出队,队尾(Tail)入队。
- 状态检查:需支持判断队列是否为空。
核心原则:队列的核心是顺序控制,选择时需平衡操作频率与性能需求。
链表
链表是通过节点(Node)链接数据,每个节点包含值域和指针域(指向下一个节点)
- 动态大小:无需预分配内存,按需扩展。
- 插入/删除快:只需调整指针(O(1)时间,头尾最优)。
- 随机访问慢:需从头遍历(O(n)时间)。
- 内存碎片:节点分散存储,缓存命中率低。
应用场景
动态数据集:频繁增删但少查询的场景(如LRU缓存淘汰机制)。
内存敏感场景:节点可动态分配,适合大规模数据存储。
队列/栈实现:链表可实现高效的头尾操作(如Java的LinkedList底层是双向链表)。 - 总结
单链表:内存占用小,但尾插和删除需遍历。
双向链表:功能更强大,但指针维护稍复杂。
适用原则:
高频头尾操作 → 双向链表。
仅需单向遍历 → 单链表。
线程安全 → 用ConcurrentLinkedDeque