5.9 快手营收千亿,薪资60W。。能去吗
- 作者
- Name
- 青玉白露
- Github
- @white0dew
- Modified on
- Reading time
- 10 分钟
阅读:.. 评论:..
大家好,我是白露啊。
最近快手发布了 2023 年度财报,里面有几点关键信息,我觉得大家应该很感兴趣。
信息参考自 HR实名俱乐部 人均薪酬60W,酸了···1、快手2023年全年总收入达1134.7亿元,同比增长20.5%。 要知道,这个全年收入证明快手是一线互联网公司了,要知道,百度2023年的营收是1346亿元人民币。
这说明在抖音占据短视频赛道大头的同时,快手仍然在稳步上升。
说人话就是,如果你是打工人,现在快手财务看起来还不错,有机会可以去试试。
2、2023年员工人数增加1000人(放在互联网寒冬的背景下,能正增长已经很不错了)。结合全年营收,“人均”年薪可达 400+万,仅次于腾讯和字节跳动。 (大家可以评论区留言,看看离这个数据还差多少,哈哈)
3、快手电商全年GMV首次突破万亿规模,达到1.18万亿元 和抖音一样,快手也开始布局电商,而且收入不菲,如果要去,快去电商部门。
除了上面公司层面有关的信息,与之相对的,我还查到快手人均薪酬(不带股权的那种),然后我结合24年校招 offer 调研情况,结果让我大为震惊,直接看下图。
看看校招 Offer的情况呢?
快手 yyds!
大伙如果要去快手的话,一定要选择这样的部门。
比如直播和电商,这会是未来几年快手的核心的核心,因为它们能赚钱!
下面我们就来看一场快手直播团队的面试吧,这场面试很难,非战斗人员请直接拉到文末。
开始面试
面试官: 你好,欢迎来到快手直播团队面试。请先做一下自我介绍**。
求职者: 您好!我是一名计算机科学专业的毕业生,对编程和软件开发充满热情。 我对算法和数据结构有深入的了解,并且在我的学习和项目经历中积累了Java开发和系统设计的实际经验。我对提升用户体验和优化系统性能充满兴趣,并且乐于接受新的挑战。 (省略500字,这里请结合你的学习背景和项目背景讲述,提前背熟)
面试官: 很好,谢谢你的介绍。接下来,我们来看道算法题。首先是将字符串转化为整数,考虑一下可能出现的溢出问题,并给出你的解决方案。(其实leetcode 8. 字符串转换整数 (atoi))
求职者: 嗯……这个问题可以通过遍历字符串并构建整数来解决。 关键点是要检查是否溢出。在Java中,我们可以在添加新的数字前检查当前结果是否大于Integer.MAX_VALUE / 10
,或者在添加数字后检查结果是否小于Integer.MIN_VALUE
。我会写一个循环来实现这个逻辑,并跳过非数字字符。
class Solution { public: int strToInt(string str) { if (str.empty()) return 0; int index = 0, n = str.size(), sign = 1, res = 0; // 处理前置空格 while (index < n && str[index] == ' ') { ++index; } // 处理符号 if (index < n && (str[index] == '+' || str[index] == '-')) { sign = str[index++] == '+' ? 1 : -1; } // 处理数字 while (index < n && isdigit(str[index])) { int digit = str[index] - '0'; // 判断是否溢出 if (res > (INT_MAX - digit) / 10) { return sign == 1 ? INT_MAX : INT_MIN; } res = res * 10 + digit; ++index; } return res * sign; } };
面试官: 现在,让我们讨论一下synchronize。你能告诉我它可以使用的几种形式吗?请给出代码示例。
求职者: 在Java中,synchronized
关键字可以用来提供方法或代码块的同步。这意味着只有一个线程可以执行synchronized修饰的方法或代码块。synchronized
可以用在实例方法、静态方法以及代码块中。例如:
// Synchronized instance method public synchronized void syncMethod() { // critical section } // Synchronized static method public static synchronized void syncStaticMethod() { // critical section } // Synchronized block on object public void syncBlock() { synchronized(this) { // critical section } } // Synchronized block on class public void syncClassBlock() { synchronized(MyClass.class) { // critical section } }
面试官: 很好,下面我们来谈谈哈希表的冲突解决方法。
求职者: 哈西冲突主要有四种方法,开放定址法、链地址法、再哈希法、建立公共溢出区。
- 开放定址法通过在哈希表内寻找空闲位置解决冲突。如果哈希函数返回的位置已被占用,就尝试表中的下一个位置,直到找到空位。
- 链地址法在哈希表的每个槽位上存放一个链表。发生冲突时,新元素会被添加到对应槽位的链表中。
- 再哈希法使用多个哈希函数。如果第一个哈希函数导致冲突,就尝试第二个,依此类推。
- 建立公共溢出区是在哈希表之外单独建立一个溢出区来存储导致冲突的所有元素。
链地址法和再哈希法之间的关联和区别主要在于处理冲突的方式。链地址法通过外部结构来存储冲突的元素,而再哈希法则尝试在哈希表内找到新的位置。链地址法适合冲突较多的情况,因为它可以无限扩展;再哈希法适用于冲突较少,且对空间使用较为敏感的场景。
底层数据结构方面,链地址法使用链表来存储冲突的元素,而再哈希法仍然是使用数组,只是尝试不同的哈希函数来定位元素。
面试官: 很好的解释。接下来谈谈链表和数组的底层结构设计、关联、区别和应用场景。
求职者: 数组是一种线性数据结构,它在内存中占据连续的空间,可以通过索引快速访问元素。但数组的大小在初始化时固定,不便于动态扩展。
链表也是线性结构,但它的元素在内存中不必连续存储,每个元素节点包含数据和指向下一个节点的指针。链表易于扩展和插入删除,但访问特定元素的速度较慢。
数组适用于大小固定,频繁访问元素的场景。而链表适用于元素数量动态变化,频繁插入和删除的场景。
面试官: 谈谈你熟悉的排序算法,以及堆排序和选择排序的使用场景有什么不同?
求职者: 我熟悉的排序算法包括冒泡排序、快速排序、堆排序、桶排序、选择排序和插入排序。其中,堆排序使用二叉堆数据结构,适合大数据量的情况,因为它的时间复杂度较低(O(n log n))。选择排序简单但效率较低(O(n^2)),适合小数据量的情况。
堆排序利用了二叉堆的性质来优化比较和交换的次数,而选择排序则是简单地遍历数组来找到最小(或最大)元素。在资源利用率和设计思路上,堆排序更适合处理大数据集,因为它能够更好地利用数据结构的性质来减少不必要的操作。
面试官: 接下来,我们来谈谈你所了解的查找算法。常用的查找结构都有哪些?
求职者: 在数据结构中,常用的查找算法包括:
- 二分查找法:在有序数组中使用,每次比较中间元素,将查找范围缩小一半,时间复杂度为O(log n)。
- 插值查找法:类似于二分查找,但是中间元素的选择基于要查找的关键字值在整个查找范围中的位置,适用于分布均匀的有序数据。
- 哈希查找:通过哈希函数将关键字映射到表中一个位置来直接访问,平均时间复杂度近似为O(1)。
- 分块查找:将数据分为若干块,块内无序块间有序,先查找块再查找块内数据。
- 树表查找:如二叉搜索树、平衡二叉树(AVL)、红黑树等,通过树结构进行查找,平衡树的查找时间复杂度为O(log n)。
面试官: 那么,你能解释一下B树、B+树和红黑树的设计思路、结构区别以及使用区别吗?
求职者: 当然。
- B树是一种平衡多路查找树,它的设计思路是减少磁盘I/O操作。在B树中,内部节点可以有多个子节点,这降低了树的高度,优化了大数据量的查找效率。
- B+树是B树的变种,其设计思路是将所有的数据都保存在叶子节点中,并且叶子节点之间通过指针连接,适合范围查询。
- 红黑树是一种自平衡二叉搜索树,它的设计思路是通过旋转和变色来保持树的平衡,保证最坏情况下操作的时间复杂度为O(log n)。
B树和B+树主要用在数据库索引中,而红黑树常用在需要快速插入删除的场景,如Java的TreeMap和TreeSet。
面试官: 队列和栈有什么区别?它们的使用场景分别是什么?
求职者: 栈是一种后进先出(LIFO)的数据结构,而队列是一种先进先出(FIFO)的数据结构。栈适用于需要反转元素、实现调用栈等场景,比如括号匹配、页面的前进后退。队列适用于需要按顺序处理任务的场景,比如打印任务队列、线程池的任务管理。
面试官: 谈谈你对JVM内存模型的理解。
求职者: JVM内存模型定义了Java虚拟机在运行Java程序时如何使用内存。它包括几个主要区域:堆(所有线程共享,用于存储对象实例)、方法区(存储类信息、常量、静态变量等)、程序计数器(当前线程执行的字节码的行号)、Java栈(存储局部变量、操作数栈、方法调用)、本地方法栈(支持native方法执行)。
面试官: 那么,垃圾回收器CMS和G1的设计思路、关联和区别以及垃圾回收阶段的不同是什么?
求职者: CMS(Concurrent Mark Sweep)的设计思路是尽可能减少应用程序停顿时间,它主要有两个阶段:标记和清除,这两个阶段大部分工作都是并发进行的。而G1(Garbage-First)的设计思路是更平衡地处理吞吐量和停顿时间,它将堆内存分割成多个区域,并根据每个区域的垃圾回收价值来优先回收。G1的回收阶段包括初始标记、并发标记、最终标记、筛选回收等。
面试官: 如果让你在系统中选择一个回收器,你有什么想法?
求职者: 在选择垃圾回收器时,我会考虑应用程序的需求。如果应用程序对停顿时间非常敏感,比如用户界面或实时系统,我可能倾向于选择CMS。如果应用程序需要更大的堆和更平衡的回收性能,我可能会选择G1。我还会考虑JVM的版本和具体的性能指标来做出决定。
面试官: 很好,答得很不错,等待后续通知吧。