我从小米裸辞后进Shopee了...
最近这段时间,应该是正值很多应届生小伙伴忙碌收尾的阶段了,不少同学估计都在秋季招聘中收获满满了吧。
而Eason当时是校招进入的小米公司,再加上后面又跳槽来了Shopee,所以今天就分享下我对这两家互联网公司的了解和工作感受,希望能帮助大家选择,也可以给还在校园的小伙伴一些坚持的动力吧。
工作感受
工作环境
我当时是在小米华东总部工作,并不是在北京总部,刚开始是在马蜂窝一般的小办公间中工作,虽然老走错工位,但比较安静。
因为当时华东总部还在扩招当中,我去的时候整个总部只有六百多号人;当时还没有现如今所谓的软件体验部等部门,互联网部门的四大金刚依旧坚挺,金凡和雷军还会时不时得来基层视察给员工们加油。
不过在我离职的时候,互联网部门已经被规整到二级部门,并按照功能进行拆分了,华东总部总人数也逐渐多了起来,办公环境和总部的工位基本一致了,网吧式工位,还是比较优雅舒适的。
到了Shopee之后,个人感觉工位没有以前那么宽敞了,可能Shopee人本身比较多,而基本都聚集在一栋深圳总部大楼里,随着人员扩张,甚至有些给食堂用的地方都拿来当做办公区了,可见Shopee工位是有那么紧张的。
福利待遇
薪资
由于小米当年是以应届生身份进去的,来了Shopee已经是社招了,两者薪资上并不能直接进行比较,没有可比性。
因此Eason特意在网上找了下同级别的薪资对照,大厂正式员工的工资反而差不多(某多多除外),一般都会划分为几个档位,根据面试情况和能力定级定薪,开发岗大致范围在 30w - 60w,上不封顶,也是从网上都能查到。
小米
岗位职级
目前小米内部头衔大体分为专员-经理-总监和副总裁及以上,层级共设10级,从13级到22级。
应届生一般12-13级,专员级别为13级左右,3年经验15级,经理为16级到17级左右,高级经理18级,总监为19级到20级左右,副总裁为22级,雷军没有职级。
薪资
薪资方面,就身边同事以及脉脉反馈:19届给的是14~16薪,算法能给到18~20k,软件开发13~16k,产品12~14k。
每年10月底会对转正1年以上(包括试用期,不含实习)的员工进行调薪。从员工的反馈来看,薪资待遇低于其它大厂,特别是5%的涨薪制度,似乎没有很令人满意。
来自某招聘平台的薪资参考
福利:送自家产品或者优惠,入职送1000元手机券,新品发布有时也送。
Shopee
Shopee的总包薪资主要组成是:基础薪资+绩效年终+签字费+股票。
除了基础薪资以外,绩效年终默认3个月,并且优秀的技术类岗位人才有签字费(3w左右),优秀人才还有300-1000不等的股票激励。
来自某招聘平台的薪资参考
薪资: 以新加坡的岗位为例:
新加坡研发岗,总包50w左右。具体是包括6400新币月基础工资*14个月,折人民币约31k;14薪加上3个月左右的绩效年终,31k*3再加300-1000不等的股票和签字费、房补…… 仔细算算,薪资加起来还是差不多有50w左右的。
弹性福利
小米
是以晚餐餐补的形式进行发放,但也不是非常多;零食感觉没有Shopee多(其实好像没吃过几回)
但公司内经常搞各式各样的小活动,参与就有奖励。比如多到爆炸的文化衫,我记得当时有个活动 1 天送 1 件文化衫,我直接拿了 5 件当睡衣......
Shopee的日常福利真的没得说,晚餐免费 + 下午茶 + 不限零食 + 过节时各种别出心裁的小福利早就刷爆了全网,我在平时也没忍住发过几个朋友圈哈哈。
此外,Shopee的员工福利和关怀同样非常的棒,茶水间、健身房、生日礼、关爱讲堂、周年礼等特殊福利,从入职场、日常出行到终身大事,都能保驾护航减少许多压力。
工作氛围
小米小米作为一家发展了 10 年左右的公司,领导层基本都是经验丰富的老手,平均工龄会更大一些,所以新人相对没有那么卷,前几年一般是可以稳定晋升的。不过,近几年公司也非常注重新力量的注入,也在变得更加年轻化,像我之前在的部门这两年就有很多新人的加入,也有不少聊得来的朋友。
Shopee
而Shopee作为一个更年轻的新势力,每年招的新人巨多,年轻的 90 后 Leader 也不少。
整体平均年龄都不会很大,所以在工作中很容易和同事打成一片,认识更多小伙伴。但同样,大家都是新人,都在寻求晋升机会,所以竞争还是很激烈的。
工作节奏
小米
很多人说小米很累,其实我不觉得。小米的管理风格让大家都是一台机器上的齿轮,只要你正常运转,啥事都没有。但你要是停转,那就会有无数人来call你。所以,保持运转就可以了,不用太快的。
很多产品半年才有一个发布版本,先要写各种设计,所以你会写文档,时间不会太少的。但因为高压的文化,抽风的运动,因此小米总是会出现一些要求加班的事情,不过这不会是常态。
Shopee
Shopee的文化轻松,上班可能不会那么轻松,虽然确实有轻松的部门,但你要是在产品一线,轻松这个词和你基本无缘。
Shopee管理不算严格,你想把事情做好你就只有自己干了,只要在规定时间内完成规定版本的需求就行。另外,版本一个月一个?
当然不是!很多大前端产品都是每周构建一个版本的。
大家用脚指头想想也会知道有多累了,产品为了赶各种假期、大促版本,暑期版本……
时间是死的,DEADLINE是12月12日就是12月12日,延期基本上是不能延期的,活动时效就没有了,看老板不劈了你!
不延期,怎么办?加班啊!
到今天,我熬夜到转钟出版本还是常事,而且比我在的这个项目更凶残的部门项目不在少数。
对外据说工作时间是10:00===》19:00,实则是你得把发版本的需求做完才能歇着。
业务
小米
我是 19 年开始在小米工作的,当时的小米以MIUI和智能家居为主打。毕竟是一家年轻的公司,新项目巨多,很多业务处于上升期,但也有很多不稳定、寻求突破的项目,比如电视、平板等。
我当时做的是一些体验项目。比如安全中心和小米笔记等老项目,如今也不知道这些项目最近怎么样了。
在这边工作感觉更安心一些,而且公司内有很多产品方法论和业务的文档,我有时也会看一看,真的很有收获。
Shopee
Shopee的业务相对丰富一些,电商、直播、外卖、社交、物流等等,经历了这几年的沉淀,发展都比较稳定、可预见。
对于新人来说,新业务确实更有挑战、有更多的机会。但同样,风险也很大,说不定搞了 1 年的项目突然就终止了......
所以还是建议大家选择成熟稳定的业务部门,一线业务和其他业务的部门待遇也可能是天差地别。
以上就是我在小米和Shopee的一些工作感受,相信能够为还在纠结进哪家大厂、想了解不同大厂福利待遇的同学提供一点指引,期待与你成为同事,我在Shopee等你哟
??/ 感谢支持 /
以上便是本次分享的全部内容,希望对你有所帮助^_^
喜欢的话别忘了 分享、点赞、收藏 三连哦~
欢迎关注公众号 **程序员巴士**,来自字节、虾皮、招银的三端兄弟,分享编程经验、技术干货与职业规划,助你少走弯路进大厂。
记一次 shopee 面试:最小栈的最优解
前阵子面试的时候,在 shopee 的一面中,问了我一道最小栈的问题,关于最小栈的问题,我以前是做过的,以为是送分题,最结果最优解没写出来,不过也脑补了一些优化,算是答的还行。下面我先大致描述下这道题,然后一步步给出最优解以及我在面试中是解法(面试中给出了几个优化,但想不出最优解)。题目如下:
实现一个这样的栈,这个栈除了可以进行普通的push、pop操作以外,还可以进行getMin的操作,getMin方法被调用后,会返回当前栈的最小值。栈里面存放的都是 int 整数,并且数值的范围是 [-100000, 100000]。要求所有操作的时间复杂度是 O(1)。
附加:如果空间复杂度也能O(1)的话可加分。
解答
对于这道题,如果是要求时间复杂度为 O(1),空间复杂度为 O(n) 或者 时间复杂度为 O(n),空间复杂度为 O(1) 的话,还是相对比较简单一点的,不过我猜想仍然有部分同学不会,所以我下面都稍微讲解一下。不过如果要求时间复杂度和空间复杂度都是 O(1) 的话,就比较难了,反正我当时是没做出来,只给出了一些优化的思路。
时间复杂度 O(n) + 空间复杂度 O(1) 这个我不讲,因为这个很简单,就是获取最小栈的时候,每次都遍历一次栈,把最小栈返回去就可以了,估计也没有人会问你这个方法
一、时间 O(1) + 空间 O(n)
这个要求其实也不难,我们可以用一个辅助栈来存放最小值。例如我们有两个栈 stack 和 helper,stack 是目标栈,helper 是辅助栈,用来存放最小值。每次 getMin 的时候,直接从 helper 栈顶获取即可。下面重点讲一下 push 操作。
每次进行 push 操作的时候,进行如下操作(假设要 push 的元素是 t)
1、对于 stack 栈,我们按照正常情况把元素 push 到栈顶就可以了。
2、然后要把元素 t push 到 helper 栈顶的时候,要先把 t 与 helper 栈顶的元素(假设是 a)进行比较,如果 t <= a,则把元素 t push 到 helper 的栈顶,如果 t > a,这个时候,我们不把 t push 进去,而是重复把 a push 到 helper 的栈顶。
我举个例子吧,例如我们要把数组 arr = {2, 1, 3} 都放入栈中,则存放过程如下:
1、首先 push 2。由于刚开始 stack 和 helper 都是空的,所以直接把 2 放入,此时目标栈和辅助栈的值如下:stack = {2},helper = {2}。
2、接下来 push 1。由于 helper 栈顶元素比 1 大,所以直接把 1 放入 helper 的栈顶,此时:stack = {2, 1},helper = {2, 1}。
3、接下来 push 3,由于 helper 栈顶元素比 3 小,所以重复把 栈顶的元素再次入栈,此时: stack = {2, 1, 3},helper = {2, 1, 1}。
对于 pop 操作,直接把两个栈的栈顶元素删除即可,所以具体代码如下:
public class 设计一个有gitMin的栈 { // 定义两个栈 public static Stack<Integer> stack = new Stack<>(); public static Stack<Integer> helper = new Stack<>(); public static void push(Integer data) { // 目标栈正常入栈 stack.push(data); if (helper.isEmpty()) { helper.push(data); } // 判断栈顶与要 push 元素的大小 else if (helper.peek() <= data) { helper.push(data); } else { helper.push(helper.peek()); } } public static Integer pop() { if (stack.isEmpty()) { return null; } helper.pop(); return stack.pop(); } public static Integer getMin() { return helper.isEmpty() ? null : helper.peek(); }}
二、被怼
不过接着面试官问我,你这个空间复杂度是 O(n),可以优化到空间复杂度为 O(1) 吗?
这时有点小紧张,因为我之前看的书和别人的讲解中,根本没看过时间和空间都是 O(1) 的解法,不过这道题中,有一个条件限制,就是数值的范围是 [-100000, 100000],我知道,这个数值限制,一定是一个突破口,可是硬是没想出来要怎么利用,于是我就按照自己的理解,给出了如下的优化方案:
1、优化1
刚才我们在对 helper 进行 push 操作的时候,如果栈顶的元素较小,那么我们是重复把栈顶的元素重复 push 进去的,显然,这是一个单调栈,并且栈顶的元素只会越来越小,假如栈顶的元素很小的话,那么有可能会出现,helper 的栈中有很多一样的元素,例如 helper = {2, 1, 1, 1, 1, 1, 1, 0, 0, 0 , 0, 0, 0}。
为了解决这个问题,我们可以用一个数值,来表示此处有多少个连续的元素,例如上面的辅助栈中有 1 个 2,6 个 1,6 个 0,那么我们可以这样来表示:helper = {2, 1, 1, 6, 0, 6}。这样的话,辅助栈用到的空间可以小一点。
当然,也有可能用的更多了,例如栈中基本没有连续的元素,例如原本 helper = {3, 2, 1},则会变成 helper = {3, 1, 2, 1, 1, 1}。当然,这是极端的情况。
2、优化2
面试官问我还能有其他方法吗?
显然,我上面的优化中,并没有用到数值范围 [-100000, 100000] 这个条件,所以肯定是不行的,该怎么利用到这个条件呢?
这个时候我是想到了位运算,一个 int 是 32 位,我打算把它分割成两部分,前面 16 位来存放目标值,后面 16 位来存放最小栈。也就是说,我不需要辅助栈 helper 了,只需要一个 stack 就够了,然后用元素的后 16 位来充当 helper 辅助栈的功能。
例如对于最上面的例子 stack = {2, 1, 3}, helper = {2, 1, 1}。那么这里只需要用一个 stack 来存放就可以了。把元素分割成 两部分,前面 16 位存放 stack 里面的值,后面 16 位存放 helper 里面的值,即 stack = {(2,2), {1, 1}, (3, 1)}。然后每次取值的时候,在通过移位的方法来获取值。
想到了这个方法,虽然没有想出最优解,不过我看面试官还是有那么点小满意的,不过我这个方法的数值范围限制是 [-2^15, 2^15 - 1],而题目的限制是 [-100000, 100000],所以会溢出,所以行不通,不过至少提供了一种思路。当然我可以用 long 类型的来存放,不过 Long 所需要的空间是 int 的两倍,所以我觉得也不大行,还是没有达到 O(1)。
然后我自己也想不出啥方法了,后面去网上和群里问被人才找到解法。下面我稍微说下这个方法
三、最优解
这种方法的话,我们的 stack 栈中,不能存放原始数值,而是应该存放 差值,啥差值?就是存放栈顶与最小值的差值。我还是详细一点给大家讲一个案例吧,案例配合代码,应该还是挺好理解的,例如 arr = {2, 1, 3, 0},那么把这些元素入栈时,stack 栈中元素以及最小值的变化如下
上面表格是 push 时,栈中数值的变化,然后再进行 getMin 和 pop 可以通过相应的判断获取,直接看我的代码实现吧,我会进行相应解释,挺好懂,代码如下:
public class 设计一个有gitMin的栈 { private Stack<Integer> stack = new Stack<Integer>(); private int min; public void push(int x) { if (stack.isEmpty()) { min = x; stack.push(0); } else { // 计算差值 int compare = x - min; stack.push(compare); // 如果差值小于0,显然 x 成为最小值,否则最小值不变 min = compare < 0 ? x : min; } } public void pop() { int top = stack.peek(); // 如果top小于0,显然最小值也一并会被删除,此时更新最小值 min = top < 0 ? (min - top) : min; stack.pop(); } public int getMin() { return min; } }
如果没有进行数值范围限制,上面的方法能行吗?答是不行,因为数值没有限制的话,差值的计算可能会溢出。
四、总结
虽然这道题总体不难,不过一道题的解法多种多样,我们千万不能止步于最简单的解法,而应该寻找最优解。后面我也会讲一些面试相关的题,并且每次讲的时候,都会给出详细的解答,从暴力一步步到最优。
大家好,我是帅地,目前也正在更面试,面经,算法 等文章,点击我的头像,你会发现相见恨晚,如果觉得文章不过,也别吝啬你的赞哦,嘻嘻
如果本文对你有帮助,别忘记给我个3连 ,点赞,转发,评论,
咱们下期见!答案获取方式:已赞 已评 已关~
学习更多JAVA知识与技巧,关注与私信博主(666)