今天腾讯内网在热火朝天地集体算账

沉默王二

共 8079字,需浏览 17分钟

 ·

2024-07-12 14:04

大家好,我是二哥呀。

在星球嘉宾 Jack 那里看到一条消息说,鹅厂内网正在热火朝天的集体算账:一是把年终奖的一部分提前摊入到 base 中,二是把房补也平均纳入到 base 当中。

截图来自星球嘉宾 Jack-Cui

这个薪酬调整说实话对于 base 低的小伙伴来说很有利,因为 base 高了意味着五险一金缴纳的更多了,每个月到手的也更多了,真正的落袋为安。

话说这公积金如果离职的话,也是可以提取的,相当于一笔不小的存款。当然了,腾讯的工作体感在所有的大厂里算是很友好的了,估计进了就不想走,除非(🤣)。

但对于 base 已经非常高的小伙伴来说,每个月的个人所得税交的就更多了,但我想既然挣的多,多纳点税也算是合情合理(反正我每个月也交不少)。

至于腾讯为什么做出这个调整,我想肯定是奔着为员工谋福利去的。说实话,这年头,肯为员工谋福利的好公司不多了,腾讯这波值得被点赞。星球里之前也有好几个球友拿到了腾讯的实习 offer,希望都稳稳转个正。

那今天我们就以《Java 面试指南》中收录的《腾讯面经同学 26 微信支付暑期实习》 面试为例,来看看腾讯的面试官都喜欢问哪些问题,好做到知彼知己百战不殆。

让天下所有的面渣都能逆袭 😁

这次面试的整体难度感觉不大,三道算法题也是 LeetCode 上 100 题中笔刷的题目,八股的话也都是非常常见的,属于送分八股(🤣)。

腾讯微信支付面经

说一说项目的亮点。

PmHub 是一套基于 SpringCloud Alibaba & LLM 的智能项目管理系统,目前拆分了用户、流程、项目管理、认证等 4 个微服务,这个项目的亮点很多,比如说:

  • Gateway 实现自定义网关统一鉴权统计接口调用时间
  • 使用 Redis+Lua 基于令牌桶实现限流
  • 使用 RocketMQ 实现审批消息异步解耦
  • 集成 OpenFeign+Sentinel 实现服务降级和网关流量控制
  • 集成 Redis 分布式锁保障流程状态更新
  • 通过分布式事务 Seata 保证任务审批状态一致性
  • 自定义注解+AOP 实现服务接口鉴权和内部认证
  • 整合 TTL 缓存用户数据
  • 如何用 Docker 容器化部署项目
  • 使用 Skywalking 监控项目性能
  • 采用 Cache Aside 模式保证缓存和数据库一致性
pmhub-教程

JVM垃圾删除

垃圾回收(Garbage Collection,GC),顾名思义就是释放垃圾占用的空间,防止内存爆掉。有效的使用可以使用的内存,对内存堆中已经死亡的或者长时间没有使用的对象进行清除和回收。

JVM 在做垃圾回收之前,需要先搞清楚什么是垃圾,什么不是垃圾,那么就需要一种垃圾判断算法,通常有引用计数算法、可达性分析算法。

二哥的 Java 进阶之路:可达性分析

在确定了哪些垃圾可以被回收后,垃圾收集器要做的事情就是进行垃圾回收,如何高效地进行垃圾回收呢?

可以采用标记清除算法、复制算法、标记整理算法、分代收集算法等。

JVM 提供了多种垃圾回收器,包括 CMS GC、G1 GC、ZGC 等,不同的垃圾回收器采用的垃圾收集算法也不同,因此适用于不同的场景和需求。

CMS 是第一个关注 GC 停顿时间(STW 的时间)的垃圾收集器,JDK 1.5 时引入,JDK9 被标记弃用,JDK14 被移除。

G1(Garbage-First Garbage Collector)在 JDK 1.7 时引入,在 JDK 9 时取代 CMS 成为了默认的垃圾收集器。

有梦想的肥宅:G1 收集器

ZGC 是 JDK11 推出的一款低延迟垃圾收集器,适用于大内存低延迟服务的内存管理和回收,在 128G 的大堆下,最大停顿时间才 1.68 ms,性能远胜于 G1 和 CMS。

https的加密技术

使用 HTTPS 主要是为了解决 HTTP 传输过程中的一些安全问题,因为 HTTP 是明文传输,所以 HTTPS 在 HTTP 的基础上加入了 SSL/TLS 协议。

二哥的 Java 进阶之路:http和 https 的区别

SSL(安全套接字)/TLS(传输层安全)协议可以用来加密通信内容,保证通信过程中的数据不被窃取和篡改。整个加密过程主要涉及两种类型的加密方法:

  • 非对称加密:服务器向客户端发送公钥,然后客户端用公钥加密自己的随机密钥,也就是会话密钥,发送给服务器,服务器用私钥解密,得到会话密钥。
  • 然后双方用会话密钥加密通信内容。

客户端会通过数字证书来验证服务器的身份,数字证书由 CA(证书权威机构)签发,包含了服务器的公钥、证书的颁发机构、证书的有效期等信息。

三分恶面渣逆袭:HTTPS 主要流程

说一说常用的并发容器

我自己常用的并发容器主要有 ConcurrentHashMap、CopyOnWriteArrayList、LinkedBlockingQueue。

在 JDK 8 及以上版本中,ConcurrentHashMap 的实现进行了优化,不再使用分段锁,而是使用了一种更加精细化的锁——桶锁,以及 CAS 无锁算法。每个桶(Node 数组的每个元素)都可以独立地加锁,从而实现更高级别的并发访问。

初念初恋:JDK 8 ConcurrentHashMap

同时,对于读操作,通常不需要加锁,可以直接读取,因为 ConcurrentHashMap 内部使用了 volatile 变量来保证内存可见性。

对于写操作,ConcurrentHashMap 使用 CAS 操作来实现无锁的更新,这是一种乐观锁的实现,因为它假设没有冲突发生,在实际更新数据时才检查是否有其他线程在尝试修改数据,如果有,采用悲观的锁策略,如 synchronized 代码块来保证数据的一致性。

CopyOnWriteArrayList 是一个线程安全的 ArrayList,它遵循写时复制(Copy-On-Write)的原则,即在写操作时,会先复制一个新的数组,然后在新的数组上进行写操作,写完之后再将原数组引用指向新数组。

CL0610:最终一致性

这样,读操作总是在一个不变的数组版本上进行的,就不需要同步了。

ArrayBlockingQueue 是一个基于数组的有界阻塞队列,采用 ReentrantLock 锁来实现线程的互斥,而 ReentrantLock 底层采用的是 AQS 实现的队列同步,线程的阻塞调用 LockSupport.park 实现,唤醒调用 LockSupport.unpark 实现。

算法题

LRU

这道题先不按照 leetcode 的解法来写,直接告诉大家我们可以使用 LinkedHashMap 来实现 LRU 缓存,LRU 是 Least Recently Used 的缩写,即最近最少使用,是一种常用的页面置换算法,选择最近最久未使用的页面予以淘汰。

public class MyLinkedHashMap<KVextends LinkedHashMap<KV{

    private static final int MAX_ENTRIES = 5// 表示 MyLinkedHashMap 中最多存储的键值对数量

    public MyLinkedHashMap(int initialCapacity, float loadFactor, boolean accessOrder) {
        super(initialCapacity, loadFactor, accessOrder);
    }

    protected boolean removeEldestEntry(Map.Entry eldest) {
        return size() > MAX_ENTRIES;
    }

}

MyLinkedHashMap 是一个自定义类,它继承了 LinkedHashMap,并且重写了 removeEldestEntry() 方法——使 Map 最多可容纳 5 个元素,超出后就淘汰。

我们来测试一下。

MyLinkedHashMap<String,String> map = new MyLinkedHashMap<>(16,0.75f,true);
map.put("沉""沉默王二");
map.put("默""沉默王二");
map.put("王""沉默王二");
map.put("二""沉默王二");
map.put("一枚有趣的程序员""一枚有趣的程序员");

System.out.println(map);

map.put("一枚有颜值的程序员""一枚有颜值的程序员");
System.out.println(map);

map.put("一枚有才华的程序员","一枚有才华的程序员");
System.out.println(map);

输出结果如下所示:

{沉=沉默王二, 默=沉默王二, 王=沉默王二, 二=沉默王二, 一枚有趣的程序员=一枚有趣的程序员}
{默=沉默王二, 王=沉默王二, 二=沉默王二, 一枚有趣的程序员=一枚有趣的程序员, 一枚有颜值的程序员=一枚有颜值的程序员}
{王=沉默王二, 二=沉默王二, 一枚有趣的程序员=一枚有趣的程序员, 一枚有颜值的程序员=一枚有颜值的程序员, 一枚有才华的程序员=一枚有才华的程序员}

沉=沉默王二默=沉默王二 依次被淘汰出局。

接雨水

这道题我在《二哥的 LeetCode 刷题笔记》中给出详细的题解,这里就先贴个图作证。

删除链表中倒数第n个节点。

这是 LeetCode 的第 19 题,我这里直接给出题解,也是直接能 beat 100% 的:

class Solution {
    public ListNode removeNthFromEnd(ListNode head, int n) {
        // 创建一个虚拟头节点,简化边界条件处理
        ListNode dummy = new ListNode(0);
        dummy.next = head;
        
        // 第一次遍历,计算链表的总长度
        int length = 0;
        ListNode current = head;
        while (current != null) {
            length++;
            current = current.next;
        }
        
        // 设置长度为到达要删除的节点的前一个节点
        int index = length - n;
        current = dummy;
        // 第二次遍历,找到要删除的节点的前一个节点
        for (int i = 0; i < index; i++) {
            current = current.next;
        }
        
        // 删除节点,即跳过要删除的节点
        current.next = current.next.next;
        
        return dummy.next;
    }
}

内容来源

  • 星球嘉宾三分恶的面渣逆袭:https://javabetter.cn/sidebar/sanfene/nixi.html
  • 二哥的 Java 进阶之路(GitHub 已有 12000+star):https://javabetter.cn

ending

一个人可以走得很快,但一群人才能走得更远。二哥的编程星球已经有 5700 多名球友加入了,如果你也需要一个良好的学习环境,戳链接 🔗 加入我们吧。这是一个编程学习指南 + Java 项目实战 + LeetCode 刷题的私密圈子,你可以阅读星球专栏、向二哥提问、帮你制定学习计划、和球友一起打卡成长。

两个置顶帖「球友必看」和「知识图谱」里已经沉淀了非常多优质的学习资源,相信能帮助你走的更快、更稳、更远

欢迎点击左下角阅读原文了解二哥的编程星球,这可能是你学习求职路上最有含金量的一次点击。

最后,把二哥的座右铭送给大家:没有什么使我停留——除了目的,纵然岸旁有玫瑰、有绿荫、有宁静的港湾,我是不系之舟。共勉 💪。

浏览 4522
5点赞
评论
收藏
分享

手机扫一扫分享

分享
举报
评论
图片
表情
推荐
5点赞
评论
收藏
分享

手机扫一扫分享

分享
举报