海量数据下的实时模糊检索问题

核心思路是:将“模糊检索”工作从关系型数据库(如MySQL)中剥离,交给专业的搜索/分析引擎来处理。

例如人:通过名字模糊查询用户,2000w数据,20%每月数据量增长,返回列表要怎么做?
方案一:mysql硬撑
方案二:引入第三方专业引擎,如ES,这是处理海量数据模糊搜索的标准工业级方案。
方案三:高阶方案——分库分表 + ES

线程安全问题

下面这段代码有什么线程安全问题,有几种方案解决?

1
2
3
4
5
6
7
8
9
10
public class demo {

public void test(){
ReentrantLock lock = new ReentrantLock();
lock.lock();
//处理业务

lock.unlock();
}
}

问题:

  • 锁是局部变量,无法实现线程间互斥
  • 未使用 try-finally,可能造成锁永不释放

解决方案一:将锁提升为成员变量,并配合使用try-finally

1
2
3
4
5
6
7
8
9
10
11
12
public class Demo {
private final ReentrantLock lock = new ReentrantLock(); // 实例锁

public void test() {
lock.lock();
try {
// 处理业务
} finally {
lock.unlock();
}
}
}

优点:同一个 Demo 实例的所有线程共享一把锁,实现互斥。
缺点:如果多个 Demo 实例,则锁不共享;如需全局共享,用静态变量。

方案二:使用静态所(所有实例共享)

1
2
3
4
5
6
7
8
9
10
11
12
public class Demo {
private static final ReentrantLock lock = new ReentrantLock();

public void test() {
lock.lock();
try {
// 处理业务
} finally {
lock.unlock();
}
}
}

优点:所有实例所有线程共用一把锁,类级别互斥。
缺点:并发度最低,适合保护静态资源。

方案三:使用synchronized内置锁

1
2
3
4
5
public class Demo {
public synchronized void test() { // 实例方法锁,等效于 synchronized(this)
// 处理业务
}
}

或者

1
2
3
4
5
6
7
8
public class Demo {
private final Object lock = new Object();
public void test() {
synchronized(lock) {
// 处理业务
}
}
}

方案四:使用ReentrantLock的静态内部类单例锁

1
2
3
4
5
6
7
8
9
// 静态内部类持有锁实例(单例)
private static class LockHolder {
private static final ReentrantLock LOCK = new ReentrantLock();
}

// 对外提供获取锁的方法(可选)
private static ReentrantLock getLock() {
return LockHolder.LOCK;
}

网络安全性问题

例如:前端和minio直接存数据,会有安全问题。如何解决?

解决这个问题的核心思路是:由可信的后端服务颁发有时效、有限权限的临时凭证,前端仅使用这些凭证与 MinIO 交互。

主要有两种标准的解决方案:预签名 URL (Presigned URL) 和 STS 临时凭证 (Security Token Service)。

  • 预签名:将有时效性的Access Key 和 Secret Key放在url中,minio去验证签名
  • STS临时凭证:给前端颁发一组临时的 Access Key、Secret Key 和 Session Token,前端可以在有效期内和权限范围内自由操作 MinIO。

docker相关问题

编写Dockerfile:这是一个包含构建指令的文本文件,定义了从基础环境、依赖安装、端口映射和启动命令的全部步骤
集群情况下使用:docker buildx bake一次构建多个镜像,提高效率。

遇到OOM问题如何定位和解决?

原因:

  • 一次性申请对象太多了
  • 内存资源耗尽没有释放
  • 本身资源不够,可以使用jmap -heap 查看堆信息
    定位:
  • 系统已经OOM挂了,提前设置-XX:+HeapDumpOnOutOfMemoryError -XX:HeapDumpPath=(要保证磁盘空间),可以在服务宕机的时候导出dump文件到指定的路径中。通过VisualVM程序去查看这个文件,可以去看到实例数和占的大小;我们可以去看这个视力,看它的gc root,找到线程引用查看到具体的代码。
  • 系统运行中还未OOM,导出dump文件:jmap -dump:format=b,file=文件名.hprof PID或者第三方工具Arthas,虽然导出dump文件会stw,但是不导出影响更大。也可以使用jmap -histo:live pid 实时查看。
  • 结合VisualVM进行调试。

常用的Linux命令

  • 文件操作:ls, cd, cp, mv, rm, find;重点说 find:比如用 find . -name “*.log” -mtime -7 查找7天内修改的日志,配合 xargs 批量删除或移动。
  • 状态性能:top, free, df/du, ps, netstat;这是区分初级和中级的关键。重点说习惯用 top 看整体负载后,按 P(CPU)和 M(内存)排序;排查内存溢出时必用 jmap 或 free -h 看缓存占比。
  • 网络状态:ping, telnet, curl, ss;强调现在用 ss -tunlp 替代 netstat(更快),并主动提及用 curl -o /dev/null -s -w ‘%{time_total}’ 来测试接口响应时间
  • 文本三剑客:grep,awk,sed;要说:排查业务报错时,先用 grep ERROR 过滤,再用 awk ‘{print $5}’ 提取IP或耗时,最后用 sed 做批量替换配置。