Feb 15
== 结构化面试 ==

在字节跳动,我学到了如何使用结构化面试法来考查应聘者的技能。

所谓结构化,指的是将各种知识技能做好划分,例如编程语言,操作系统,数据库,网络,算法,工程/架构设计,并通过几个面试官之间的多轮交叉面试来考查掌握程度。

这样的面试方法,可以避免某个面试官考察太偏,并充分挖掘候选人的亮点。

== 技能 ==

在具体的面试中,每一个方向都会由浅入深去考查。

以编程语言为例,比如某个应聘者常用语言是Python,我会先考查一些语言的基础特性,例如什么是magic function,__repr__ 和 __str__ 的区别等。

确认候选人对语言的使用掌握符合预期后,再考查候选人对python底层实现的理解,例如展开聊聊python的gc相关知识。

更进一步,可以结合一些具体的应用场景来考查候选人对语言的综合应用能力,例如使用Python的多线程,需要考虑什么,如何提高某些任务中的效率等。

通过这样的综合考察,我避开了所有学过下面这本书的程序员。

点击在新窗口中浏览此图片


== 算法 ==

值得一提的是算法/数据结构,这是字节跳动面试的一大特点,也是网上各面经都会提(tu)到(cao)的。

点击在新窗口中浏览此图片

通常来说每一轮面试都会要求候选人完成一道算法题,现场面试就直接在纸上写,远程面试则是在在线共享编辑的IDE环境里完成。

可能早期常有面试官让候选人手写红黑树,以至于"手写红黑树"已经成为一个内部梗。

点击在新窗口中浏览此图片

实际上难度没有太夸张,通常来说15分钟内完成 Leetcode Medium 级别的题目,就能满足面试要求了(划重点)。

我更倾向于考查操作基础数据结构的题目,关注点放在对代码的掌控力,而不是某个具体的算法。

不过,对于有ACM经历的同学,面试官可能会尝试用 Hard 级别题目来challenge。比如我内推的某同学被问了 manacher's algorithm,可能是和面试官八字不合。

但也不用太担心,毕竟不是谁都像他一样拿了ACM金牌。

点击在新窗口中浏览此图片

== 沟通 ==

候选人的沟通能力也是考查的重点。

例如,在面试中的工程设计题通常是开放式问题,题面往往不是精确的,问题的规模,可能存在的问题,或者可以忽略的一些细节,都可以在前期的沟通中确认,然后再开始设计。

点击在新窗口中浏览此图片

还有,在面试过程中的知识盲点,要注意避免不懂装懂的强行作答,但利用已有知识做出的合理推测则是加分项。两种行为的边界可能有点模糊,这就考验候选人的沟通技巧了。

== 总结 ==

我想要招什么样的候选人?概括而言就是:聪明,勤奋,有潜力。

更具体的,大佬早就讲过了,推荐阅读字节跳动创始人张一鸣的演讲《我面了两千个年轻人,发现混得好的都有这5种特质》:https://www.toutiao.com/i6681549238490366472

== 硬广 ==

最后,我目前在字节跳动的网盟广告业务线(穿山甲),由于业务持续高速发展,长期缺人、不限HC,欢迎踊跃投递:

后端开发(上海):https://job.toutiao.com/s/sBAvKe

后端开发(北京):https://job.toutiao.com/s/sBMyxk

广告策略研发(上海):https://job.toutiao.com/s/sBDMAK

测试开发(上海):https://job.toutiao.com/s/sBUKuh

其他地区、职能线:https://job.toutiao.com/s/sB9Jqk
Jul 4

英语流利说 TED 课程 不指定

felix021 @ 2019-7-4 00:04 [随想] 评论(0) , 引用(0) , 阅读(535) | Via 本站原创
Apr 24
工作这几年,面试了很多人,也结合了自己工作的经验,有一些心得,但是没有深入地思考过。

正好看到两位大佬的总结,很有共鸣,做个梳理,作为一面镜子,照照自己。



~ 张一鸣:我面了两千个年轻人,发现混的好的都有这5种特质

  @ https://www.toutiao.com/i6681549238490366472

点击在新窗口中浏览此图片


~ 谢熊猫君:如何辨认身边的聪明人?

  @ https://mp.weixin.qq.com/s/jvqMxdHRRBhhWl29fj3RHg

点击在新窗口中浏览此图片
Mar 12
这篇文章用于展示微软有多蠢。

除了环境光感应调整屏幕亮度之外,Surface Pro 还有一个傻逼特性,叫做 Adaptive Contrast(有些地方翻译为自适应亮度)。

这是 Intel 显卡驱动中实现的一个功能,在屏幕显示的内容亮度较低的时候(例如打开一个暗色调的图片),自动降低屏幕的亮度用于省电。

结果就是体验烂到爆炸。微软自作聪明起来,简直比苹果还蠢。

而且找不到关闭选项:Surface Pro 6 上的 Intel 驱动程序没有独立的控制面板,官网下载的驱动程序无法直接安装 —— 得先删除显卡,然而还是没有显卡控制面板。

微软技术支持服务上有人提出这个问题,官方人员的回答Windows自带的帮助功能一个尿性:都是套路,且毫无卵用。

网上可以搜到很多无效解决方案:

1. 设置 - 系统 - 显示 - “当光线变化时自动调节亮度”

误:不是这个功能。

2. 控制面板 - 系统和安全 - 电源选项 - 更改计划设置 - 更改高级电源设置 - 显示 - 启用自适应亮度 - 关闭

误:无效

3. 注册表编辑器 - 找到下述注册表键值 - 从 9240 修改为 9250

[HKEY_LOCAL_MACHINE\SYSTEM\ControlSet001\Control\Class\{4d36e968-e325-11ce-bfc1-08002be10318}\0001] FeatureTestControl

误:早期版本的 Surface Pro 上有 0001 这个项,但 Surface Pro 6 没有(只有 0000 ,而且 value 是 8200 而不是 9240 )。新建一个 0001 ,设置 FeatureTestControl = 9250 无效。

最后终于找到这里:https://mikebattistablog.wordpress.com/2016/05/27/disable-intel-dpst-on-sp4/

应该修改 0000 项里的 FeatureTestControl  ,这是一个 bitfield,其中从低到高的第 5 个 bit 表示是否启用  Intel Display Power Saving Technology (DPST)。将这个 bit 修改为 1 ,就可以禁用 DPST。

最终,将 0000 下的 FeatureTestControl  从 8200 改为 8210 ,并重启以后解决问题。
Aug 3

方法论 不指定

felix021 @ 2018-8-3 03:49 [随想] 评论(2) , 引用(0) , 阅读(1602) | Via 本站原创
1. 意志力

    有些人似乎天生就有很强的意志力,可以长时间连续做某件事情而不知疲倦,例如学霸可以长时间做题,计算机大神可以长时间编写代码(看看那些 Hackathon 比赛)。但我认为这里有一些事实被掩盖了——你回顾一下,是不是也有一些自己可以长时间做而不会疲倦的事情,例如王者荣耀、吃鸡,又或者刷各种美剧?你也许会觉得,这不一样啊,玩游戏和刷剧是这种有意思的事情,并不需要意志力的支撑。问题就在这里——可能很多人无法理解的是,学霸们和计算机大神们可以从做题、写码中获得快乐,所以才会觉得是强大的意志力在支撑着他们。

    在能得到快乐的事情上,持续的投入不需要强大意志力的支撑。反过来说,在不是特别感兴趣甚至令人反感的事情上,意志力就非常重要。不巧的是,意志力是一种有限的资源,合理、有效地利用这个资源,我认为是取得成绩的一个关键因素。

    那该怎么办呢?鸡汤地说,就是想办法让自己喜欢上要做的事情,如果做不到,至少也应该减少排斥感。当然,给汤不给勺是耍流氓,所以请继续往下看。

2. 反馈(奖励)

    很多人都对嗑瓜子这种带有魔性的娱乐活动深有体会,拿着一袋瓜子,不嗑完根本停不下来。如果不巧你不喜欢嗑瓜子,可以想想那些让你觉得非常爽的游戏,无论具体的游戏形式如何呈现,都会有一个共性,就是总会给你立即的回馈。游戏总会给完成挑战的玩家一些奖励,激励他们继续玩下去。好玩的游戏尤其在意回馈的呈现形式,比如施放一个技能产生的光影声音特效、对手被攻击掉血的数值化呈现,杀死一个对手后增加经验值、掉下来的装备,完成一个剧情任务以后的礼包奖励等等,都希望够给玩家创造充分的满足感,引导玩家继续完成下一个目标。

    人类本质上还是一种动物,大脑中对反馈的本能反应,相当于给游戏的设计者开了一个后门,用于操纵玩家的行为。利用好这个特点,即使在本来并不十分感兴趣的领域,也能够显著改善对意志力的消耗。举例而言,我总是会边写边运行我的代码,一方面可以确认写好的代码没有错误(避免把一大堆问题积攒到最后),另一方面运行结果本身是一个有效的反馈(每次运行结果都更完整、更接近目标),激励我继续改进;而且在学习数据结构时(例如一个二叉树),我总会写一个 dump 方法,用来把内存中抽象的数据可视化。

3. 目标

    游戏设计的“心流(flow)”理论给出的几个关键因素中,我认为反馈是最重要的,其次是目标。好的游戏总会设定合理的目标,引导玩家一步一步入坑。太简单的目标会让人觉得无聊,太难的目标则很容易让人因畏难而放弃。就像下棋/打球,和新手、或水平远高于自己的选手对战,都不是一件愉快的事情,而让人既觉得愉快又能提高自己水平的,正是与水平相当(或者略高)的人对战,获胜的可能性(不确定性)和对获胜的追求,会带来双方激烈的对抗,而这些对抗能给参与者淋漓酣畅的快意(反馈),从而形成有效的正反馈循环。

    同样地,在学习过程中,给自己设定合理的目标能够有效降低对意志力的消耗。如何设置合理的目标,可能没有通用的方法,但幸运的是,可以在实践中调整,找到最适合自己的阈值。

4. 启动成本

    俗话说万事开头难,如果能想办法减少开头的困难,那万事就不那么难了。所谓的困难,换种说法就是成本高。这里的成本是广义的,不仅仅包含金钱成本,也包含时间成本,以及其他为了达成目标所要付出的代价。而这里的目标还只是开始做某件事情,如果启动成本过高,在开始之前就会消耗大量意志力,那么结果便可想而知。

    一个典型的例子是健身。我曾经的一份工作,公司隔壁是一个专业大型健身房,提供浴巾、拖鞋等各种洗浴用品,公司发放免费的年卡,于是我每周都会有2~3次午休或下班时间“说走就走”地去健身,甚至还请了教练来辅导我,过程虽然有些辛苦,但回想起来确实很享受那段时光。换工作以后,我也曾经办过一次季度健身卡,但是启动成本陡增:我需要自掏腰包来办理健身卡,而且这家健身房离我有十几分钟脚程、不提供浴巾和拖鞋等,每次去健身房之前心里都一番挣扎,结果是,虽然我坚持了一周2次的频率,但季度卡到期后就没再续费。我做了另一个决定:在家里腾出一小块地方,买了一架椭圆机,只要有15分钟空隙就可以完成一次轻松的健身。如果我愿意,还可以开启刷剧模式,很愉快地在椭圆机上磨蹭大半个小时。

    降低启动成本,其本质就是想办法制定一个较容易达成的初始目标(启动)。硅谷创业家 Eric Rise 所著《精益创业》(Lean Startup)的核心思想“最小化可行产品”(Minimum Viable Product, MVP),我认为也是最小化启动成本的一个应用,通过最小代价开发出一个可用的产品(达成目标:启动),推向市场,验证其可行性(反馈),根据市场反馈持续不断地迭代改进(阶段性目标),形成正反馈循环。

通过降低启动成本,设置适合自己的目标,建立能够带来奖赏的反馈机制,形成正反馈的循环,从而最大化地利用好意志力资源,这就是我的方法论。

如果不够的话,还有一个开挂的技巧——研究表明,吃糖可以在一定程度上补充意志力。也对,要是在健身减肥的过程中可以吃甜品,应该就没那么难坚持下来了吧?
May 26

centos 安装 daemontools 不指定

felix021 @ 2017-5-26 00:10 [随想] 评论(0) , 引用(0) , 阅读(5950) | Via 本站原创
09年在B公司实习的时候从运维同学偷师知道了daemontools这个package,有个supervise命令特别好用(很符合B公司当时宣传的“简单可依赖”),以前用ubuntu/debian,apt-get直接就装上了。现在线上用的是centos,需要自己编译安装,稍微麻烦点。具体的过程在官网 http://cr.yp.to/daemontools/install.html 说得还是比较详细了,不过编译的时候可能会报错
引用
./load envdir unix.a byte.a
/usr/bin/ld: errno: TLS definition in /lib64/libc.so.6 section .tbss mismatches non-TLS reference in envdir.o
/lib64/libc.so.6: could not read symbols: Bad value
collect2: error: ld returned 1 exit status

搜了一下,解决方案也很简单:
引用
The fix is quite simple: explicitly add #include <errno.h> to the offending file and then recompile.

按照说明,在 src/error.h 里面添加了这句再编译就通过了。
Jan 11

解决ssh延迟 不指定

felix021 @ 2016-1-11 17:29 [随想] 评论(0) , 引用(0) , 阅读(6756) | Via 本站原创
不知道为什么这么多年都没遇到啥问题,到了钱厂以后接连遇到3种不同的ssh延迟,觉得有必要记一下了:

1. GSSAPIAuthentication

ssh -vv someserver 可以看到如下类似字样的:
引用
debug1: Next authentication method: gssapi-with-mic
debug1: Unspecified GSS failure.  Minor code may provide more information
Credentials cache file '/tmp/krb5cc_1000' not found


在 ~/.ssh/config(也可以是 /etc/ssh/ssh_config)加上
引用
Host *
  GSSAPIAuthentication no
  GSSAPIKeyExchange no


2. AddressFamily

ssh -vv 在这里卡住的:
引用
debug2: ssh_connect: needpriv 0

加上
引用
Host *
  AddressFamily inet


3. UseDNS

在server端卡住的(忘了log是啥了),在server的 /etc/ssh/sshd_config 加上
引用
UseDNS no



ssh的坑真多,感觉应该抽空整理一个全集,包括之前记录过的 ServerAliveCountMax/ClientAliveCountMax,还有诸如GatewayPorts之类的。

参考:
Fixing SSH login long delay
debug2: ssh_connect: needpriv 0 stuck - Fix.

Dec 4

PHP的除法 不指定

felix021 @ 2015-12-4 20:49 [随想] 评论(2) , 引用(0) , 阅读(7180) | Via 本站原创
今天要实现一个简单的功能:按需给出长度为n的空格串。

如果是用Python,我就直接用这一句来解决了,既简单又直观:
' ' * n

可惜PHP就是不好使,只好写一个函数。最简单的办法当然是一个循环,但是看起来太蠢了,效率也低(虽然可以用一个数组缓存来解决),看起来也不帅。所以试着写了一个递归的版本(其实也应该要用数组来缓存提高效率,但是以下代码省略了相关逻辑,看起来清晰一点):
function spaces($n)
{
    if ($n == 1)
        return ' ';
    return spaces($n / 2) . spaces($n - $n / 2);
}

看起来酷多了对不对?

不对……因为一调用就递归到死啊魂淡。什么破玩意,连这种代码也不能一次跑对,简直让我对自己的能力产生了怀疑。

好吧,那就调试一下。
function spaces($n)
{
    if ($n == 1)
        return ' ';
    printf("%d = %d + %d", $n, $n / 2, $n - $n / 2);
    fgetc(STDIN);
    return spaces($n / 2) . spaces($n - $n / 2);
}


printf竟然输出了"3 = 1 + 1",这尼玛我都要开始怀疑人生了,什么鬼!

经过各种折腾,最后不知为什么放弃治疗,用了大概这样的代码(说真的,我在运行之前都觉得这是徒劳):
function spaces($n)
{
    if ($n == 1)
        return ' ';
    var_dump($n / 2); var_dump($n - $n / 2);
    fgetc(STDIN);
    return spaces($n / 2) . spaces($n - $n / 2);
}


输出:
引用
float(1.5)
float(1.5)


卧槽……

卧槽……

卧槽……

重说三。

当时已经接近崩溃了,于是到Google去试图寻找一点安慰,“php int division get float”返回给我的第一条,竟然是一个StackoverFlow的问题:How do I get a float value when dividing two integers? (PHP),提问者表示他用 12 / 13 得到的结果是 1 。SF的大神们纷纷出招,甚至还有人回答:
引用
Just use $value = (float)($x/$y);

我看着左边的-1,深藏功与名。

然后继续解决问题。我想知道为什么我这儿两个整数一除就变成了浮点数,然而试了几个不同的环境,都是一样的,看起来倒了这血霉的似乎不是我一个。

查来查去也没查出什么来,于是我鼓起勇气、抛弃羞耻心,找到了一个我觉得我这辈子都不会需要打开的页面:

PHP:算术运算符 - http://php.net/manual/zh/language.operators.arithmetic.php

这个页面标题里的第一句话是“还记得学校里学到的基本数学知识吗?就和它们一样。”。

接下来是一个表格,列出了负号、加、减、乘、除、取余的说明。

表格后面还跟了一句话:

除法运算符总是返回浮点数。

除法运算符总是返回浮点数。

除法运算符总是返回浮点数。

尼玛……这说的学校居然TMD是小学啊……我了个大槽……谁家小学还教 “% 取余” 符号的!!谁家小学教的除法返回浮点数还带余数的!!

然而我还是不太相信,我用了八九年的PHP,我竟然不知道它没有整数除法?

翻,翻源码。

在 php5-src/Zend/zend_vm_def.h 可以看到 除法操作符(ZEND_DIV )的Handler,调用的是 fast_div_function ,这个函数里面有一段被注释掉的老的实现,目前实际调用的是 div_function ,实际上都是一样的,截取后者的一部分:
ZEND_API int div_function(zval *result, zval *op1, zval *op2 TSRMLS_DC) /* {{{ */
{
    zval op1_copy, op2_copy;
    int converted = 0;

    while (1) {
        switch (TYPE_PAIR(Z_TYPE_P(op1), Z_TYPE_P(op2))) {
            case TYPE_PAIR(IS_LONG, IS_LONG):
                if (Z_LVAL_P(op2) == 0) {
                    zend_error(E_WARNING, "Division by zero");
                    ZVAL_BOOL(result, 0);
                    return FAILURE;        /* division by zero */
                } else if (Z_LVAL_P(op2) == -1 && Z_LVAL_P(op1) == LONG_MIN) {
                    /* Prevent overflow error/crash */
                    ZVAL_DOUBLE(result, (double) LONG_MIN / -1);
                    return SUCCESS;
                }
                if (Z_LVAL_P(op1) % Z_LVAL_P(op2) == 0) { /* integer */
                    ZVAL_LONG(result, Z_LVAL_P(op1) / Z_LVAL_P(op2));
                } else {
                    ZVAL_DOUBLE(result, ((double) Z_LVAL_P(op1)) / Z_LVAL_P(op2));
                }
                return SUCCESS;
    ....


真的什么都不用说了。

EDIT UPDATE: 那个stackoverflow的问题,其实有人在问题的评论里指出了结果本来就是浮点数,不知道提问者怎么脑抽的。

EDIT UPDATE 2: PHP 7新增了一个 intdiv 函数,还真是非常PHP-Style的函数名和解决方法,看着就令人蛋疼。
分页: 1/3 第一页 1 2 3 下页 最后页 [ 显示模式: 摘要 | 列表 ]