Seeker的奇妙求职历险(腾讯医疗一面和网易有道一面)

前言

没想到PCG一面挂了之后被CSIG的医疗部门捞了,又面了一次,面完之后状态是显示等待复试,但是一直没消息,估计和阿里一样把我晾着吧。
网易有道面试感觉还算和面试官交谈甚欢,但是面完之后到现在都没有收到二面的通知,不会凉了吧。
雷火也是,明天就满一个礼拜了,也一直还是处理中。
哎,秋招真累。
心累归心累,面试整理还是要整理一下,下面还是总结一下这两次面试中遇到的一些问题。

场景/算法题

给出一个100M的文件,文件里面存放了多个英文单词,给出一台内存只有100M的机器,实现一个单词联想的功能,例如输入"ab",输出"abject"(悲惨的,广大秋招的同学们都过得非常悲惨),“abjure”(正式放弃,我正式放弃秋招,回家种田,家里也没有田,就只能啃老打电动,最后被愤怒的老父亲砍死在床上)。

一开始的时候我写了使用set存放文件中的单词,然后根据输入的数据逐个匹配,将结果存放到list中。
然后面试官说,你再看看题目,代码写不出来也没关系,写个伪代码或者说说思路。
我一看只有100M内存,好吧,这样应该不行。
这个故事告诉我们,就算面试时候紧张得不行也一定要多读几遍题目。

然后我说我想使用数据流的方式,每次读入内存一个单词,是就保存,不是就丢弃。
面试官说,这样每次都要遍历一遍太麻烦了,你再想想。

我思考了一会,想起了前几天那道在leetcode复制粘贴的前缀树。
我说,我想对这个文件进行分割,根据开头单词的不同存放到不同的文件中,然后在内存中保存一个map映射这些文件的名字,每次输入之后只把对应的文件读入内存。如果单个文件过大还可以继续分割。

然后面试官说,这样也行吧,本来我想的是压缩,但是你这种分割方式也行。
然后到这里大概10多分钟,也没让我继续写代码了。

Java八股文

面向对象、集合、JUC、volatile、synchronized之类的,这些有道也面了,腾讯这边没有细问,只是volatile让我详细讲了讲底层实现。有道这边让我详细介绍了hashMap、concurrentHashMap以及countDownLatch的实现和原理。

GC八股文

介绍下GC,从回收谁开始说起,GC root、可达性分析、三色标记法、增量更新、原始快照、CMS、G1,最后说说ZGC是怎么实现并发回收的。

计算机网络

腾讯这边真的很喜欢问网络,这次问我说说closed_wait状态发生在哪一端。

线程池

有道这边问了线程池,问我项目中用的什么线程池,我就说了说ThreadPoolExecuter,讲了讲原理,如何实现动态线程的,keepAlive如何实现的。

数据库八股文

有道问的其实不是那么八股文,就问我怎么优化的,怎么查看sql查询慢之类的,没有问我底层实现。
腾讯这边就相当八股文了,说一下事务、怎么实现的。

CPU突然飙升怎么办?

这个问题是腾讯问的,我没想到真有面试问这个的,就凭印象说了说,使用了阿里的arthas进行性能监控,先用top看看哪个进程,然后看看是进程中的哪个线程,这个线程是干嘛的,是业务线程还是GC,业务线程就打印一下当前堆栈信息,看看是不是有死循环或者是一直创建大对象。GC线程就看看哪个对象最多,是不是发生了内存泄漏,最后看看GC日志。最后再决定如何优化。

JVM参数和GC日志

这个问题是有道问的。
问我知道哪些JVM参数,答最大堆、最小堆、栈大小(还说的不是参数xmx)。
问我还有呢,我说还可以设置使用哪个垃圾回收器,设置一些CMS的参数,比如新生代、老年代大小,担保空间、GC阈值之类的。
然后问我有没有调过,有没看过GC日志?
答:没有,垃圾项目不需要调。
感觉是不是太实诚了,不过说调过又要问我怎么调的,到时候答不上来或者无法让他相信感觉会更糟。

从马老师那边找了一份课件,里面有详细的调优参数和GC日志分析,大致看一看,希望下次能多说一点吧。

GC常用参数

  • -Xmn -Xms -Xmx -Xss
    年轻代 最小堆 最大堆 栈空间
  • -XX:+UseTLAB
    使用TLAB,默认打开
  • -XX:+PrintTLAB
    打印TLAB的使用情况
  • -XX:TLABSize
    设置TLAB大小
  • -XX:+DisableExplictGC
    System.gc()不管用 ,FGC
  • -XX:+PrintGC
  • -XX:+PrintGCDetails
  • -XX:+PrintHeapAtGC
  • -XX:+PrintGCTimeStamps
  • -XX:+PrintGCApplicationConcurrentTime (低)
    打印应用程序时间
  • -XX:+PrintGCApplicationStoppedTime (低)
    打印暂停时长
  • -XX:+PrintReferenceGC (重要性低)
    记录回收了多少种不同引用类型的引用
  • -verbose:class
    类加载详细过程
  • -XX:+PrintVMOptions
  • -XX:+PrintFlagsFinal -XX:+PrintFlagsInitial
    必须会用
  • -Xloggc:opt/log/gc.log
  • -XX:MaxTenuringThreshold
    升代年龄,最大值15
  • 锁自旋次数 -XX:PreBlockSpin 热点代码检测参数-XX:CompileThreshold 逃逸分析 标量替换 …
    这些不建议设置

CMS日志

[GC (CMS Initial Mark) [1 CMS-initial-mark: 8511K(13696K)] 9866K(19840K), 0.0040321 secs] [Times: user=0.01 sys=0.00, real=0.00 secs] 
	//8511 (13696) : 老年代使用(最大)
	//9866 (19840) : 整个堆使用(最大)
[CMS-concurrent-mark-start]
[CMS-concurrent-mark: 0.018/0.018 secs] [Times: user=0.01 sys=0.00, real=0.02 secs] 
	//这里的时间意义不大,因为是并发执行
[CMS-concurrent-preclean-start]
[CMS-concurrent-preclean: 0.000/0.000 secs] [Times: user=0.00 sys=0.00, real=0.00 secs] 
	//标记Card为Dirty,也称为Card Marking
[GC (CMS Final Remark) [YG occupancy: 1597 K (6144 K)][Rescan (parallel) , 0.0008396 secs][weak refs processing, 0.0000138 secs][class unloading, 0.0005404 secs][scrub symbol table, 0.0006169 secs][scrub string table, 0.0004903 secs][1 CMS-remark: 8511K(13696K)] 10108K(19840K), 0.0039567 secs] [Times: user=0.00 sys=0.00, real=0.00 secs] 
	//STW阶段,YG occupancy:年轻代占用及容量
	//[Rescan (parallel):STW下的存活对象标记
	//weak refs processing: 弱引用处理
	//class unloading: 卸载用不到的class
	//scrub symbol(string) table: 
		//cleaning up symbol and string tables which hold class-level metadata and 
		//internalized string respectively
	//CMS-remark: 8511K(13696K): 阶段过后的老年代占用及容量
	//10108K(19840K): 阶段过后的堆占用及容量

[CMS-concurrent-sweep-start]
[CMS-concurrent-sweep: 0.005/0.005 secs] [Times: user=0.00 sys=0.00, real=0.01 secs] 
	//标记已经完成,进行并发清理
[CMS-concurrent-reset-start]
[CMS-concurrent-reset: 0.000/0.000 secs] [Times: user=0.00 sys=0.00, real=0.00 secs]
	//重置内部结构,为下次GC做准备

G1日志

[GC pause (G1 Evacuation Pause) (young) (initial-mark), 0.0015790 secs]
//young -> 年轻代 Evacuation-> 复制存活对象 
//initial-mark 混合回收的阶段,这里是YGC混合老年代回收
   [Parallel Time: 1.5 ms, GC Workers: 1] //一个GC线程
      [GC Worker Start (ms):  92635.7]
      [Ext Root Scanning (ms):  1.1]
      [Update RS (ms):  0.0]
         [Processed Buffers:  1]
      [Scan RS (ms):  0.0]
      [Code Root Scanning (ms):  0.0]
      [Object Copy (ms):  0.1]
      [Termination (ms):  0.0]
         [Termination Attempts:  1]
      [GC Worker Other (ms):  0.0]
      [GC Worker Total (ms):  1.2]
      [GC Worker End (ms):  92636.9]
   [Code Root Fixup: 0.0 ms]
   [Code Root Purge: 0.0 ms]
   [Clear CT: 0.0 ms]
   [Other: 0.1 ms]
      [Choose CSet: 0.0 ms]
      [Ref Proc: 0.0 ms]
      [Ref Enq: 0.0 ms]
      [Redirty Cards: 0.0 ms]
      [Humongous Register: 0.0 ms]
      [Humongous Reclaim: 0.0 ms]
      [Free CSet: 0.0 ms]
   [Eden: 0.0B(1024.0K)->0.0B(1024.0K) Survivors: 0.0B->0.0B Heap: 18.8M(20.0M)->18.8M(20.0M)]
 [Times: user=0.00 sys=0.00, real=0.00 secs] 
//以下是混合回收其他阶段
[GC concurrent-root-region-scan-start]
[GC concurrent-root-region-scan-end, 0.0000078 secs]
[GC concurrent-mark-start]
//无法evacuation,进行FGC
[Full GC (Allocation Failure)  18M->18M(20M), 0.0719656 secs]
   [Eden: 0.0B(1024.0K)->0.0B(1024.0K) Survivors: 0.0B->0.0B Heap: 18.8M(20.0M)->18.8M(20.0M)], [Metaspace: 38
76K->3876K(1056768K)] [Times: user=0.07 sys=0.00, real=0.07 secs]

Linux常用命令

有道这边问我,你查看日志的时候涉及到哪些命令?
我说我们一般是使用可视化工具直接下载下来的,如果不能下载的话就cd,找到日志文件vim,如果太大打不开就使用命令查看前十行之类的(具体命令忘了)。
然后问我在文件中查找某个字段用哪个命令?不知道。

查看前十行:
head -n 10
后十行
tail -n 10
第3000行开始,向后1000行
cat filename | tail -n +3000 | head -n 1000
查找某个字段
grep 'word' filename(果然是grep,当时应该猜一下的)

分布式事务

这个是腾讯PCG问的,当时忘记写下来了。之后看了看就2阶段提交、TCC、异步消息。具体的我已经更新在MySQL那一篇了。

分布式锁

这个是有道问的,问我分布式锁了解过吗?
我就回答了redis中的分布式锁,说了一下可能出现的问题比如时间过长需要设置过期时间、删除锁的时候删除了别人的锁所以需要设置锁名字。
然后他说,还有吗,别的分布式锁了解吗?
答,不会。

数据库的分布式锁

数据库的分布式锁是通过数据库的事务来实现的,当一个请求进入之后首选需要去锁(写锁)定数据库的某一个字段,然后等到处理完成之后再释放。

redLock

redis的分布式锁,当一个请求需要锁定资源的时候首先会设定一个锁的超时时间和有效时间,超时时间小于有效时间,然后向所有的redis尝试锁定这个资源,超过超时时间如果没有加锁成功则认为加锁失败。
如果超过一半的redis都加锁失败则认为这次加锁失败,释放已经锁定的所有资源。
如果超过一半的redis加锁成功,则认为加锁成功,锁的真正有效时间为(有效时间-最后一个redis返回加锁成功的时间)。

热更新和分布式

有道问的。
你们网吧项目每次更新都要停机对吧?那么有没有什么办法可以让他不停机呢?

我首先想到的是热更新,就说了OSGI,更新的时候把类加载器一同替换,这样就可以重新加载。

然后他说再想想,我想了一会没想出来,他说想想阿里他们怎么做的。
我说,他们肯定使用了高可用,阿里的话应该是一个集群,使用nginx进行代理,一台机器下线之后就用nginx把请求转发到另外一台机器上去。

他问我,nginx怎么配置?
答,不会。

Nginx如何配置

nginx有一个nginx.conf文件,所以使用nginx只需要对这个文件进行配置就可以了。
那么如何设置反向代理呢?

//表示对“/”开头的URL请求进行代理
location /{
	//代理的地址和端口号
	proxy_pass http://127.0.0.1:3000
}

如何设置负载均衡

upstream my_server_pool{
	//nginx有4中负载均衡算法,默认的是轮询,根据分配的权重进行轮询
	//字段从左到右分别为代理地址、权重、最大错误连接、请求失败后暂停服务时间
	server 127.0.0.1:3308 weight=1 max_fails=2 fail_timeout=30;
	server 127.0.0.1:3309 weight=2 max_fails=2 fail_timeout=30;
}

使用Nginx进行代理的还有一个好处就是可以解决跨域问题。

反问

腾讯这边问了下哪个部门,然后问他我哪里还可以提升。他说,时间太短看不出来。不过腾讯一共就面了30分钟,面试官还不是搞Java的,估计也面不出什么。

有道这边他说,你做的项目都是单机的,分布式的内容可以看一看,微服务、springCloud、kafka之类的。
没想到现在面试还要懂分布式了吗,想想也是,别人懂,你不懂,不就被筛了吗?哎,太卷了。


在这里插入图片描述

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值