6.21 985硕,求职不易,顶住压力。。。
- 作者
- Name
- 青玉白露
- Github
- @white0dew
- Modified on
- Reading time
- 13 分钟
阅读:.. 评论:..
大家好,我是白露。
现在的就业形势严峻到什么地步了?就连985硕的毕业生找了一年才找到工作。。。我分享一位网友的经历,希望他研三一年应聘的感受能够给大家启发和动力。
结束了,研三一年应聘感受,终于走到了尽头。
今天答辩刚过,前几周也拿到offer,签了三方,整个人真的累到不行。以下是我个人,一名985硕士学渣在2023年秋招至2024年春招的经历。
2023年4-5月,我试图投华为的实习岗位,但却没能通过。这成为了我求职的第一道坎。
7月,我将简历投向大疆,揭开了秋招的序幕。但求职的压力骤增,我索性开始海投。
可惜的是,选择上犯了错——技术岗均是投向大厂,而产品经理和游戏策划岗位虽然投了不少,但因缺乏实习经历,大多数连笔试机会都没能获得。
大厂的技术岗位笔试过后也几乎都被挂,某些岗位甚至连笔试机会也没有。
从7月到10月,我是几乎没有任何面试机会的。曾尝试投简历到比亚迪,但最终简历被直接刷掉。
到了11月,投的新凯来虽然迅速走完所有流程,但最终审批被卡,hr也不回复,还给了一个白菜价薪资。此后,我不得不放弃秋招,转而期待春招的机会。
2024年2月,本以为可以大展拳脚的春招开始了,但现实依旧残酷。
由于小论文发表晚,延毕的可能性时刻压在心头。我忙于修改论文,几乎没时间复习算法题和八股文,精神和体力在春招中越发捉襟见肘。
主投技术岗(算法和硬件)例如vivo基带硬件工程师、oppo算法岗位,结果仍是惨淡收场。vivo笔试直接被刷,美团、oppo等算法岗位笔试后杳无音讯,小厂则因算法题不扎实、专业不匹配等原因频频被挂。
眼看即将延毕,选择放弃了一些重要的面试(如农行、移动、浦发银行等),最终在4月收到人生第一份offer:教育机构卓越教育。
随后5月又收到第二份offer:国星光电。
5月30日,终于小论文被录用,答辩通过。
总而言之,压力山大。
对于这位网友的经历,其他网友很多感同身受,因为今年实在是太难了。
- “好吓人,没实习连面试机会都没有吗?”
- “9硕真不至于吧,要是一开始就投java估计好很多,算法还是太卷。”
- “校友实惨😂我现在也还被老板催进度,还好已经有offer了。”
- “这可是985啊,看的我冒冷汗了,哥们。”
- “哥,华工硕今年就业怎么样?寄算机不是年包20,30吗😭,我们双非本能赶上开发岗都算好,大部分人都干不了开发。”
白露也说一下我自己的经历吧,相信老粉丝都清楚。
当年我毕业的时候,拿到offer的部门突然被裁了,整个部门被裁。
我整个人都懵了!
我必须要在毕业前两个月内重新找到一份工作。
那段时间可谓压力山大,但内心始终有一个坚定的信念支撑着我:“我一定能找到工作”。
每天不分昼夜地修改简历、准备面试题、背八股文。
持续一个月,终于在煎熬中如愿以偿地拿到了字节跳动的offer。
在我看来,求职并不是单纯的投递简历,更重要的是要根据自己的特长和背景精准定位。
同时,要时刻准备好,充实自己的专业技能。
未来充满不确定性,但只要脚踏实地,一步一个脚印,我相信终会迎来属于每个人的成功。
美团二面面经
面试官: 同学你好,欢迎参加今天的面试。我们先聊聊索引吧。你能解释一下什么是索引,索引有哪些种类吗?
求职者: 当然可以。索引是数据库中的一种数据结构,能够帮助快速查找数据。它类似于书的目录,通过索引可以快速找到目标数据。索引的种类主要有:
- 主键索引:基于表的主键创建的索引,唯一且非空。
- 唯一索引:与主键索引类似,但允许空值。
- 普通索引:没有唯一性限制。
- 全文索引:用于对文本进行全文搜索。
- 组合索引:基于多个列创建的索引。
我还知道空间索引,这个在地理信息系统(GIS)中比较常用。
面试官: 好的,那你能再详细讲讲空间索引吗?它是如何工作的?
求职者: 嗯,空间索引主要用于处理多维空间数据,比如地理位置。它能加快对这些数据的检索。常见的空间索引有R树、Quad树和Geohash。
- R树:用于索引多维空间数据,适合范围查询。它将数据分层次存储,按照最小边界矩形(MBR)组织节点。
- Quad树:将空间递归地划分为四个象限,适合二维空间数据,例如地图。
- Geohash:将地理位置编码成字符串,适合快速的邻近查询。
面试官: 很好,接下来我们聊聊MVCC吧。你能解释一下MVCC是什么吗?
求职者: 好的。MVCC,即多版本并发控制(Multi-Version Concurrency Control),是数据库管理系统用来提供并发控制的一种方法。
- MVCC通过保存数据的多个版本来实现。每个事务在开始时会获取一个唯一的时间戳。
- 读操作会读取其开始时存在的数据版本,不会被其他事务的写操作阻塞。
- 写操作会创建新的数据版本,并在提交时将其时间戳更新。
这使得读操作和写操作互不干扰,从而提高了并发性能。
面试官: 很好,接下来我们讨论一下MySQL的加锁机制。MySQL是怎么加锁的?
求职者: MySQL的加锁机制主要包括表级锁和行级锁。表级锁包括表锁和元数据锁,而行级锁又分为共享锁(S锁)和排他锁(X锁)。
- 表级锁:锁定整个表,适用于批量操作,但并发性能较低。
- 表锁:显式加锁,锁定整个表。
- 元数据锁:用于保护表的结构,防止DDL操作和DML操作冲突。
- 行级锁:锁定单行数据,适用于高并发操作。
- 共享锁(S锁):允许多个事务读取同一行,但不能进行修改。
- 排他锁(X锁):一个事务独占此行,其他事务不能读或写。
此外,MySQL还支持间隙锁(Gap Lock)和临键锁(Next-Key Lock),用于防止幻读现象。
面试官: 很好,接下来我们继续深入。你刚才解释得很好,特别是关于MVCC和一致性哈希的部分。现在我想了解一下,你在实际项目中有使用过这些技术吗?如果有,你能具体说说是怎么应用的吗?
求职者: 当然可以。在我之前的一个项目中,我们使用了MySQL作为主要的数据库,并使用了MVCC来提高并发性能。
- MVCC使得读操作不会被写操作阻塞,这对于我们高并发的业务场景非常重要。
- 我们还使用了一致性哈希来进行分布式缓存的节点分配,具体来说是用在Redis集群中,以确保当节点增加或减少时,数据迁移的量最小。
通过这些技术,我们显著提高了系统的并发性能和扩展性。
面试官: 听起来很不错。那你能具体讲讲你们是如何实现一致性哈希的吗?
求职者: 好的,我们使用了Ketama一致性哈希算法。具体步骤如下:
- 哈希环:我们将所有的缓存节点映射到一个哈希环上,每个节点有一个哈希值。
- 虚拟节点:为了均匀分布数据,我们为每个实际节点创建多个虚拟节点。
- 数据映射:每个数据项通过哈希函数计算其哈希值,然后顺时针找到最近的节点存储。
- 节点变动:当节点增加或减少时,只需重新分配受影响的少部分数据。
通过这种方式,我们减少了因节点变动导致的数据迁移量。
面试官: 很好。我们再深入一点,聊聊MySQL的锁机制。你能详细说说**间隙锁(Gap Lock)和临键锁(Next-Key Lock)**吗?
求职者: 当然可以。
- 间隙锁(Gap Lock):用于锁定一个范围内的所有不包含记录的间隙,防止其他事务在这个间隙内插入数据。主要用于防止幻读现象。
- 举个例子,如果一个事务在某个范围内进行查询并加了间隙锁,其他事务就不能在这个范围内插入新记录。
- 临键锁(Next-Key Lock):结合了行锁和间隙锁,锁定一个范围内的所有记录和间隙。它是InnoDB默认的锁模式,用于防止幻读。
- 举个例子,如果一个事务在某个范围内进行查询并加了临键锁,其他事务就不能在这个范围内插入、删除或修改记录。
通过这些锁机制,MySQL能有效防止幻读和并发冲突。
面试官: 不错,解释得很清楚。最后一个问题,我们来聊聊Redis的底层数据结构。你能详细说说跳表是如何在Redis中应用的吗?
求职者: 当然可以。跳表是一种用于有序集合的数据结构,能够高效地进行插入、删除和查找操作。具体来说:
- 跳表由多层链表组成,每一层都是一个有序链表。
- 基础层(Level 0)包含所有元素,而每一层的元素都是下一层的子集,通过随机函数决定是否将元素提升到上一级。
- 查找操作:从最高层开始,每次在当前层找到小于目标值的最大元素,然后向下到下一层继续查找,直到找到目标元素。
- 插入操作:新元素首先插入到基础层,然后根据随机函数决定是否提升到上一级。
- 删除操作:首先找到要删除的元素,然后从每一层中删除它。
在Redis中,跳表被用于实现有序集合(Sorted Set,ZSet),能够在**O(log n)**时间复杂度下进行插入、删除和查找操作,非常高效。
面试官: 不错。那你能解释一下一致性哈希吗?
求职者: 当然可以。**一致性哈希(Consistent Hashing)**是一种分布式系统中的负载均衡算法,主要用于解决节点动态变化时数据重分布的问题。
- 一致性哈希将整个哈希值空间组织成一个环,每个节点在环上有一个哈希值。
- 数据通过哈希函数映射到环上的某个位置,并顺时针找到最近的节点存储。
- 当节点增加或减少时,只需重新分配受影响的少部分数据,而不是全部数据。
这样就能极大地减少因节点变化导致的数据移动,提高系统的扩展性和容错性。
面试官: 好的,接下来我们聊聊Redis。你能解释一下Redis中的IO多路复用吗?
求职者: 好的。Redis中的IO多路复用主要是通过select、poll、epoll等系统调用实现的。它允许在单个线程中管理多个网络连接,提高了并发性能。
- select:遍历文件描述符,检查其状态,效率较低。
- poll:与select类似,但在数据结构上有所优化。
- epoll:效率更高,适用于大量文件描述符的场景。它通过事件驱动机制,避免了遍历所有描述符。
Redis使用epoll来实现高效的网络IO操作,从而支持高并发的请求处理。
面试官: 最后一个关于Redis的问题:你了解哪些Redis的底层数据结构?
求职者: 当然,Redis的底层数据结构主要包括:
- SDS(简单动态字符串):用于字符串类型。
- 双向链表:用于列表类型。
- 字典:用于哈希类型。
- 跳表:用于有序集合类型。
- 整数数组:用于压缩列表。
这些数据结构各有其特点,能够高效地支持不同类型的数据操作。
面试官: 接下来我们写几道SQL吧。请写一个查询,查找表employees
中所有薪水大于5000的员工姓名和其对应的部门名称。
求职者:
SELECT e.name, d.department_name FROM employees e JOIN departments d ON e.department_id = d.department_id WHERE e.salary > 5000;
面试官: 很好,再写一个查询,找出表orders
中每个客户的订单总数。
求职者:
SELECT customer_id, COUNT(*) AS order_count FROM orders GROUP BY customer_id;
面试官: 最后一个查询,找出表products
中价格最高的商品名称和价格。
求职者:
SELECT name, price FROM products ORDER BY price DESC LIMIT 1;
面试官: 不错,最后我们来做一道算法题。请解答LeetCode 154题《寻找旋转排序数组中的最小值 II》。
求职者: 好的,我解释我的思路:
- 定义左右指针:我们用
left
和right
两个指针,初始分别指向数组的两端。 - 二分查找:在循环中,计算中间位置
mid
。 - 比较中间值和右边界值:
- 如果
nums[mid]
大于nums[right]
,说明最小值在右半部分,调整left
为mid + 1
。 - 如果
nums[mid]
小于nums[right]
,说明最小值在左半部分,调整right
为mid
。 - 如果
nums[mid]
等于nums[right]
,无法确定最小值在哪一半,将right
左移一位。
- 如果
- 返回最小值:最终
left
指向最小值,返回nums[left]
。
#include <vector> using namespace std; class Solution { public: int findMin(vector<int>& nums) { int left = 0, right = nums.size() - 1; while (left < right) { int mid = left + (right - left) / 2; if (nums[mid] > nums[right]) { left = mid + 1; } else if (nums[mid] < nums[right]) { right = mid; } else { right--; } } return nums[left]; } };
这样我们就能在O(log n)
的时间复杂度内找到旋转排序数组中的最小值。
面试官: 很好,今天的面试就到这里,感谢你的回答。我们会尽快通知你结果。祝你好运!