大家好,我是二哥呀。
真的是进入决赛圈了,能开奖的互联网公司都开了,这不,百度今年也挺早,星球里就有球友拿到了一个 SP 的百度 offer。
我这里也整理了一些百度的薪资情况放在了《Java 面试指南》专栏中,供大家做个参考,这样好对比感受一下自己所处的位置,尤其是 26 届的小伙伴,可以提前锁定目标了。
硕士 985,后端开发,开到了 30k,应该是 SSP 了,地域:上海 本硕双非,后端岗,给到了 26k,虽然没有签字费,但鼠鼠知足了,地域:北京 硕士 985,凤巢(百度搜索推广服务管理平台的内部开发代号),给到了 34k,还有 3 万的签字费 硕士 211,总包 51,后端开发岗,做 ai 相关的小程序和 app,真没想到百度也能给这么高了
可能外界对百度的产品褒贬不一,但百度在业界内一直都是顶着“黄埔军校”的称号存在,很多从百度出来的工程师跳槽到其他大厂或者中厂、独角兽,都非常受欢迎。
之前有个球友从百度测开跳到小红书,薪资涨幅非常夸张。
所以如果是应届生,在薪资条件差不多的情况下,我还是比较推荐去百度的,这可能和他们早年养成的培养体系有关。另外,还有一点应该也有关系,就是李彦宏在百度世界大会的一段采访中这样讲过:
事实上,我很多的研发资源还是投在了外界看来基础的能力或者理想主义者看重的东西。
要知道,大多数的公司都是急功近利的,没有产出的部门可能很快就被干掉了。百度能有这种觉悟,确实有超出我的预期。
那接下来,我们就以Java 面试指南中收录的百度同学 4 面试为例来看看百度在面试中更看重求职者哪些技术栈和知识点。冲冲冲。
1、二哥的 Linux 速查备忘手册.pdf 下载 2、三分恶面渣逆袭在线版:https://javabetter.cn/sidebar/sanfene/nixi.html
百度同学 4 面试
联合索引底层存储结构(和其他种类的索引存储结构有什么区别?)
在 MySQL 中,联合索引的底层存储结构是 B+ 树。B+ 树是一种多路搜索树,它的每个节点最多包含 M 个子节点,其中 M 是一个正整数。
除了 B+树索引,还有基于哈希表的索引,查询效率可以达到 O(1)。
Hash 索引在原理上和 Java 中的 HashMap 类似,当发生哈希冲突的时候也是通过拉链法来解决。
当 InnoDB 发现某个索引被频繁访问时,会在内存中创建一个哈希索引,以加速对这个索引的访问。
联合索引的叶子节点存的什么内容?
比如说有这样一个联合索引 idx_c2_c3(c2 和 c3 列,主键是 c1),那么叶子节点存储的是 c2、c3 索引列的值和c1 主键列的值。这样,当查询时,可以先通过联合索引找到对应的主键值,然后再通过主键值找到完整的数据行。
事务会不会自动提交?
在 MySQL 中,默认情况下事务是 自动提交 的。每执行一条 SQL 语句(如 INSERT、UPDATE),都会被当作一个事务自动提交。
如果需要手动控制事务,可以使用 START TRANSACTION 开启事务,并通过 COMMIT 或 ROLLBACK 完成事务。
MySQL默认的隔离级别是什么?
可重复读。
Gc 算法有哪些?
垃圾收集算法主要有三种,分别是标记-清除算法、标记-复制算法和标记-整理算法。
说说标记-清除算法?
标记-清除
算法分为两个阶段:
标记:标记所有需要回收的对象 清除:回收所有被标记的对象
优点是实现简单,缺点是回收过程中会产生内存碎片。
说说标记-复制算法?
标记-复制
算法可以解决标记-清除算法的内存碎片问题,因为它将内存空间划分为两块,每次只使用其中一块。当这一块的内存用完了,就将还存活着的对象复制到另外一块上面,然后清理掉这一块。
缺点是浪费了一半的内存空间。
说说标记-整理算法?
标记-整理
算法是标记-清除复制算法的升级版,它不再划分内存空间,而是将存活的对象向内存的一端移动,然后清理边界以外的内存。
缺点是移动对象的成本比较高。
G1 垃圾回收器了解吗?
G1 在 JDK 1.7 时引入,在 JDK 9 时取代 CMS 成为默认的垃圾收集器。
G1 把 Java 堆划分为多个大小相等的独立区域Region,每个区域都可以扮演新生代(Eden 和 Survivor)或老年代的角色。
同时,G1 还有一个专门为大对象设计的 Region,叫 Humongous 区。
这种区域化管理使得 G1 可以更灵活地进行垃圾收集,只回收部分区域而不是整个新生代或老年代。
什么时候会触发 GC?
如果 Eden 区没有足够的空间时,就会触发 Young GC 来清理新生代。
什么时候会触发 Full GC?
在进行 Young GC 的时候,如果发现 老年代可用的连续内存空间
<新生代历次 Young GC 后升入老年代的对象总和的平均大小
,说明本次 Young GC 后升入老年代的对象大小,可能超过了老年代当前可用的内存空间,就会触发 Full GC。执行 Young GC 后老年代没有足够的内存空间存放转入的对象,会立即触发一次 Full GC。 System.gc()
、jmap -dump
等命令会触发 full gc。
线程安全和线程不安全是什么意思?
多线程安全是指在并发环境下,多个线程访问共享资源时,程序能够正确地执行,而不会出现数据不一致或竞争条件等问题。反之,如果程序出现了数据不一致、死锁、饥饿等问题,就称为线程不安全。
场景:有一个 key 对应的 value 是一个json 结构,json 当中有好几个子任务,这些子任务如果对 key 进行修改的话,会不会存在线程安全的问题?如何解决?如果是多个节点的情况,应该怎么加锁?
会。
在单节点环境中,可以使用 synchronized 关键字或 ReentrantLock 来保证对 key 的修改操作是原子的。
class KeyManager {
private final ReentrantLock lock = new ReentrantLock();
private String key = "{\"tasks\": [\"task1\", \"task2\"]}";
public String readKey() {
lock.lock();
try {
return key;
} finally {
lock.unlock();
}
}
public void updateKey(String newKey) {
lock.lock();
try {
this.key = newKey;
} finally {
lock.unlock();
}
}
}
在多节点环境中,可以使用分布式锁 Redisson 来保证对 key 的修改操作是原子的。
class DistributedKeyManager {
private final RedissonClient redisson;
public DistributedKeyManager() {
Config config = new Config();
config.useSingleServer().setAddress("redis://127.0.0.1:6379");
this.redisson = Redisson.create(config);
}
public void updateKey(String key, String newValue) {
RLock lock = redisson.getLock(key);
lock.lock();
try {
// 模拟读取和更新操作
String currentValue = readFromDatabase(key); // 假设读取 JSON 数据
String updatedValue = modifyJson(currentValue, newValue); // 修改 JSON
writeToDatabase(key, updatedValue); // 写回数据库
} finally {
lock.unlock();
}
}
private String readFromDatabase(String key) {
// 模拟从数据库读取
return "{\"tasks\": [\"task1\", \"task2\"]}";
}
private String modifyJson(String json, String newValue) {
// 使用 JSON 库解析并修改
return json.replace("task1", newValue);
}
private void writeToDatabase(String key, String value) {
// 模拟写回数据库
}
}
Setnx,知道吗? 用这个加锁有什么问题吗?怎么解决?
setnx 从 Redis 版本 2.6.12 开始被弃用,因为可以通过 set 命令的 NX 选项来实现相同的功能。
使用 setnx 创建分布式锁时,虽然设置过期时间可以避免死锁问题,但可能存在这样的问题:线程 A 获取锁后开始任务,如果任务执行时间超过锁的过期时间,锁会提前释放,导致线程 B 也获取了锁并开始执行任务。这会破坏锁的独占性,导致并发访问资源,进而造成数据不一致。
可以引入锁的自动续约机制,在任务执行过程中定期续期,确保锁在任务完成之前不会过期。
比如说 Redisson 的 RedissonLock 就支持自动续期,通过看门狗机制定期续期锁的有效期。
你项目的难点有哪些?
在 PmHub 项目中,印象最深刻的一个难点是集成OpenFeign和Sentinel实现自定义的fallback服务降级。
所谓的服务降级,就是当微服务出现异常的时候,访问者能够从系统中得到一些比较友好的通知,比如:服务繁忙,请稍后再试。
那对于普通的接口来说,可以通过 @SentinelResource 注解来完成,对于需要自定义的接口来说,可以通过实现 UserFeginFallbackFactory 接口来完成。
ending
一个人可以走得很快,但一群人才能走得更远。二哥的编程星球已经有 6600 多名球友加入了,如果你也需要一个良好的学习环境,戳链接 🔗 加入我们吧。这是一个 编程学习指南 + Java 项目实战 + LeetCode 刷题 + 简历精修 的私密圈子,你可以阅读星球专栏、向二哥提问、帮你制定学习计划、和球友一起打卡成长。
两个置顶帖「球友必看」和「知识图谱」里已经沉淀了非常多优质的学习资源,相信能帮助你走的更快、更稳、更远。
欢迎点击左下角阅读原文了解二哥的编程星球,这可能是你学习求职路上最有含金量的一次点击。
最后,把二哥的座右铭送给大家:没有什么使我停留——除了目的,纵然岸旁有玫瑰、有绿荫、有宁静的港湾,我是不系之舟。共勉 💪。