OPPO 开奖了,被薪资打动了...
创始人
2025-10-18 10:41:54
0

面试刷题网站:

大家好,我是小林。

这几天看到 OPPO 开始开奖了,就跟大家捋捋 26 届校招开发岗的薪资情况,目前知道的就这么几个例子:

  • 应用开发:22k x 15,南京,硕士

  • 后端开发:24k x 15 + 1.2k x 12(房补),硕士,深圳

  • 后端开发:20k x 15 + 1.2k x 12(房补),本科,深圳

  • C++开发:22k x 15,成都,硕士

那个每月 1200 的房补,大概是只有 base 在深圳的才有,二线城市好像没这部分。总包也简单,就是月薪加上 3 个月年终奖,然后签字费啊、期权啊这些,目前看是没有的。

我大概琢磨了下,20-22k 应该就是白菜 offer,24k 算 SP 了。整体看下来,跟去年没太大差别。对了,去年的情况我也给大家贴过,照着去年的数猜,SSP offer 大概能到 26k 左右。

前阵子还有个同学,拿到了 OPPO 的秋招 offer,但手里还有美团这类公司的选择,来问我该咋选。

我当时是这么想的:OPPO 给的薪资也能到 20k+,但关键看你之后想不想在互联网公司发展。要是想的话,那美团可能更对口。OPPO 其实跟小米、华为是一类的公司,薪资比小米高些,但整体看又不如华为,有点夹在中间的意思。要是想找个兜底的,那 OPPO 倒是可以考虑。

今天就给大家看看今年 OPPO 秋招的面经,面的是后端开发岗。

里面的八股题不算多,也就 10 个左右,但后端该考的技术栈重点基本都问到了,像 Java 并发、Redis、MySQL、Linux 命令这些,都没落下。

整体面试的问题都比较基础,没什么刁钻的。要是你感觉这些题自己基本都会,那恭喜你,完全可以投简历去试试面试了。

oppo(后端开发一面)1. java多线程是什么?需要注意什么?

Java 多线程是指在一个 Java 程序中同时运行多个线程,这些线程共享程序的内存空间(如全局变量、方法区等),但有各自的栈和程序计数器,能同时执行不同的任务,比如一个线程处理用户输入,另一个线程后台下载文件,提升程序效率。

使用 Java 多线程需要注意以下几点:

  • 首先是线程安全问题。多个线程同时操作共享数据时,可能出现错误。比如两个线程同时给一个变量加 1,原本该加 2,结果可能只加了 1,这是因为线程切换时没做好数据保护。需要用synchronized关键字、Lock锁等方式,保证同一时间只有一个线程操作共享数据。

  • 其次是线程间通信。线程需要协作时,比如一个线程生产数据,另一个线程消费数据,要通过waitnotify等方法控制,避免出现一方没准备好,另一方就操作的情况,否则可能导致数据错误或线程无限等待。

  • 然后是线程的创建和销毁成本。频繁创建和销毁线程会消耗系统资源,影响性能。可以用线程池管理线程,提前创建好一定数量的线程,重复使用,减少资源消耗。

2. hashmap和concurrenthashmap 区别是什么?

JDK1.7版本:hashmap和concurrenthashmap的区别

  • 内存结构:hashmap采用数组 + 链表的结构。数组是 HashMap的主体,链表则是为了解决哈希冲突而存在。当两个不同的键通过哈希函数计算出相同的数组索引时,它们会以链表的形式存储在该索引位置。ConcurrentHashMap采用分段锁机制,内部结构是一个 Segment数组,每个 Segment类似于一个小的 HashMap,它也有自己的数组和链表结构。

  • 线程安全性:hashmap是非线程安全的,在多线程环境下,如果多个线程同时对 HashMap进行读写操作,可能会导致数据不一致、死循环等问题。ConcurrentHashMap是线程安全的。每个 Segment都有自己的锁,不同的 Segment可以被不同的线程同时访问,因此在多线程环境下可以提高并发性能,只有当多个线程同时访问同一个 Segment时,才会发生锁竞争。

  • 性能:hashmap由于没有锁的开销,在单线程环境下性能较好。但在多线程环境下,为了保证线程安全,需要额外的同步机制,这会降低性能。ConcurrentHashMap通过分段锁机制,在多线程环境下可以实现更高的并发性能,不同的线程可以同时访问不同的 Segment,从而减少了锁竞争的可能性。

JDK1.8版本:hashmap和concurrenthashmap的区别

  • 内存结构:hashmap采用数组 + 链表 + 红黑树的结构,当链表长度超过一定阈值(默认为 8)时,链表会转换为红黑树,以提高查找效率。ConcurrentHashMap弃了分段锁机制,采用 CAS + synchronized来保证线程安全,内部结构同样是数组 + 链表 + 红黑树。

  • 线程安全性:hashmap仍然是非线程安全的,多线程环境下的问题依然存在。ConcurrentHashMap通过 CAS 和 synchronized保证线程安全。在插入元素时,首先会尝试使用 CAS 操作更新节点,如果 CAS 失败,则使用 synchronized锁住当前节点,再进行插入操作。

  • 性能:hashmap在单线程环境下,由于红黑树的引入,当链表较长时查找效率会有所提高。ConcurrentHashMap在多线程环境下,由于摒弃了分段锁,减少了锁的粒度,进一步提高了并发性能。同时,红黑树的引入也提高了查找效率。

3. redis有哪些锁?

第一种:SETNX 锁(基础锁)

SETNX 是 Redis 的一个命令,意思是 只有当键不存在时,才设置键值,这就是它实现锁的核心。比如多个服务要抢 订单锁,就执行SETNX order_lock 1:谁能成功设置这个键,谁就拿到锁;没设置成功的,就说明锁被别人拿了。

但它有个问题:如果拿到锁的服务崩溃了,没来得及删锁,这个键会一直存在,其他服务永远拿不到锁。所以实际用的时候,会给键加个过期时间,比如SET order_lock 1 NX EX 10(NX 就是 SETNX 的意思,EX 表示过期时间 10 秒),避免锁 死在那。

第二种:Redisson 分布式锁(最常用的分布式场景锁)

如果是多个服务器(分布式系统)抢锁,SETNX 锁的 过期时间 不好控制 , 比如服务 A 拿锁后,任务执行了 15 秒,但锁只设了 10 秒过期,锁过期后服务 B 拿到锁,这时 A 任务跑完删锁,会误删 B 的锁。

Redisson 锁就解决了这个问题,底层用了 Redis 哈希结构 + 看门狗机制:拿锁时,会在 Redis 里存一个哈希键,键里包含 锁名 和 当前服务的标识;同时启动一个 看门狗 线程,每隔一段时间(比如锁过期时间的 1/3)就给锁续期,只要服务还在执行任务,锁就不会过期;服务执行完,会根据自己的标识删锁,不会误删别人的。而且它还支持 可重入(同一服务再次拿锁不用等),适合复杂的分布式场景。

第三种:Redlock 红锁(高可用分布式锁)

如果 Redis 是集群(比如主从架构),主节点挂了,从节点还没同步到锁的信息,这时候新的服务可能在从节点上拿到重复的锁 ,Redlock 就是为解决这个问题设计的。

它的逻辑是:让多个独立的 Redis 节点(至少 3 个)一起参与锁的判断,服务要拿锁时,得在超过半数的节点上成功设置锁(比如 3 个节点里成功 2 个,5 个里成功 3 个),才算真正拿到锁;删锁时,要删掉所有节点上的锁。这样就算某个节点挂了,其他节点还能保证锁的唯一性,适合对锁的可靠性要求极高的场景。

4. redis穿透,击穿,雪崩指什么,怎么解决?

  • 缓存雪崩:当大量缓存数据在同一时间过期(失效)或者 Redis 故障宕机时,如果此时有大量的用户请求,都无法在 Redis 中处理,于是全部请求都直接访问数据库,从而导致数据库的压力骤增,严重的会造成数据库宕机,从而形成一系列连锁反应,造成整个系统崩溃,这就是缓存雪崩的问题。

  • 缓存击穿:如果缓存中的某个热点数据过期了,此时大量的请求访问了该热点数据,就无法从缓存中读取,直接访问数据库,数据库很容易就被高并发的请求冲垮,这就是缓存击穿的问题。

  • 缓存穿透:当用户访问的数据,既不在缓存中,也不在数据库中,导致请求在访问缓存时,发现缓存缺失,再去访问数据库时,发现数据库中也没有要访问的数据,没办法构建缓存数据,来服务后续的请求。那么当有大量这样的请求到来时,数据库的压力骤增,这就是缓存穿透的问题。

缓存雪崩解决方案:

  • 均匀设置过期时间:如果要给缓存数据设置过期时间,应该避免将大量的数据设置成同一个过期时间。我们可以在对缓存数据设置过期时间时,给这些数据的过期时间加上一个随机数,这样就保证数据不会在同一时间过期。

  • 互斥锁:当业务线程在处理用户请求时,如果发现访问的数据不在 Redis 里,就加个互斥锁,保证同一时间内只有一个请求来构建缓存(从数据库读取数据,再将数据更新到 Redis 里),当缓存构建完成后,再释放锁。未能获取互斥锁的请求,要么等待锁释放后重新读取缓存,要么就返回空值或者默认值。实现互斥锁的时候,最好设置超时时间,不然第一个请求拿到了锁,然后这个请求发生了某种意外而一直阻塞,一直不释放锁,这时其他请求也一直拿不到锁,整个系统就会出现无响应的现象。

  • 后台更新缓存:业务线程不再负责更新缓存,缓存也不设置有效期,而是让缓存永久有效,并将更新缓存的工作交由后台线程定时更新

缓存击穿解决方案:

  • 互斥锁方案,保证同一时间只有一个业务线程更新缓存,未能获取互斥锁的请求,要么等待锁释放后重新读取缓存,要么就返回空值或者默认值。

  • 不给热点数据设置过期时间,由后台异步更新缓存,或者在热点数据准备要过期前,提前通知后台线程更新缓存以及重新设置过期时间;

缓存穿透解决方案:

  • 非法请求的限制:当有大量恶意请求访问不存在的数据的时候,也会发生缓存穿透,因此在 API 入口处我们要判断求请求参数是否合理,请求参数是否含有非法值、请求字段是否存在,如果判断出是恶意请求就直接返回错误,避免进一步访问缓存和数据库。

  • 缓存空值或者默认值:当我们线上业务发现缓存穿透的现象时,可以针对查询的数据,在缓存中设置一个空值或者默认值,这样后续请求就可以从缓存中读取到空值或者默认值,返回给应用,而不会继续查询数据库。

  • 布隆过滤器:我们可以在写入数据库数据时,使用布隆过滤器做个标记,然后在用户请求到来时,业务线程确认缓存失效后,可以通过查询布隆过滤器快速判断数据是否存在,如果不存在,就不用通过查询数据库来判断数据是否存在。即使发生了缓存穿透,大量请求只会查询 Redis 和布隆过滤器,而不会查询数据库,保证了数据库能正常运行,Redis 自身也是支持布隆过滤器的。

5. mysql的数据结构是什么?

MySQL InnoDB 引擎是用了B+树作为了索引的数据结构。

B+Tree 是一种多叉树,叶子节点才存放数据,非叶子节点只存放索引,而且每个节点里的数据是按主键顺序存放的。每一层父节点的索引值都会出现在下层子节点的索引值中,因此在叶子节点中,包括了所有的索引值信息,并且每一个叶子节点都有两个指针,分别指向下一个叶子节点和上一个叶子节点,形成一个双向链表。

主键索引的 B+Tree 如图所示:

比如,我们执行了下面这条查询语句:

select* fromproduct whereid= 5;

这条语句使用了主键索引查询 id 号为 5 的商品。查询过程是这样的,B+Tree 会自顶向下逐层进行查找:

  • 将 5 与根节点的索引数据 (1,10,20) 比较,5 在 1 和 10 之间,所以根据 B+Tree的搜索逻辑,找到第二层的索引数据 (1,4,7);

  • 在第二层的索引数据 (1,4,7)中进行查找,因为 5 在 4 和 7 之间,所以找到第三层的索引数据(4,5,6);

  • 在叶子节点的索引数据(4,5,6)中进行查找,然后我们找到了索引值为 5 的行数据。

数据库的索引和数据都是存储在硬盘的,我们可以把读取一个节点当作一次磁盘 I/O 操作。那么上面的整个查询过程一共经历了 3 个节点,也就是进行了 3 次 I/O 操作。

B+Tree 存储千万级的数据只需要 3-4 层高度就可以满足,这意味着从千万级的表查询目标数据最多需要 3-4 次磁盘 I/O,所以B+Tree 相比于 B 树和二叉树来说,最大的优势在于查询效率很高,因为即使在数据量很大的情况,查询一个数据的磁盘 I/O 依然维持在 3-4次。

6. b树和b+树的区别是什么?

  • 在B+树中,数据都存储在叶子节点上,而非叶子节点只存储索引信息;而B树的非叶子节点既存储索引信息也存储部分数据。

  • B+树的叶子节点使用链表相连,便于范围查询和顺序访问;B树的叶子节点没有链表连接。

  • B+树的查找性能更稳定,每次查找都需要查找到叶子节点;而B树的查找可能会在非叶子节点找到数据,性能相对不稳定。

7. 有一个进程运行时间很久,怎么排查问题?

首先,确认进程是否真的在 “卡壳” 还是正常执行。用ps -ef | grep 进程名找到进程 ID(PID),再用top -p PIDhtop -p PID观察:如果 CPU 占用率持续接近 0,可能是进程在等待资源(如锁、网络、磁盘 IO);如果 CPU 长期高占用,可能是陷入死循环或复杂计算;如果内存占用持续增长,可能有内存泄漏。

其次,查看进程的执行状态和调用栈。用ps -aux | grep PID看进程状态:若状态是 “D”(不可中断睡眠),说明在等待磁盘 IO,可能是磁盘读写慢或卡盘,可结合iostat看磁盘 IO 是否饱和;若状态是 “R”(运行)但没进展,用pstack PID(或gdb attach PID后执行bt)查看线程调用栈,看是否卡在某个函数(如死锁时会显示线程在等待同一把锁)。

然后,检查进程相关的日志和输出。如果进程有日志文件,用tail -f 日志路径看是否有最新输出,是否卡在某个步骤(如 “正在连接数据库” 却一直没后续);若进程有标准输出 / 错误,可通过ls -l /proc/PID/fd找到输出重定向的文件(如 fd 1 是 stdout),查看内容判断是否有异常信息(如连接超时、权限错误)。

接着,排查外部依赖是否异常。进程若依赖数据库、网络服务等,用netstat -anp | grep PIDss -tulnp | grep PID查看网络连接:若连接状态是 “SYN_SENT”,可能是目标服务没响应;若 “ESTABLISHED” 但没数据传输,可能是对方卡住。同时检查依赖服务是否正常(如数据库是否宕机、接口是否超时)。

最后,若上述方法没线索,可尝试生成进程快照分析。用gcore PID生成核心 dump 文件(需进程允许),再用gdb或对应语言的调试工具(如 Java 用 jstack、jmap)分析:Java 进程可用jstack PID看线程状态,jmap -histo PID看对象占用,排查是否有死锁或内存泄漏;C/C++ 进程用 gdb 分析调用栈和变量值,定位代码层面的问题。

通过这几步,通常能找到进程运行久的原因,看是外部资源等待、代码逻辑问题(死循环、死锁),还是依赖服务异常,再针对性解决。

8. linux系统有哪些常用命令?

Linux 系统的常用命令可以按功能分为几类,涵盖文件操作、进程管理、系统信息查看等常用场景,以下是最基础且高频使用的命令:

  • 文件和目录操作方面,ls用于列出目录内容,加-l可显示详细信息(权限、大小等),-a能看到隐藏文件;cd用来切换目录,比如cd /home进入 home 目录,cd ..返回上一级;pwd显示当前所在目录的完整路径。

  • 创建和删除操作中,mkdir 目录名创建新目录,touch 文件名创建空文件;rm 文件名删除文件,rm -r 目录名删除目录(-r表示递归),rm -f强制删除不提示。

  • 文件内容查看有cat 文件名直接显示全部内容;more 文件名分页显示,按空格翻页;less 文件名功能类似 more,但支持上下键滚动;head -n 5 文件名看前 5 行,tail -n 5 文件名看后 5 行,tail -f 文件名可实时跟踪文件更新(常用于看日志)。

  • 文件复制和移动,cp 源文件 目标路径复制文件,cp -r 源目录 目标路径复制目录;mv 源文件 目标路径移动文件,也可用来重命名(如mv a.txt b.txt)。

  • 进程管理命令,ps查看当前运行的进程,ps -ef显示所有进程详细信息;top动态查看进程占用资源情况(按 q 退出);kill 进程ID终止指定进程,kill -9 进程ID强制终止(-9 是信号编号)。

  • 系统信息查看,df -h显示磁盘空间使用情况(-h以人类易读的单位显示);free -h查看内存使用;uname -a显示系统内核等信息;hostname查看主机名;date显示当前时间。

  • 权限管理方面,chmod修改文件或目录权限,比如chmod 755 文件名设置所有者可读可写可执行,其他用户可读可执行;chown 用户名:组名 文件名更改文件所有者和所属组。

  • 压缩和解压,tar -zcvf 压缩包名.tar.gz 目录名打包并压缩;tar -zxvf 压缩包名.tar.gz解压;zipunzip分别用于 zip 格式的压缩和解压(需安装对应工具)。

  • 网络相关,ping 域名/IP测试网络连通性;ifconfig查看网卡信息(部分系统用ip addr);netstat -tuln查看监听的端口;curl 网址wget 网址用于下载网络资源。

9. 数据库的三大范式是什么?

第一范式(1NF):要求数据库表的每一列都是不可分割的原子数据项。

举例说明:

在上面的表中,家庭信息和学校信息列均不满足原子性的要求,故不满足第一范式,调整如下:

可见,调整后的每一列都是不可再分的,因此满足第一范式(1NF);

第二范式(2NF):在1NF的基础上,非码属性必须完全依赖于候选码(在1NF基础上消除非主属性对主码的部分函数依赖)

第二范式需要确保数据库表中的每一列都和主键相关,而不能只与主键的某一部分相关(主要针对联合主键而言)。

举例说明:

在上图所示的情况中,同一个订单中可能包含不同的产品,因此主键必须是订单号和产品号联合组成,

但可以发现,产品数量、产品折扣、产品价格与订单号和产品号都相关,但是订单金额和订单时间仅与订单号相关,与产品号无关,

这样就不满足第二范式的要求,调整如下,需分成两个表:

第三范式(3NF):在2NF基础上,任何非主属性不依赖于其它非主属性(在2NF基础上消除传递依赖)

第三范式需要确保数据表中的每一列数据都和主键直接相关,而不能间接相关。

举例说明:

上表中,所有属性都完全依赖于学号,所以满足第二范式,但是班主任性别和班主任年龄直接依赖的是班主任姓名,

而不是主键学号,所以需做如下调整:

这样以来,就满足了第三范式的要求。

10. 其他问题

  • 项目用到了什么技术栈?

  • 项目中遇到的最大的困难是什么,怎么解决的?

  • 无手撕

相关内容

热门资讯

特朗普和泽连斯基的会谈气氛很紧... 特朗普在10月17日与泽连斯基来了一场紧张会谈,他告诉后者目前不打算提供“战斧”,根据“值得”新闻援...
中国科协悼念杨振宁:家训“有生... 享誉世界的物理学家杨振宁先生,因病于2025年10月18日在北京逝世,享年103岁。18日,中国科协...
“机器人创造机器人,完全颠覆认... 欧洲采购商Jamie(右)跟随记者走进里工实业 文/羊城晚报记者 孙绮曼 图/羊城晚报记...
苹果突然宣布:10月22日,新... 苹果最新一代智能手机iPhone 17系列开售至今已经一个月有余,结合目前国内各平台的销售情况来看,...
美国联邦政府“停摆”影响扩大,... 新华社北京10月18日电 随着美国联邦政府“停摆”进入第18天,国家核安全管理局、联邦法院系统等部门...
核物理学家马余刚:杨振宁先生逝... “杨振宁先生的逝世,对我们物理学界来说,是损失了精神支撑。”10月18日下午,中国科学院院士、核物理...
专家学者齐聚青岛国际版博会 探... 10月16日至18日,第十届中国国际版权博览会(以下简称“版博会”)在青岛举行。本届版博会的主题为“...
原创 在... 前言 硅谷是技术天才的天堂,也是职场鄙视链最直白的地方,奇怪的是代码写得一般的印度裔程序员,却在这...
男生刺死同班女生,作案前搜索“... 今年4月,广东省深圳市龙华区初三学生潘某某,在自家楼栋门口被同住一小区的同班男同学钟某持刀杀害。钟某...
“气氛紧张”,美媒爆美乌总统会... 【环球网报道 记者 张江平】据美国Axios新闻网当地时间17日报道,消息人士透露,美国总统特朗普当...