211非科班阿里Java后端实习面经(三面+HR面)(已意向)

写在前面

  1. 本人目前是北邮非科班大三在读,GPA中上,培养方案内包括一些不是很硬的计算机课程,如C、Java程序开发、Web应用开发、数据库、计算机网络等,讲得比较水,主要靠自学和项目。
  2. 有过一段京东物流的Java后端实习经历,实习时间比较短,全程跟了两个项目。
  3. 同期精投了阿里、百度、字节等大厂,没有海投。重点准备了算法、Java SE和MySQL的知识,网络、Spring、Redis准备偏弱。

面试内容

一面:电话面

  • 自我介绍
  • 面试官口述了一个经典银行扣款场景的Java代码,询问了相关多线程问题:
    • Q1:多线程场景下,会出现什么问题?
    • A1:举例,现有余额50元,A、B两线程分别计划扣款10和20元。可能出现A线程读取50元后,扣款操作未写入,此时B线程操作执行成功后内存中余额变为30元,而A线程又将40元写入回内存,最终获得不了期望的20元结果。总结来讲是线程的原子性无法被保障。
    • Q2:如何解决该问题?
    • A2:对方法用synchronized修饰,从而达到加锁的效果。
    • Q3:了解volatile关键字吗?volatile关键字修饰余额变量可以吗?
    • A3:了解。volatile保证了线程绕过缓存直接读取到关键字所修饰的成员的主存,解决了缓存不一致问题,保障了内存的可见性。在所问场景下,仅用volatile不可以解决该问题,因为volatile仅解决了可见性问题,而该场景下的并发问题主要是操作原子性的问题,不可以用volatile关键字来解决。
    • Q4:说回synchronized关键字,synchrinized关键字获取的是谁的锁?
    • A4:获取的是对应支付类实例对象的锁,具体的锁描述在JVM堆空间的该对象头部。
    • Q5:synchronized关键字还有一种代码块形式,其中圆括号的参数如果是该对象的另一个Object成员,可以吗?
    • A5:可以,这样synchronized获取的是指定成员对象的锁,从代码来分析,这个对象在支付类对象的生命周期内唯一,仍然可以有效解决这个问题。
    • Q6:这是一个悲观锁还是乐观锁?
    • A6:是悲观锁。
    • Q7:有没有乐观锁实现手段?
    • A7:有两种手段:1. CAS 2. 加入版本号,每次写入时比对版本号,如果与期望不同,则自旋。
  • 在上一问中,你对synchronized(this)的描述比较混乱,讲讲this关键字
    • this关键字返回的是对象,是运行时的实例,而非class对象。
  • 询问项目,Java大文件读写部分,简述一下优化过程
    • 一开始用Scanner直接读取,会出现OOM错误,因为Scanner会尝试把整个文件写入内存,而目标文件远大小大于内存大小;紧接着利用Buffer做优化,解决OOM问题;最后用多线程+调整Buffer的大小,从而提高效率至5倍左右。
  • 为什么调整Buffer的大小可以提高效率?
    • 在读操作中,Buffer一旦满,就需要执行一次flip操作,这个操作是耗时的,所以要减少Buffer的刷新次数,则需要Buffer尽可能大,而在多线程环境下,我们还需要考虑到各个线程持有的Buffer总大小不能超过堆空间上限,否则仍然会OOM。
  • 对这个任务来说,线程的数量应该如何选择,是越多越好吗?
    • 不是越多越好。因为该IO任务的瓶颈实则是硬盘读写速度的上限,开过多的线程只会浪费维护过多线程从而产生的成本,并不能实际解决问题。
    • 在该项目中,我选用了2倍CPU逻辑核心的线程数+1。
  • 为什么是2倍+1?
    • 2倍恰好可以跑满线程数,多一个线程用来抢占结束任务或者挂掉放弃时间片的工作线程的资源,从而最高限度利用时间与空间资源。
  • 反问环节
    • 询问面试表现,面试官告知等通知。
    • 询问之后精进Java Web开发的建议,回答多做项目多读源码。
  • 当晚HR给反馈,约下一轮面试的时间。

二面:视频面(记录不全)

  • 自我介绍
  • 介绍一下进程、线程、协程
    • 进程:系统调度资源的最小单元,一个进程包含多个线程,进程的切换开销大。
    • 线程:CPU调度资源的最小单元,同一进程的线程共享资源,切换开销小,拥有独立的栈空间和指令计数器。
    • 协程:用户态的轻量级线程,采用异步机制,上下文切换时保存并且回到先前记录的状态。
  • 是否了解linux,介绍一下top指令
    • linux下的任务管理器,给出性能占用总览,列出各进程的性能占用。
  • top指令的load average(未答出)
    • 按照算法推算出1min 5min 15min活跃的进程数,如果这个数值除以逻辑CPU数大于5则说明系统超负荷。
  • 如何保护一个暴露的HTTP API?
    • 将http升级成https
    • 用token+id的方式生成令牌
    • 请求体签名加密
    • 参数签名加密
  • HTTP响应码404、302、500分别是什么意思?
    • 404 未找到资源
    • 302 页面重定向
    • 500 服务器内部错误,响应体为具体错误内容
  • 了解tcp粘包吗,怎么解决的(未答出)
  • HashTable相较于HashMap和ConcurrentHashMap落后在哪里?
    • HashTable没有更好的哈希冲突解决机制,HashMap和ConcurrentHashMap给出了链表向红黑树的转化策略。
    • HashTable没有做二进制优化,插入位桶用的是模运算,而HashMap和ConcurrentHashMap规范了位桶的size必须为2的整次幂,从而用& (n-1)的位运算来优化。
    • HashTable直接使用hashcode作为hash,HashMap和ConcurrentHashMap使用了hash()混淆方法,利用高位低位异或运算的方式提高了低位的混淆度,维持了高位的混淆度,降低了size小于2^16时的哈希碰撞概率。
    • 在并发问题上,HashTable对几乎所有的public方法加了synchronized关键字,锁的粒度巨大,为HashTable整表,并发效率差。ConcurrentHashMap将锁的粒度细化到table的每个元素,并用CAS操作保证了扩容安全,多线程协作扩容,最大程度提高了并发效率。
  • 谈谈你对Java反射的认识和理解(答得很差,面试官也未进行向深引导,回答非优解,而是面试复现)
    • 反射提供了运行时编译代码的机会。(是错的)
    • 反射的效率差。(业界存疑)
  • 面试官对反射的回答比较无语,时间也快到了,没继续问问题,聊了聊爱看的技术与非技术书籍。
  • 反问环节
    • 没敢问面试表现,询问了今后学习的方向,借着面试官聊看书的事情,问了有没有推荐的方法论层级的书籍。
  • 反馈等了几天,估计是部门确实缺人,给了三面的通知。

三面:视频面,总监面

  • 在我自我介绍前,面试官先做了自我介绍,体验极好。
  • 关注到我非科班,询问了代码学习的原因和历程。
  • 对于电影订票系统,如何保障同一张票不被重复售卖:
    • 对售票方法进行加锁。
    • 利用消息队列的异步性保障只有一个请求是可以购票的,其余给出已售出响应。
  • 有没有数据库层面可以解决问题的手段?
    • 利用事务来保证原子性,提高隔离级别。
  • 讲讲数据库引擎和索引:
    • InnoDB、MyIsam,说明常用InnoDB,主要讲了InnoDB
    • B+树,哈希索引,大致说了数据结构和设计原因
  • 讲一讲Java的线程安全,有什么,如何保证?
    • 原子性,顺序性,可见性
    • Synchronized关键字可以全保。
    • volatile来保证可见性,CAS操作保证原子性和顺序性 。
    • JUC框架下的锁、Barrier、Latch等,他们的底层都是基于AQS实现的,还有线程安全容器,比如ConcurrentHashMap等。
  • 登录系统如何设计,安全性如何保证?(看我JUC有备而来,没有继续往深问。把到嘴边的AQS实现和CAS原理又给憋回去了)
    • 避免请求体明文,利用HTTPS或者其他非对称加密手段。
    • 防SQL注入,在前端和Java内部判断请求内容合法性。
    • 防止缓存击穿,方法同上。
    • 防CRSF/CORS,验证cookie和session。
  • 具体讲讲如何判断请求内容合法性,有没有实现好的类可以解决此类问题?
    • PreparedStatement防SQL注入
    • 拦截器处理非法请求
  • 讲讲关键的HTTP版本变化
    • 1.1:支持长链接,复用TCP信道
    • 2.0:支持二进制格式,个人认为这是Java微服务成为可能的原因之一,序列化与反序列化传递对象,结合京东物流网关项目展开来谈了;请求头压缩;多路复用;
  • 如果是你设计之后的HTTP版本,你会怎么设计,解决哪些问题?知道不知道一些尝试代替HTTP的应用层协议?
    • 答得不好,提到了HTTP的性能瓶颈是维护TCP信道开销产生的,模糊讲了一下改进思路。
    • 面试官主动介绍了QUIC协议
  • 谈一谈你知道的设计模式,应用过哪些?
    • 一口气说了很多,强调了做游戏设计时用过中介者模式、命令模式、单例模式、装饰模式等,强调了京东物流网关项目我负责的部分用了责任链模式。
  • 详细说一说你怎么用的责任链模式
    • 项目中我负责对出参和入参进行处理,设计了相关的引擎(Client),分别用于进行打新地址、插入租户信息、合法性检测、类型转换。
  • 责任链模式能否保证对信息做了全部处理吗?
    • 不能,因为没有明确的接受者,但在我的项目里处理都相对统一。在处理单服务调用多服务的场景时会遇到这个情况,用别的方法解决了。
  • 说一说你的技术偶像,对开源精神的理解。(谈了很多,从中学开始身边的技术大牛就很多,平时也爱刷知乎派上了用场)
  • 隔天约了HR面。

HR面:电话面(记录不全)

  • 具体询问了我们专业都学什么课程
    • 分计算机课程和非计算机课程作答的,强调了商科、产品课程可以作为素质能力应用到工作沟通和需求理解上。
  • 评价一下前东家
    • 正面评价,氛围温暖,mentor带我飞等等。
    • 强调了阿里是一个更高的平台。
  • 阿里高在了哪里
    • 更好的Java程序员摇篮,举了阿里某某大牛的名字,举了阿里的Java开发规范、代码审查工具、fast-json等等。
  • 如果你拿到了譬如字节、腾讯这样的offer,你会怎么选择
    • 选阿里,原因同上,讲的是阿里在Java这方面技术更硬,更值得学习和展现自我价值。
  • 谈谈代码学习过程中对自己的认知变化
    • 谈了邓宁-克鲁格理论认知曲线,绘声绘色讲述了自己从刚开始学到现在,此时处在一个知道该学什么,同时也知道前路漫漫的上升阶段。
  • 谈谈学习方法
    • 阅读源码,项目驱动+随机学习,跟着兴趣走
    • 课堂也带来了一些知识
  • 评价自身的优缺点
  • Base北京or杭州的倾向
  • 对薪酬的态度
    • 前两三年,认为平台的吸引力大于薪酬,比起赚钱更在意自我价值的实现和个人成长。
  • 一周后收到意向书邮件。

反思

  1. 技术表现上,明显二面有点拉垮,复盘结果是准备仓促,过于慌张,没有将问题很好向深度延展。
  2. 存在一定的技术广度问题,Redis和MySQL需要进一步加强,计算机网络由于非科班的原因比较差,需要在下一阶段恶补。
  3. 三面的时候面试官关于前沿技术的提问点醒了我,如果想在行业内提升不能局限于算法和“八股文”,也要关注行业前沿技术。
  4. 自身的优势在沟通和JDK的源码阅读经验上,劣势在于算法和网络,注意持续学习,注意扬长避短。

你可能感兴趣的:(面经,面试,java,后端)