大家好,我是二哥呀。
最近大厂的开奖是接二连三,并且很多球友都表示超出了预期,我在 offershow 上统计了一波 B 站的信息给大家做个参考。
-
硕士 985,后端岗,开到了 32k,大 SSP?准备为爱发电了
-
本科 985,开发岗,给到了 25k,暑期实习转正,另外还有 1k 的房补,我想说的是,暑期转正开出来的真不如秋招进去的,这年头,还是新鲜的越值钱
-
硕士 985,开发岗,开了 30k,有点意外,相对来说很高了,可能是因为 B 站终于盈利了,这次真的大方了
-
从 B 站发布的 2024 年 Q3 财报来看,的确是首次实现了单季度盈利,净利润2.4亿元。并且 B 站还官宣了一项新的股份回购计划,将在 24 个月内累计回收价值不超过 2 亿美元的股票。
就我个人的体感来看,明显能看到 B 站的商单多了,我关注的几个up,几乎所有的视频都加入了商业变现,并且 B 站确实也给流量,这让B 站的创作者有更强的动力去更新高质量的内容。
希望小破站持续努力。😄
从今年秋招的结果来看,腰部以上选手的确是赶上了一个好时候,尤其是拿到大厂 offer 的小伙伴,明显比去年和前年好上了很多。
希望明年春招和暑期实习还有这样的好运气。
那接下来,我们就以
Java 面试指南
中收录的哔哩哔哩同学 1 二面为例来看看B 站今年的面试难度,如果是你遇到这样的题目,该如何作答呢?
背八股就认准三分恶的面渣逆袭
-
-
2、三分恶面渣逆袭在线版:https://javabetter.cn/sidebar/sanfene/nixi.html
哔哩哔哩同学 1 二面
你在系统中解决的难点是什么?
在
PmHub 项目
中,印象最深刻的一个难点是集成OpenFeign和Sentinel实现自定义的fallback服务降级。
所谓的服务降级,就是当微服务出现异常的时候,访问者能够从系统中得到一些比较友好的通知,比如:服务繁忙,请稍后再试。
那对于普通的接口来说,可以通过 @SentinelResource 注解来完成,对于需要自定义的接口来说,可以通过实现 UserFeginFallbackFactory 接口来完成。
你在这个项目中承担的什么角色?你是解决方案的提供者还是一个方案的执行者?
我在 PmHub 这个项目中扮演的是主导者角色,不仅提供解决方案,在遇到疑难杂症的时候,也能去花时间去调查,并且通过编写代码去解决问题。
当然了,我也会安排一些宿友能够完成的任务,帮助他们提高,比如说使用 JWT 无状态来完成登录,前后端的跨域问题解决等。
你用的lombok,你用了什么功能,你介绍一下
我用 Lombok,主要是希望借助 Lombok 的注解,在编译的时候自动为 Javabean 的属性生成 getter / setter,不仅如此,还可以生成构造方法、equals方法、hashCode方法,以及 toString方法,让整体项目的代码更加简洁。
技术派源码截图
springBoot启动机制,启动之后做了哪些步骤;
Spring Boot 的启动由 SpringApplication 类负责:
-
第一步,创建 SpringApplication 实例,负责应用的启动和初始化;
-
第二步,从 application.yml 中加载配置文件和环境变量;
-
第三步,创建上下文环境 ApplicationContext,并加载 Bean,完成依赖注入;
-
-
第五步,发布启动完成事件 ApplicationReadyEvent,并调用 ApplicationRunner 的 run 方法完成启动后的逻辑。
关键的代码逻辑如下:
public ConfigurableApplicationContext run(String... args) {
// 1. 创建启动时的监听器并触发启动事件
SpringApplicationRunListeners listeners = getRunListeners(args);
listeners.starting();
// 2. 准备运行环境
ConfigurableEnvironment environment = prepareEnvironment(listeners);
configureIgnoreBeanInfo(environment);
// 3. 创建上下文
ConfigurableApplicationContext context = createApplicationContext();
try {
// 4. 准备上下文
prepareContext(context, environment, listeners, args);
// 5. 刷新上下文,完成 Bean 初始化和装配
refreshContext(context);
// 6. 调用运行器
afterRefresh(context, args);
// 7. 触发启动完成事件
listeners.started(context);
} catch (Exception ex) {
handleRunFailure(context, ex, listeners);
}
return context;
}
SpringBoot 启动大致流程-图片来源网络
你说一下JVM内存结构?
按照 Java 的虚拟机规范,JVM 的内存区域(JVM 的内存结构/JVM 运行时数据区)可以细分为
程序计数器
、
虚拟机栈
、
本地方法栈
、
堆
、
方法区
等。
三分恶面渣逆袭:Java虚拟机运行时数据区
其中
方法区
和
堆
是线程共享的,
虚拟机栈
、
本地方法栈
和
程序计数器
是线程私有的。
垃圾回收机制是什么?
垃圾回收就是对内存堆中已经死亡的或者长时间没有使用的对象进行清除或回收。
JVM 在做 GC 之前,会先搞清楚什么是垃圾,什么不是垃圾,通常会通过可达性分析算法来判断对象是否存活。
二哥的 Java 进阶之路:可达性分析
在确定了哪些垃圾可以被回收后,垃圾收集器(如 CMS、G1、ZGC)要做的事情就是进行垃圾回收,可以采用标记清除算法、复制算法、标记整理算法、分代收集算法等。
技术派项目使用的 JDK 8,所以默认采用的是 CMS 垃圾收集器。
你是如何使用jmap,你用过哪些命令?
①、我一般会使用
jmap -heap
查看堆内存摘要,包括新生代、老年代、元空间等。
二哥的Java 进阶之路:jmap -heap
②、或者使用
jmap -histo
查看对象分布。
二哥的Java 进阶之路:jmap -histo
③、还有生成堆转储文件:
jmap -dump:format=b,file=
。
二哥的Java 进阶之路:jmap -dump
聊聊你对线程池各个参数的理解?
线程池有 7 个参数,需要重点关注
corePoolSize
、
maximumPoolSize
、
workQueue
、
handler
这四个。
三分恶面渣逆袭:线程池参数
①、corePoolSize
定义了线程池中的核心线程数量。即使这些线程处于空闲状态,它们也不会被回收。这是线程池保持在等待状态下的线程数。
②、maximumPoolSize
是线程池允许的最大线程数量。当工作队列满了之后,线程池会创建新线程来处理任务,直到线程数达到这个最大值。
③、workQueue
用于存放待处理任务的阻塞队列。当所有核心线程都忙时,新任务会被放在这个队列里等待执行。
④、handler
,拒绝策略 RejectedExecutionHandler,定义了当线程池和工作队列都满了之后对新提交的任务的处理策略。常见的拒绝策略包括抛出异常、直接丢弃、丢弃队列中最老的任务、由提交任务的线程来直接执行任务等。
如何知道你设置的线程数多了还是少了?
可以先通过 top 命令观察 CPU 的使用率,如果 CPU 使用率较低,可能是线程数过少;如果 CPU 使用率接近 100%,但吞吐量未提升,可能是线程数过多。
然后再通过 JProfiler、VisualVM 或 Arthas 分析线程运行情况,查看线程的状态、等待时间、运行时间等信息,进一步调整线程池的参数。
通常来说:
-
对于 CPU 密集型任务,线程数接近 CPU 核心数即可。
-
对于 IO 密集型任务,线程数可以简单设置为 CPU 核心数 × 2。
给你一个需求,你需要写一个连接池,你现在可以写一下(我直接懵逼。。。。。。)
数据库连接池的核心功能主要包括: