得物薪资开了,比去年还猛。

科技   2024-12-08 14:04   河南  

大家好,我是二哥呀。

得物 App 我不经常用,去年想买一双乔丹的那个爆款鞋,我妹就推荐我去得物上看看,说上面啥样的鞋都有。

后来也有一些球友在得物实习,或者拿到得物的 offer,就关注的多了一些。我也统计了一波得物 25 届秋招的薪资信息,放在 Java 面试指南中,方便大家做个参考。

  • 硕士海龟,策略算法岗,给到了 32k,还有 1.2k 的房补
  • 硕士 985,数据分析岗,给了 28k,纠结了好几天,还是拒了
  • 硕士 985,Java 岗,给到了 29k,还有一点签字费
  • 硕士 211,软开岗,开了 28k,也是有房补
  • 硕士 985,Java 岗,给到了 30k,7% 的公积金,还离家近

对比了一下去年的数据,发现得物今年开的薪资更猛了,这说明得物这几年一直发展的不错。但有一点我必须说明一下,据在得物实习和工作过的球友反馈,确实节奏挺快的。

这也能理解,总部在顶级一线城市上海嘛。

截图来自得物 APP

据说,得物目前的用户中,90后的占比超过 90%,在国内总计 2.6 亿 95 后人群中,得物的渗透率达到了 70%。

换句话说,这是一个属于年轻人的平台,活力四射。

那接下来,我们就以 Java 面试指南中收录的得物面经同学 9 面试题目为例,来看看得物到底面试难度如何?

背八股就认准三分恶的面渣逆袭

得物面经同学 9 面试题目

JVM的架构,具体阐述一下各个部分的功能?

JVM 大致可以划分为三个部分:类加载器、运行时数据区和执行引擎。

截图来源于网络

① 类加载器,负责从文件系统、网络或其他来源加载 Class 文件,将 Class 文件中的二进制数据读入到内存当中。

② 运行时数据区,JVM 在执行 Java 程序时,需要在内存中分配空间来处理各种数据,这些内存区域主要包括方法区、堆、栈、程序计数器和本地方法栈。

③ 执行引擎,JVM 的心脏,负责执行字节码。它包括一个虚拟处理器,还包括即时编译器 JIT 和垃圾回收器。

Zset的底层如何实现?

跳表是有序集合 Zset 的底层实现之⼀。在 Redis 7.0 之前,如果有序集合的元素个数小于 128 个,并且每个元素的值小于 64 字节时,Redis 会使用压缩列表作为 Zset 的底层实现,否则会使用跳表;在 Redis 7.0 之后,压缩列表已经废弃,交由 listpack 来替代。

三分恶面渣逆袭:跳表

跳表由 zskiplist 和 zskiplistNode 组成,zskiplist ⽤于保存跳表的基本信息(表头、表尾、⻓度、层高等)。

typedef struct zskiplist {
    struct zskiplistNode *header, *tail;
    unsigned long length;
    int level;
} zskiplist;

zskiplistNode ⽤于表示跳表节点,每个跳表节点的层⾼是不固定的,每个节点都有⼀个指向保存了当前节点的分值和成员对象的指针。

typedef struct zskiplistNode {
    sds ele;
    double score;
    struct zskiplistNode *backward;
    struct zskiplistLevel {
        struct zskiplistNode *forward;
        unsigned int span;
    } level[];
} zskiplistNode;

Mysql隔离机制有哪些?怎么实现的?可串行化是怎么避免的三个事务问题?

事务的隔离级别定了一个事务可能受其他事务影响的程度,MySQL 支持的四种隔离级别分别是:读未提交、读已提交、可重复读和串行化。

三分恶面渣逆袭:事务的四个隔离级别

事务的隔离级别是如何实现的?

读未提交不提供任何锁机制来保护读取的数据,允许读取未提交的数据(即脏读)。

读已提交和可重复读通过 MVCC 机制中的 ReadView 来实现。

  • READ COMMITTED:每次读取数据前都生成一个 ReadView,保证每次读操作都是最新的数据。
  • REPEATABLE READ:只在第一次读操作时生成一个 ReadView,后续读操作都使用这个 ReadView,保证事务内读取的数据是一致的。

串行化级别下,事务在读操作时,必须先加表级共享锁,直到事务结束才释放;事务在写操作时,必须先加表级排他锁,直到事务结束才释放。

什么是串行化?

串行化是最高的隔离级别,通过强制事务串行执行来避免并发问题,可以解决“脏读”、“不可重复读”和“幻读”问题。

Spring源码看过吗?Spring的三级缓存知道吗?

看过一些,主要就是针对 Spring 循环依赖、Bean 声明周期、AOP、事务、IOC 这五部分。

星球嘉宾楼仔:Spring 源码解析

Spring 通过三级缓存机制来解决循环依赖:

  1. 一级缓存:存放完全初始化好的单例 Bean。
  2. 二级缓存:存放正在创建但未完全初始化的 Bean 实例。
  3. 三级缓存:存放 Bean 工厂对象,用于提前暴露 Bean。
三分恶面渣逆袭:三级缓存

抛开Spring,讲讲反射和动态代理?那三种代理模式怎么实现的?

  1. 反射:用于检查和操作类的方法和字段,动态调用方法或访问字段。反射是 Java 提供的内置机制,直接操作类对象。
  2. 动态代理:通过生成代理类来拦截方法调用,通常用于 AOP 实现。动态代理使用反射来调用被代理的方法。

代理方式有两种:JDK 动态代理和 CGLIB 代理。

①、JDK 动态代理是基于接口的代理,只能代理实现了接口的类。

使用 JDK 动态代理时,Spring AOP 会创建一个代理对象,该代理对象实现了目标对象所实现的接口,并在方法调用前后插入横切逻辑。

优点:只需依赖 JDK 自带的 java.lang.reflect.Proxy 类,不需要额外的库;缺点:只能代理接口,不能代理类本身。

②、CGLIB 动态代理是基于继承的代理,可以代理没有实现接口的类。

使用 CGLIB 动态代理时,Spring AOP 会生成目标类的子类,并在方法调用前后插入横切逻辑。

图片来源于网络

优点:可以代理没有实现接口的类,灵活性更高;缺点:需要依赖 CGLIB 库,创建代理对象的开销相对较大。

讲讲线程池?为什么用线程池?

线程池,简单来说,就是一个管理线程的池子。

三分恶面渣逆袭:管理线程的池子

①、频繁地创建和销毁线程会消耗系统资源,线程池能够复用已创建的线程。

②、提高响应速度,当任务到达时,任务可以不需要等待线程创建就立即执行。

③、线程池支持定时执行、周期性执行、单线程执行和并发数控制等功能。

集合里面的arraylist和linkedlist的区别是什么?有何优缺点?

ArrayList 是基于数组实现的,LinkedList 是基于链表实现的。

三分恶面渣逆袭:ArrayList和LinkedList的数据结构

ArrayList 适用于:

  • 随机访问频繁:需要频繁通过索引访问元素的场景。
  • 读取操作远多于写入操作:如存储不经常改变的列表。
  • 末尾添加元素:需要频繁在列表末尾添加元素的场景。

LinkedList 适用于:

  • 频繁插入和删除:在列表中间频繁插入和删除元素的场景。
  • 不需要快速随机访问:顺序访问多于随机访问的场景。
  • 队列和栈:由于其双向链表的特性,LinkedList 可以高效地实现队列(FIFO)和栈(LIFO)。

介绍一下计网里面的tcp和udp协议

TCP 是面向连接的,而 UDP 是无连接的。

三分恶面渣逆袭:TCP 和 UDP 区别

TCP 就像是打电话一对一私聊,UDP 就像是拿个大喇叭在广播(😂)。

三分恶面渣逆袭:TCP 和 UDP 比喻

在数据传输开始之前,TCP 需要先建立连接,数据传输完成后,再断开连接。这个过程通常被称为“三次握手”、“四次挥手”。

UDP 是无连接的,发送数据之前不需要建立连接,发送完毕也不需要断开,数据以数据报形式发送。

换句话说:TCP 是可靠的,它通过确认机制、重发机制等来保证数据的可靠传输。而 UDP 是不可靠的,数据包可能会丢失、重复、乱序。

介绍一下http和https的区别?为什么https安全?

HTTPS 是 HTTP 的增强版,在 HTTP 的基础上加入了 SSL/TLS 协议,确保数据在传输过程中是加密的。

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

HTTP 的默认端⼝号是 80,URL 以http://开头;HTTPS 的默认端⼝号是 443,URL 以https://开头。

HTTPS怎么保证建立的信道是安全的?

主要通过 SSL/TLS 协议的多层次安全机制,首先在握手阶段,客户端和服务器使用得是非对称加密,生成的会话密钥只有服务器的私钥才能解密,而私钥只有服务器持有。

在数据传输阶段,即使攻击者拦截了通信数据,没有会话密钥也无法解密。

Mysql有很大的数据量怎么办?

当单表数据增量过快,比如说单表超过 500 万条数据,就可以考虑分表了。

在技术派实战项目中,我们将文章表和文章详情表做了分表处理,因为文章的详情数据量会比较大,而文章的基本信息数据量会比较小。

垂直拆分可以减轻只查询文章基本数据,不需要附带文章详情时的查询压力。

当然了,当表的数据量过大时,仍然要考虑水平分表,将一个表的数据分散到多个表中,以减轻单表的查询压力。

三分恶面渣逆袭:表拆分

比如说我们将文章表拆分成多个表,如 article_0、article_9999、article_19999 等。

怎么分表分库?

如果表的字段过多,我会按字段的访问频率或功能相关性拆分成多个表,减少单表宽度。

如果单表数据量过大,我会按 ID 或时间将数据分到多张表中。比如订单表可以按 user_id % N 进行水平分表。

如果业务模块较多,我会将不同模块的表分布到不同的数据库中,比如用户相关的表放在一个库,订单相关的表放在另一个库。

可以使用 mycat 或者 Sharding-JDBC 等中间件。

Redis的基本数据类型?

Redis 有五种基本数据类型,这五种数据类型分别是:string(字符串)、hash(哈希)、list(列表)、set(集合)、sorted set(有序集合,也叫 zset)。

三分恶面渣逆袭:Redis基本数据类型

Redis的持久化呢?有何优缺点?

Redis 支持两种主要的持久化方式:RDB 持久化和 AOF持久化。这两种方式可以单独使用,也可以同时使用。

三分恶面渣逆袭:Redis持久化的两种方式

RDB 持久化通过创建数据集的快照来工作,在指定的时间间隔内将 Redis 在某一时刻的数据状态保存到磁盘的一个 RDB 文件中。

AOF 持久化通过记录每个写操作命令并将其追加到 AOF 文件中来工作,恢复时通过重新执行这些命令来重建数据集。

如果需要尽可能减少数据丢失,AOF 是更好的选择。尤其是在频繁写入的环境下,设置 AOF 每秒同步可以最大限度减少数据丢失。

如果性能是首要考虑,RDB 可能更适合。RDB 的快照生成通常对性能影响较小,并且数据恢复速度快。

如果系统需要经常重启,并且希望系统重启后快速恢复,RDB 可能是更好的选择。虽然 AOF 也提供了良好的恢复能力,但重写 AOF 文件可能会比较慢。

在许多生产环境中,同时启用 RDB 和 AOF 被认为是最佳实践:

  • 使用 RDB 进行快照备份。
  • 使用 AOF 保证崩溃后的最大数据完整性。

B+树了解吗?底层呢?为什么这么用?

MySQL 的默认存储引擎是 InnoDB,它采用的是 B+树索引,是 B 树的升级版。

B 树是一种自平衡的多路查找树,和红黑树、二叉平衡树不同,B 树的每个节点可以有 m 个子节点,而红黑树和二叉平衡树都只有 2 个。

换句话说,红黑树、二叉平衡树是细高个,而 B 树是矮胖子。

二哥的 Java 进阶之路:B 树

B 树的一个节点通常包括三个部分:

  • 键值:即表中的主键
  • 指针:存储子节点的信息
  • 数据:表记录中除主键外的数据

不过,正所谓“祸兮福所倚,福兮祸所伏”,正是因为 B 树的每个节点上都存了数据,就导致每个节点能存储的键值和指针变少了,因为每一页的大小是固定的,对吧?

于是 B+树就来了,B+树的非叶子节点只存储键值,不存储数据,而叶子节点存储了所有的数据,并且构成了一个有序链表。

用户1260737:B+树

这样做的好处是,非叶子节点上由于没有存储数据,就可以存储更多的键值对,树就变得更加矮胖了,于是就更有劲了,每次搬的砖也就更多了(😂)。

ending

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

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

如果觉得有帮助,不妨随手点个赞、在看、转发三连吧,如果你想第一时间收到推送,也可以给我加个星标🌟谢谢你看我的文章,我们明天见。

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

沉默王二
技术文通俗易懂,吹水文风趣幽默。学 Java,认准二哥的网站 javabetter.cn
 最新文章