一面

  • 在聊项目,聊到我们可以访问到一些敏感的用户数据,比如用户信息、订单信息等,面试官问如何保证这些敏感信息的安全性?参考new bing:
    数据加密:对敏感数据进行加密,确保数据在传输和存储过程中不被窃取或篡改。
    访问控制:对敏感数据的访问进行控制,只有经过授权的人员才能访问。
    安全培训:对系统使用人员进行安全培训,提高其安全意识和技能。

  • UV是多少?相关知识:UV(Unique Visitor):独立访客,统计1天内访问某站点的用户数

  • 假如线上某服务CPU占用率很高,QPS很低,响应很慢,你有什么办法定位问题?如果就是某个Java进程CPU占用率很高呢? 汇总new bing以及1的答案:

通过 top命令查看CPU情况,如果CPU比较高,则通过 top-Hp命令查看当前进程的各个线程运行情况,找出CPU过高的线程之后,将其线程id转换为十六进制的表现形式,然后在jstack日志中查看该线程主要在进行的工作。这里又分为两种情况:

  1. 如果是正常的用户线程,则通过该线程的堆栈信息查看其具体是在哪处用户代码处运行比较消耗CPU;
  2. 如果是 VMThread,则怀疑是否是GC导致CPU占用高。This VM Thread if it is consistently taking a huge amount of CPU could be a precursor to an OOM Heap error. 2

使用jmap命令生成Java进程的内存快照,查看是否存在内存泄漏。
使用jstat命令查看Java进程的GC情况,查看是否存在频繁的Full GC。

此外,如果接口耗时的情况是不定时出现,则可以通过压测的方式加大阻塞点出现的频率,再通过 jstack查看堆栈信息等手段,找到阻塞点。因为如果说该接口中有某个位置是比较耗时的,由于我们的访问的频率非常高,那么大多数的线程最终都将阻塞于该阻塞点,这样通过多个线程具有相同的堆栈日志,我们基本上就可以定位到该接口中比较耗时的代码的位置。如下是一个代码中有比较耗时的阻塞操作通过压测工具得到的线程堆栈日志:

`"http-nio-8080-exec-2"#29 daemon prio=5 os_prio=31 tid=0x00007fd08cb26000 nid=0x9603 waiting on condition [0x00007000031d5000]`` java.lang.Thread.State: TIMED_WAITING (sleeping)``at java.lang.Thread.sleep(NativeMethod)` `at java.lang.Thread.sleep(Thread.java:340)``at java.util.concurrent.TimeUnit.sleep(TimeUnit.java:386)``at com.aibaobei.user.controller.UserController.detail(UserController.java:18)``"http-nio-8080-exec-3"#30 daemon prio=5 os_prio=31 tid=0x00007fd08cb27000 nid=0x6203 waiting on condition [0x00007000032d8000]`` java.lang.Thread.State: TIMED_WAITING (sleeping)``at java.lang.Thread.sleep(NativeMethod)``at java.lang.Thread.sleep(Thread.java:340)` `at java.util.concurrent.TimeUnit.sleep(TimeUnit.java:386)``at com.aibaobei.user.controller.UserController.detail(UserController.java:18)``"http-nio-8080-exec-4"#31 daemon prio=5 os_prio=31 tid=0x00007fd08d0fa000 nid=0x6403 waiting on condition [0x00007000033db000]`` java.lang.Thread.State: TIMED_WAITING (sleeping)` `at java.lang.Thread.sleep(NativeMethod)``at java.lang.Thread.sleep(Thread.java:340)``at java.util.concurrent.TimeUnit.sleep(TimeUnit.java:386)``at com.aibaobei.user.controller.UserController.detail(UserController.java:18)`

从上面的日志可以看出,这里有多个线程都阻塞在了UserController的第18行,说明这是一个阻塞点,也就是导致该接口比较缓慢的原因。

    • 扩展问题:频繁full gc的案例?相关案例3
      用本地缓存(公司基础架构组自己研发的框架)存放了商品数据。如果只存热点商品,内存占用不会太大,但是如果存放全量商品,内存就不够了。初期我们给每个缓存记录都加了7天的过期时间,这样就可以保证缓存中绝大部分都是热点商品。后来过期时间被去掉了。没有了过期时间,日积月累本地缓存越来越大,很多冷数据也被加载到了缓存。
  • 如何防止因为并发导致的库存超卖问题?不能借助任何第三方中间件,只有一个数据库和一个Java应用。答案参考 本博—-Orderly Network面试

  • 一道笔试题

附: 本博—–达美乐的面试中有用jstack查看死锁的实例


  1. 博客园—–CPU飙高,频繁GC,怎么排查? ↩︎

  2. StackOverflow—–What does java “VM thread” do? ↩︎

  3. 稀土掘金—–jvm频繁full gc问题排查 ↩︎