huawei 实习生

java基础
1.String常用的方法有哪些 tolowercase….
String str=””;
str.toCharArray();
2.HashMap.putIfAbsent()
3.cookie和session的区别(sessionId存储在cookie里)
4.SQL优化的问题,建表三范式,explain命令(补一下知识)
5.事务的注解什么时候失效(补一下spring aop)
6.事务的隔离级别
7.类在什么时候加载,几种类加载器(反射的时候会不会加载)
8.泛型
B extends A
List lst=new List();
泛型擦除的问题
9.git rebase的使用 回滚
10.分页插件

国际化中台P5

小组主要负责网关,服务稳定性,节能提效,全链路监控
1.二十分钟笔试,问客户端如何不通过json,html等文本协议实现对象序列化,使用java语言,服务端可跨语言解析。
答:二进制传输协议
2.一小时面试
先问网络
2.1 ASCii ,Unicode UTF-8 编码有什么不同,如果我客户端使用ASCii对中文编码,服务端接收会有什么后果?

答:考虑不同编码的字节数,使用字节数少的编码去编字节数多的字符,会出现信息缺失,乱码现象。
举例:数据库常用的UTF8mba编码和UTF8编码,如果数据库设置字符集是UTF8,存储UTF8mba就会乱码,UTF8mba对应5个字节,UTF8是4个字节

2.2经典网络八股文,在浏览器输入url,会发生哪些事情?

答:没有完整复述出流程,主要是浏览器这边会根据http协议找到服务端机器,然后对数据包包装header,MAC,IP,TCP,HTTP层层递进,建立TCP连接之后,再拆包,获得数据。
面试官提示:找到服务端地址要先请求DNS,再追问DNS细节。
答:先找到DNS服务器根节点,从根节点查到一级域名解析服务器地址,再去一级域名服务器找二级域名服务器地址,层层解析,最后拿到host:端口信息。

2.3TCP协议中close_wait和time_wait的区别(本质是四次挥手的具体原理)

答:close_wait是服务端收到客户端自己没有信息需要传输的通知了,自己进入close_wait,并且向客户端返回ACK表示自己知道客户端没有内容传输了。这时候进入time_wait,time_wait一般是两个数据包传输周期,因为首先服务端要保证客户端能收到自己的ACK,此为一个周期,再就是如果客户端有数据包因为网络延迟在客户端告诉服务端自己没有内容传输了之后才抵达服务端,服务端多等待的这一个时间周期能保证延迟包被接收。否则这个端口关闭后再次被复用,网络延迟的数据包会污染新的TCP连接!!

2.4TCP的可靠性是怎么实现的?
可靠性要保证数据包没有丢失,也不会重复接收,再就是服务端能按照数据包的正确顺序来接收。
从以上三点来回答,其实都是依靠数据包里的Seq序列号来保证的。数据包有丢失,服务端可以感知到序列号的不连续性,缺失的序列号就是丢包了,重复接收也是根据序列号,如果序列号重复,就不接收此数据包。顺序性也依据序列号来保证。
面试官追问:服务端怎么知道客户端要发多少数据包过来?
其实客户端发送数据包会在Header里加上包的总大小。Content-Length。不知道是不是想问这个,假如TCP协议规定了每个数据包的固定大小,那服务端是可以计算出数据包的数量的。但每个数据包大小是不是一致?存疑。没答上来。

2.5UDP为什么传输性能要比TCP好,两种协议各自适应的情形
答:UDP不需要进行三次握手,四次挥手的过程,所以传输性能好。。。(不知道标答是什么,可能是UDP没有维护连接这一概念吧)UDP适合流媒体传输,丢包导致的视频掉帧无所谓,但不能延迟。TCP适合大文件传输,因为UDP的数据包有大小限制(UDP不分包,只有一个包,这个昨天也没答上来)

2.6.1 为什么要对URI进行编码

答:便于服务端解析哪些是参数,哪些是地址串。

2.6HTTPS相关
答:不了解。。(印象中涉及证书认证,SSL。。。)

2.7
接着问操作系统
为什么人们总说系统调用是耗费性能的?

答:线程从用户态进入内核态,需要进行上下文切换。具体切换的内容是诸如代码块的地址,寄存器地址,栈指针等
面试官对我的回答做出总结:线程上下文切换需要先保存用户态数据,再读取内核态的数据,从内核态返回的时候同样要先保存内核态线程状态,再转化到用户态。
答:对。

2.8.0
简历上写:熟悉mybatis框架
问:如果不使用框架,如何进行数据库连接?
答:Java提供了建立连接的SPI,各个数据库厂商按照SPI的规范实现自己的connectionSDK,Java程序启动的时候,会根据驱动的名称加载相应的SDK和数据库建立连接。复述了一下JDBC的连接过程(不完整),创建PreparedStatement对象对sql进行拼接,再通过连接发送给服务端。
追问:为什么不同的数据库要使用不同的驱动?
答:每个数据库采用的传输协议不同,就对应不同的SDK实现。

2.8.1
JMM模型相关(我写在简历上了,才会问这个)
答:JMM使得每一个JVM中的程序都认为自己拥有完整独立的内存区域,制定一些规则,处理(不同线程)对同一块内存的竞争使用时的并发问题。
JMM相关八股文定义没有复述出来。
面试官追问:
JMM的好处是什么?为什么要引入JMM?
答:屏蔽底层操作系统内存的概念,可以让JVM分配的内存在程序自己看来是连续的。(今天回想,可能跟垃圾回收有关)

2.8.2
简历上写熟悉springcloud框架
问:RPC调用要经历哪些过程
答:公司使用的RPC协议是http,流程和前面提到的http流程大致相同。
面试官提示:服务是怎么知道自己要调用的服务地址的?
答:Eureka注册中心返回服务的具体地址
问:请求Eureka的过程叫什么
答:服务发现。。(????概念问题,不太清楚)

2.9
JVM分代进行垃圾回收有什么好处(年轻代,老年代)
答:年轻代经过多次survival会进入老年代。分代管理主要是为了减少stw的时间。(良好的回收策略是多次小范围的youngGC,尽量避免出现FullGC)

2.10
开始问项目
问:实际工作中排查问题的经历
答:我以自己简历上的项目为例子,描述排查推送系统FullGC的过程。
告警系统告警=>由于发生FullGC,首先想到的是把进程内存dump出来,分析出是哪个对象占用大量的内存=>找到对象后回到代码逻辑,分析为什么这个对象会占用这么多内存,以及内存回收不掉的原因=>设置过期参数解决内存泄漏的问题。
面试官追问:这个参数是怎么实现内存不会无限增长的?
答:把Apache-Http内部代码逻辑复述了一遍

2.11
问一台服务器突然CPU飙升,怎么排查
答:top命令找出是哪个进程占用CPU
面试官追问:怎么找到这个进程里哪个线程消耗CPU
答:不知道。。
面试官给出答案:每个时刻jstack导出瞬时程序的线程使用情况,对多个时刻的jstack分类汇总,统计每个线程出现的次数,如果有一个线程每时每刻都在运行,就可以认为找到了该线程。

2.12
问Linux常用查询系统IO,CPU,内存的命令
答:不知道。。。

2.13
问redis为什么单线程可以承受高并发?
答:系统调用epoll的原理。一个线程就可以处理事件监听并执行。redis的执行操作都是基于内存,实际的业务逻辑执行非常快,网络IO又通过epoll实现,所以单线程模型也很高效。

2.14
问redis采用多线程来监听客户端连接,服务效率会变高吗?
答:不一定,多线程就会引入并发访问内存的问题,加锁是消耗性能的,但是多线程确实可以让redis的增删改查业务逻辑运行更快,所以最终结果是两者的平衡。(不知道面试官想听什么答案。。。)

总结:事后才知道这个部门是做网关的,所以面试的侧重点都在客户端和服务端是怎么交互的,编码问题、协议问题问的非常多!

二面:写题半小时=>
1.给定一个IPV4的地址判断是否有效,
2.给定字符串aabbbacc,三个及三个以上重复字母会抵消,示例字符串结果是cc

三面:
你从这个项目中学会了什么?
理论知识的实践,对网络IO有深入理解,数据库表结构设计,代码逻辑抽象能力,系统设计(有了解),问题排查思路,排查实践,增强失败(arthas 使用),依赖排查???
你对这个项目的贡献是什么?
全链路协助排查问题,配置下发的流程很长,需要大家分段排查。解决网络隔离问题,为全链路项目提供基础的环境支持,功能支持
你的亮点是什么?
重构这方面,抽象能力的体现,数据库对象的抽象。更多是算法上的优化,递归解析对象等。心跳设计上,针对不同业务不同心跳响应时间,设计一个单独的字段。
这个项目的技术难点在哪?
增强时机判断,是否要增强,前面有matcher来决定具体增强匹配规则,分区的匹配,标签的匹配,
怎么排查问题?
主要是资源问题。
1看告警,2看日志,gc日志可以看到频繁fullgc后系统占用的内存还是增长趋势,可以知道有内存泄漏的问题。3看代码。
首先要重启服务,
为什么转行计算机?
被开源环境吸引,认为知识没有那么封闭,喜欢这样技术主导的交流氛围。以钻研问题、解决问题为乐趣。
自己的规划是什么?
目前工作经验不足,希望接触更多应用于生产的技术,自学的理论知识和公司实际使用还是有差距。在广度上拓展后再致力于具体工作上的深度挖掘,为公司贡献更多自己的努力。对于技术有极客精神。
毕业时接触最多的就是来杭州阿里的。
全链路项目,业务为什么需要压测?业务并发多大?
目前参与了全链路压测的业务有实名,用户,签署三个业务域,压测主要是为了对自身系统进行摸底,老板要求业务量增长几倍,自身系统是否能支持这么大的流量。有客户希望我们给出服务压测报告。
压测的接口主要根据业务域,业务场景的核心接口都会覆盖到。
比如签署业务,部分接口压测QPS达到100-300不等。
对不同业务接口采取的并发量不同,QPS有300左右,服务出现慢查,连接资源受限,服务报错5xx,流量增大,服务内存上涨,存在OOM风险。
推送系统项目,业务场景,什么时候需要异步什么时候需要同步代码实现?
耗时的操作不要在同步过程去处理。
推送系统接入MQ的作用:削峰填谷
改为异步的两个作用:1.消费MQ改为异步了,一是防止MQ消息堆积,二是防止各个业务之间消息的干扰,阻塞是按照topic阻塞。而将MQ的消息转移到推送系统内存中时,阻塞是按照路由阻塞的。
2.Client内部实现是异步IO,业务线程不会阻塞在等待IO响应上,提高系统的处理能力。
为什么要使用异步IO是因为,如果是同步,那系统每秒能处理的请求最多只能是我的工作线程数量。
异步IO有一个线程去轮询事件,我自己的业务线程一直都在运行,没有阻塞等待。
业务发送端QPS = MQ topic 的TPS 20-30左右
推送系统推送端的QPS 大致相当,保证了消息基本没有积压。(观察近几天流量,最高QPS也只有30,并不太需要削峰。)
推送系统整体业务流程是:公司内部业务应用有通知三方客户的需求,具体实现是,业务把消息发送给MQ,
推送系统从MQ消费消息,msg中有三方客户的http地址,推送系统负责请求这个地址完成消息推送,最后记录日志供业务查询使用。
MQ消费积压,并不是因为只使用一条队列,积压在一条队列里,MQ内部16条队列,mqclient一次拉取一批消息到服务本地,可拉取的消息是由16条队列到时间可以消费的消息共同组成的。

你人生最大的挫折是什么,最跨不过去的一道坎是什么?
转行这件事情。人对于未知的东西总是恐惧的。特别是当自己处在一种别人认为很稳定,前途一片光明的状态的时候,自己要主动放弃这些东西,去追求未知,这个决策是需要很大的决心的。知道自己内心想要的东西,如果这条路确实不能满足自己的期望,会决然放弃。我自己想要的东西是什么?希望通过自己的努力改变一些事情,而不是通过我的背景我的出身去决定我这个人的发展。始终还是相信有付出就会有回报。

新老员工的优势与区别。
新员工最缺乏的是经验,但我觉得不是长久会存在的问题。老员工都是从新员工过来的,只要自己积极学习,工作勤谨,经验迟早会丰富起来。
但是新员工敢想敢做,也没有家庭负担,成长起来很快。对技术有热情,更勇于挑战自己,不安逸在舒适圈里。
老员工见多识广,遇到故障,能更快定位解决。知识的积累更深厚,更能看到问题的本质。

我的缺点是什么?
应激能力不高。我觉得这个是个人天赋的问题。为了弥补我这个缺陷,我会做很多准备工作,台上一分钟台下十年功。比如公司会安排故障演练,故障复盘,故障总结归档,都是为了让我们在故障发生的时候能更从容地解决问题。我自己会熟悉代码,刚接受一个项目,遇到的问题都会自我沉淀,文档记录,一个是代码熟悉度,一个是排查问题套路熟悉度。故障排查手册多看。熟能生巧。
举例大学上课,老师喜欢讲完新的知识点立马出题,然后限定时间内把答案发给她,这时候考验的一部分是这些知识掌握程度,一部分是自己的应激能力,能不能在短时间内解答题目。为了弥补自己的缺陷,我都是自己自学一遍下节课的内容,答题就很沉着,也取得了很好的成绩。

如果有其他公司给出offer,为什么选择阿里?
阿里的产品深入人心,淘宝,支付宝,钉钉这些都是我日常会用到的软件服务。本科从同学那里听说的阿里,受众面比较广泛。技术栈也很匹配。电商行业沉淀很多年,海外电商也有十多年了,技术体系完善健壮,但是一旦发现问题,肯定不是能够轻松解决的,有技术挑战。其他新兴的大厂,字节,短视频业务,杀时间的软件,不太接受这样的娱乐方式。虽然现在流量当道,但是娱乐和刚需比起来,需求强度要弱化很多。我不需要别人来填充我的碎片化时间,自己每天都有安排,也有自己的事情要做。

事务是怎么实现的?
ACID 原子性,要么全部成功,要么全部回滚。一致性,事务执行前后处于一致性状态,AB互相转账,总数不变。隔离性(四种隔离级别),事务之间感觉不到其他事务也在执行。持久性,一个事务一旦提交,对数据库的改变是永久性的,不能因为数据库发生故障事务的结果就丢失了。
mysql是可重复读,解决不了幻读的现象。mvcc来解决。
事务的原子性是通过undo log 实现的,先写到磁盘,再对数据进行操作,一旦失败就会根据undo log 回滚。
事务的持久性是通过redo log 实现的, 当事务真正提交时,会先把redo log 刷新到磁盘,再把数据库数据刷新到数据库,重做日志的大小是512字节,刷新到磁盘是原子性的。
undo log 和redo log共同组成transaction log
事务id,修改的行元素,old value ,new Value
隔离性是把并发的事务线性化,优化回滚性能。避免级联回滚。
可重复读是读取的同一范围数据的快照,但是会发生幻读,幻读的产生是update操作的不一致

排查问题必备命令详解:
jmap 会先gc,保证分析的都是存活的对象
提取进程内存信息,用于分析OOM的原因。
jmap -dump:format=b,file=HeapDump.bin
jmap -heap 输出堆的信息

jhat简单分析内存中对象情况
jhat -J-mx768m -stack false HeapDump.bin

jstack
jstack 用于JVM当前时刻的线程快照,又称threaddump文件,它是JVM当前每一条线程正在执行的堆栈信息的集合。生成线程快照的主要目的是为了定位线程出现长时间停顿的原因,如线程死锁,死循环,请求外部时长过长导致的停顿等原因。
jstack 可以用jps查看java进程id。
实际运行中,一次dump不一定能确认问题。多产生几次分析问题。
jstack -F 线程挂起要加上-F才能dump信息
jstack -F -l pid 查出某个进程中运行的所有线程

jstat
可以观察classLoader compiler gc相关信息。
jstat -gcutil 2000 100 #每2s输出一次内存情况,连续输出100次
jstat -gc 输出heap各个分区大小
对应的指标:
S0C 年轻代ServivorFrom容量
S1C 年轻代ServivorTo容量
S0U 使用的内存
S1U 使用的内存
EC Eden容量
EU Eden使用的
OC 老年代容量
OU 老年代使用的
PC 永久代(元空间)容量
PU 永久代使用量
YGC gc次数
YGCT gc时间
FGC 老年代GC 次数
FGCT GC时间
GCT gc总时间

jstat -gcutil xxxx
展示的指标是U/C的百分比

jstat -gcnewcapacity xxxx
jstat -gcoldcapacity xxx
jstat -gcnew xxx
jstat -gcold xxxx

jstack日志重要分析:
Deadlock 表示有死锁
Waiting on condition 等待某个资源或条件来唤醒自己。具体需要根据jstack trace 分析,比如线程正在sleep,网络读写繁忙等。
Blocked:阻塞
waiting on monitor entry 在等待获取锁
如果系统慢,需要关注Blocked,Waiting on condition
如果cpu高,线程有死循环,关注runable状态
free
free显示系统内存的使用情况,包括物理内存,交换内存和内核缓冲区内存
free -h 输出更友好
持续观察内存的状况 free -h -s 3 每隔3s打印一次
Mem 内存使用状况,Swap是交换空间的使用状况
total 显示系统总的可用物理内存和交换空间大小
used 显示已使用的
free 可用的
shared 共享内存
buff/cache 使用的物理内存大小
available 还可以被应用程序使用的物理内存
buffer特指对块设备的缓存,cache 指所有缓存,其中包括buffer
free 和 available的区别,free是真正没有使用的物理内存,available 是从应用角度看到的可用内存。
available=free+buffer+cache

交换空间是磁盘上的一块空间,当物理内存吃紧的时候,linux会将内存中不常访问的数据保存到swap上,当系统需要访问swap上的内容时,再加载进来,换入换出的概念。
netstat
netstat 用于显示网络相关信息,如网络连接,路由表,接口状态,多播成员等。
输出内容分为两部分:
Active Internet Connections 有源TCP连接,”Recv-Q”和”Send-Q”是接收队列和发送队列。这些数字一般都是0,如果不是表示软件包在队列中堆积。
Active UNIX domain sockets 有源Unix套接口,只能用于本机通信。
Proto显示连接使用的协议,RefCnt表示连接到本套接口的进程号,Types显示套接口的类型,State显示套接口当前状态,Path表示连接到套接口的其他进程使用的路径名。

netstat -a 列出所有端口,包括监听和未监听的
netstat -at 列出所有tcp端口
netstat -au 列出所有udp端口
netstat -l 列出监听端口
netstat -lt 只监听tcp的端口
netstat -lu 只监听udp的端口
netstat -s 显示每个协议的统计信息
netstat -st/-su
netstat -p 可以显示pid/进程名称
找出程序运行的端口:
netstat -ap | grep ssh
找出运行在指定端口的进程
netstat -an | grep ‘80’
netstat -i 显示网络接口列表
netstat -ie ===ifconfig
查看连接某服务端口最多的IP
netstat -nat | grep ‘ip’ | awk ‘{print $5}’ | awk -F: ‘{print $1}’ | sort|uniq -c|sort -nr|head -20
分析access.log 获得访问前10的ip
awk ‘{print $1}’ access.log | sort|uniq -c|sort -nr|head -10

top
输出分析:
前五行是当前系统情况整体的统计信息区。
up 70 days 系统已经运行70天。
2 users 当前有2个用户登陆系统
load average 每分钟负载情况
Tasks 系统有206个进程,1个运行,205个休眠,stoped 0,zombie 0
Cpu 状态信息
5.9%us 用户空间cpu百分比
3.4% sy 内核空间百分比
0.0% ni 改变过优先级的进程占用的cpu
90.4% id 空闲cpu百分比
0.0% wa IO等待占用cpu百分比
0.0 hi 硬中断
0.2% 软中断
内存状态:
total used(被内核纳入管理,但不一定真正占用,不会释放给free) free(没被内核纳入管理) buffers
swap交换信息
total used(重点关注,如果这个数值在不断变化,说明内存不够用了) free cached
进程监控状态分析:
Pid 进程Id,
pr 优先级
ni 优先值
virt 虚拟内存总量=swap+res
res 进程使用未被换出的物理内存
shr 共享内存
s 进程状态
%mem 物理内存百分比
time+ 进程使用cpu总计
command 进程名字
press 1 可以看逻辑cpu状况
press b 高亮当前进程