b站-Java后端or数开-日常实习-一/二面

线下面试,没录音,很多题目记不得了

题目

  1. jvm的内存模型?String s = new String("abc")时发生了什么?
  2. jvm的垃圾回收器及使用场景。
  3. 介绍下依赖注入DI
  4. 介绍下HashMap
  5. instanceof实际是怎么完成判断的?
  6. 为什么选择Kafka?为什么能够支持大流量场景?如何保证数据不丢失?
  7. apollo的使用场景和原理
  8. 爬虫后数据清洗的方法有哪些?
  9. redis的使用场景?介绍下zset使用的数据结构?
  10. binlog日志的格式?介绍下redo log和undo log?
  11. 介绍下回表查询

算法

给了两道比较简单的题

53. 最大子序和

136. 只出现一次的数字

复盘

String s = new String("abc")时发生了什么?

首先是去方法区的字符串常量池中寻找"abc"字符串,如果没有,则创建。

在堆中创建一个String对象,指向字符串常量池中的地址。

栈上指向堆中对象的地址。

所以看该字符串常量池中是否存在“abc”,若存在,则只需要在堆中创建一个对象,否则创建两个。

如果对于String a = "abc"?

则无需在堆上创建对象,栈上直接存储指向字符串常量池的地址。

jvm的垃圾回收器及使用场景

为什么需要垃圾回收器?

  1. 释放内存供其他对象使用
  2. 减轻程序员负担,自动管理内存
  3. 减少内存碎片

垃圾回收器及使用场景

注:图中的实线表示新生代垃圾回收器和老年代垃圾回收器的组合使用情况,其中G1和ZGC都是即可新生又可老年。

新生代

从新生代开始说起,Serial是单线程垃圾回收器,其不支持并发,垃圾回收时会停止所有工作线程,且在对大内存进行处理时,但效率效率较低。

由此引出两个改进方向:

  1. 垃圾回收和工作线程并发执行,减少Stop the World(STW)现象
  2. 使用多线程进行垃圾回收,加快对大内存的垃圾回收速度。

针对方向一,专门针对新生代的垃圾回收器均未做调整,这可能是因为年轻代的回收相对较快?引入并发执行可能带来更多的风险?

针对方向二,则引出了Serial的多线程版本:ParNew。单核上与Serial效果一致,多核上效率更高,默认线程数和cpu数量相等。

垃圾回收时,有一个trade off,即停顿时间和吞吐量。有可能面临的问题是:每次的停顿时间减少了,但是停顿次数更多,导致最后的总吞吐量可能更少。根据不同的场景,可以确定目标是max(减少停顿时间, 增大吞吐量)。一般对于web服务,响应用户请求通常需要减少停顿时间,对于长时间的计算任务,交互较少的任务,那可能需要增大吞吐量。

对于新生代的垃圾回收,如果是专注于吞吐量,可以选择Parallel Scavenge,该垃圾回收器的特点是吞吐量优先,且可控。

对于新生代来说,实际垃圾清除时,都是用标记-复制算法,其特点是高效,不会产生内存碎片,缺点就是费内存,但是新生代一般都比较小,所以这么选择也合理。

老年代

和新生代中Serial对应的老年代垃圾回收器是Serial old,也是单线程,优缺点基本一致。

和新生代Parallel Scavenge对应的老年代垃圾回器是Parallel old,优缺点基本一致。

二者均采用标记-整理算法,特点是无内存碎片,但相对效率不高。

在新生代中提到一个改进方向,就是通过工作线程和垃圾线程并发执行,来降低STW时间。老年代中的CMS即从这个角度解决问题,以获取最短停顿时间。

当然这里的并发不是完全并发,是在并发标记和并发清理阶段并发,而在处理标记和重新标记时进行STW,不过这两个阶段很快,最终STW时间很短。

优点上就是低停顿时间,缺点:

  1. 对cpu资源敏感,cpu不足4个时,对用户影响大
  2. 无法处理浮动垃圾,出现Concurrent Mode failure时,会导致full gc,这时候会采用Serial old来进行垃圾收集,Serial old可是一个单线程的垃圾回收器,这次会产生长时间的STW。
  3. 每次垃圾回收阶段,用户线程还在运行,并产生垃圾,所以需要预留空间,不能像其他垃圾回收器那样等老年代满了再回收,这个比较可以通过-XX:CMSInitiatingOccupancyFraction修改。
  4. 使用标记-清除算法,有内存碎片。

老少通吃

G1回收器基于分区的思想,每个小区可以属于新老代。

G1有计划的避免在全区域进行垃圾收集,其根据每个区中垃圾堆积的价值(回收后的空间大小 vs 回收所需要的时间),维护优先队列,来确定收集目标。

每个区维护区域内引用类型与其他区域数据的引用关系,使用Remembered Set,目的是在做GC Roots Tracing时避免扫描全堆。(之前的垃圾回收器在新老之间也要记录)

不同的代所占据的区块数也是动态调整。

整体上使用标记-整理,对于每个小块来说,回收时将其复制到另一小块,是标记-复制。高效且避免了内存碎片。

好处就是STW时间可控(通过参数设置停顿时间不超过N毫秒),由于分区策略,对大内存应用也好使。

至于其如何去解决G1的每个问题,这里就没看了。

ZGC暂时没看。

Kafka高吞吐量的原因

Kafka在普通机械硬盘下也可以达到每秒几百万的处理量。

从以下四个方面考虑其高性能的原因:

  • 磁盘顺序读写:虽然在随机读写下,机械硬盘 < 固态硬盘 << 内存,但是顺序读写时,访问速度差距小了很多。
  • 页缓存:数据首先写入到文件系统的页缓存中,依赖操作系统进行flush时异步刷盘(可以调整producer.type来修改,sync or async),降低磁盘I/O次数。
  • 零拷贝:考虑消费者从kafka消费数据,Kafka将数据发送到网络上的过程
  • 不使用零拷贝的情况,4次传输,CPU参与
  • 使用零拷贝,2次传输,全程DMA控制,缩短时间65%。
  • 批量处理:发送端进行批量压缩和发送,降低网络IO带来的影响。消费者要一条,实际发送了n条,同时通过offset来控制消费进度。

Binlog的日志格式

binlog不同于redo log,undo log,其实在Server层实现的日志。用于备份恢复和主从复制。

如果数据库数据全部被删了,需要通过binlog恢复,redo log因为是循环写,所以数据不全。

Binlog的日志格式分为三种

  • STATEMENT(默认):记录逻辑操作,sql语句。在有uuid,now等动态函数式,可能导致数据不一致。
  • ROW:记录数据最终被修改的样子,但是针对一条update语句,可能会记录n条修改记录,导致binlog过大。
  • MIXED:根据不同情况自动使用STATEMENT和ROW模式。

相比较而言,redo log记录的是物理日志,即在实际的物理地址上进行了什么更新。

instanceof实际是怎么完成判断的?

对 A instanceof B来说,

if A为null: 
  return True
if A == B:
  return True

switch A:
	case 接口类型:
		遍历A实现的接口,若有与B一致的,return True
	case 类类型:
		遍历A的super链直到Object,若有与B一致的,return True
	case 数组类型:
		看B,B如果是类,只能是Object
		B如果是接口,必须是数组实现的接口之一。
		B如果是TC类型的数组,则与A的SC类型的数组,相比,二选一:
			TC和SC是相同的基本类型
			TC和SC都是引用类型,但是可以在运行时强制转换。

参考资料

https://blog.csdn.net/weixin_54232686/article/details/126862579

https://blog.csdn.net/weixin_63020134/article/details/131357852

https://blog.csdn.net/Mr_YanMingXin/article/details/121451254

https://zhuanlan.zhihu.com/p/658756647

https://juejin.cn/post/7103335306103324685

全部评论
在哪投的呀
点赞 回复
分享
发布于 02-29 18:48 四川
过了吗
点赞 回复
分享
发布于 03-03 14:08 湖南
联易融
校招火热招聘中
官网直投
m
点赞 回复
分享
发布于 03-04 10:17 贵州

相关推荐

&nbsp;适合小白或者其他领域转Flink或者轻度使用者查看,大佬轻轻喷基础篇1.&nbsp;什么是Apache&nbsp;Flink?​Apache&nbsp;Flink是一个开源的流处理和批处理框架,可以实现快速、可靠、可扩展的大数据处理。​2.&nbsp;Flink与Hadoop的区别是什么?​Flink是一个全面的流处理和批处理框架,提供了低延迟和高吞吐量的实时数据处理能力,而Hadoop更侧重于离线批处理。​3.&nbsp;Flink中的事件时间(Event&nbsp;Time)和处理时间(Processing&nbsp;Time)有什么区别?​事件时间是数据实际生成的时间,而处理时间是数据到达Flink系统的时间。事件时间可以通过时间戳标记数据,而处理时间是Flink根据数据到达的顺序生成的。​4.&nbsp;Flink的容错机制是如何实现的?​Flink使用检查点(Checkpoint)机制实现容错。它会定期保存应用程序的状态,并在发生故障时恢复到最近的一个检查点状态。​5.&nbsp;什么是Flink的窗口(Window)?窗口是Flink中用于对无限数据流进行有界处理的机制。它将无限流切分为有限的、不重叠的块,并对每个窗口进行计算。6.&nbsp;Flink支持哪些类型的窗口?​Flink支持滚动窗口(Tumbling&nbsp;Window)、滑动窗口(Sliding&nbsp;Window)和会话窗口(Session&nbsp;Window)。7.&nbsp;Flink中的状态后端(State&nbsp;Backend)是什么?​状态后端是Flink用于保存和管理应用程序状态的机制。它可以存储状态到内存、文件系统或分布式存储系统(如HDFS)中。8.&nbsp;Flink的水印(Watermark)是什么?​水印是用于表示事件时间进度的标记。它通常与数据流中的时间戳一起使用,用于处理乱序事件和延迟数据。9.&nbsp;Flink的时间窗口触发器(Trigger)是什么?​时间窗口触发器用于控制何时触发计算窗口的输出。它可以基于元素数量、处理时间、水印等条件进行触发。​...&nbsp;完整版见:原文链接:https://blog.csdn.net/qq_30757161/article/details/137459710#数据开发##金三银四,你有感觉到吗##大数据#
点赞 评论 收藏
转发
lz后端开发菜鸡,本来准备5月完全准备好再开始投日常实习,天天刷牛客焦虑的不行,于是从3月中旬开始投递。第一周刚开始投,某中厂嫌我oq,说“你们学校鸽的人太多了”,面试都没有给,让lz一度以为现在形势很好(现在来看简直好笑,估计是没hc的托辞罢了)。于是,lz狠狠的投了几个大厂,结果很多直到现在还是待筛选,太难了。直到周三,xhs某部门给了面试。一面是电话面,问了十几分钟八股,全答上了,约的第二天上午二面,但是没约具体时间,面试官说后面他来安排,等邮件就是了。当天晚上,b站简历通过,邮件约的周四下午一面。周四上午,lz早早醒来,从9点等到10点半,感觉不对劲,xhs一直没邮件约面试具体时间,于是给面试官发短信,得到的回复是“我ld觉得你之前没有其他大厂实习经历,其他方面都很不错,抱歉目前面试还没安排”。我:。。。这个时候才感受到形势不对劲,下午还有b站一面,于是调整了一下心态,继续准备面试。b站一面感觉还行,没怎么问八股,全程问项目,手撕全排列秒了。最后反问环节得知目前只有1个hc,现在有十几个人在排序,心又凉了半截。当天晚上,xhs另一个部门又约面了,约的周五下午,于是继续准备面试。周五下午,xhs一面,全程八股,答出来9成,但是最后没给手撕,感觉不对劲,果然,面完一个小时就收到感谢信,心态崩了,遂开始海投。第二周海投结果一般,感觉现在日常实习hc也太少了,小厂不想去面,大厂都没给机会,一度准备摆烂了。直到周四,b站终于告知lz通过一面,下午约二面,感觉是前面有大哥鸽了,5个工作日才给二面。b站二面基本上都是开放性问题,感觉稳了,但又不敢半场开香槟,于是接着海投接着复习。周五,b站给了hr面,面完就给了oc,激动不已,泪目,半个月终于拿到了满意的offer。ps:下周入职,第一次实习需要注意什么捏
点赞 评论 收藏
转发
7 58 评论
分享
牛客网
牛客企业服务