时空主站

嗨,我是时空,一名来自中国的开发者。

0%

原文:有没有已经被证实存在的超能力?有能够后天习得的超能力吗?

作者:张天一
链接:https://www.zhihu.com/question/32235004/answer/57412334
来源:知乎
著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。

there is no spoon.
我回来补充了!!
———————————乱七八糟的分割线—————————

知乎上一位信基督的程序员朋友说,“就好比你玩游戏,不能因为在游戏里找不到职业为程序员的 NPC,又无法用游戏中的规则造一个程序员角色出来,就说程序员是假的,因为他有可能在游戏之外的某个维度 debug 。换个说法是,游戏是虚拟的,程序员的存在才是真实。”(侵删致歉)私以为说的非常好。
如果代入这个理论来看的话,世界就有意思了。
一神教和多神教的区别就是这个世界的程序是一位程序员写的还是多位程序员写的,不同教派的区别就是因为自己所处的数据片段不一样所以脑补的神的形象也不一样。
还记得Neo去见先知的那个片段吗?看见那几个孩子,他们每个人都做了违反物理规律的事情,那个意念弯曲勺子的小僧侣对着他说,不要掰它,要看透它。
他说,“There is no spoon.”
很巧的是魔兽争霸3有一个作弊码,There is no spoon,输入后你的英雄魔法是无限的。
如果他们有自己的意识的话他们会意识到世界的规律变化了,而对你而言,你也不过是在利用代码而已。再举一个例子如Minecraft这种沙盒游戏,你可以通过合理的资源配置来完成一些科技,组成与门或门非门来完成牌子电路或者红石电路,甚至做出CPU,而有些你作弊也可以。科学就像是你在摸索mc的世界规律来完成科技,开作弊码就像是直接利用了代码的后门,“看透”了数据的本质(其实并没有真正看透,譬如你使用作弊码只是知其然不知其所以然,只能算作“使用”而非“破解”)。
这就是科学力量和超自然力量的关系。更直接的说,一个是掰勺子,一个是看穿勺子。两者实际上都是在“使用”它,而所谓的唯物世界不过是按照规律运行的一组数据,你可以像在mc里做电路一样发展科技,完成很厉害的事,也可以理解程序破解程序直接的为自己谋福利,两者有区别吗?有。基础一样吗?基础都是这一组数据,问题的关键是,你要怎么去理解它,使用它。你没有玩过mc做不出电路,只知道作弊码也算不得破解程序,你要发展你要趋利避害你要往好的地方走你要活着,你就要学习规律。
你把世界当做一个沙盒游戏,很多的哲学问题都可以迎刃而解。
你面前的勺子,There is no spoon.

(你们再说地球OL我就要报警了!!!)
接下来要给大家介绍一位始祖级程序员,老子。
以及在宗教界独树一帜的宗教,道教。
把上面的话替换几个字比如把规律和程序换成“道”,就基本是道门的要旨了。
下面的话我的评论只涉及纯粹标准的各宗教徒,个人评价无攻击意图。第一,道教确实非常奇特,第二,我对道教了解较深,所以将以道教尤其是早期道教作为一种特异的哲学和宗教现象来讨论,并非由于我是道教徒。道门独树一帜的地方就在于,别的宗教学习世界系统的程序员,我们学习这个程序的运行原理。当然,所有的宗教都引人向善给人以内心的平静,仅仅从利益角度的狭义功利主义而言,撇开信仰不提,其他的宗教大多目的都是希望通过遵从使得程序员对他们有所偏好来获得特殊的权限,而道教敬天地人神,最尊敬的就是道。理解道,参悟道,学习道,使用道,道如同涛涛江河,他们学习水流的方向和规律顺着水流游的游刃有余左右逢源,这是道教徒的本意。亚伯拉罕一神系的三大宗教犹太教伊斯兰教基督教都是一神教,即使有主神和他们的小伙伴们的故事说到底拜的还是一个神,掌管万物;佛教在入中国之前也基本算是释迦牟尼一神主万世法;希腊、美洲、北欧、玛雅那是各自神系下的神话体系,不算宗教。
再回头看看道教就耐人寻味起来。道教没有统领一切的神,而诸神各有职司。耐人寻味之处就在于,绝大多数的神,都是由人而化神,很少有比如火气水气之精或天地交感化而为神。现在,我们回到那个有趣的理论基础上去,即是:
道教徒跪拜的不是设立世界程序的程序员,而是在这个程序里生出来的AI极高高到足以看透数据世界的本质并突破了数据限制的人,并且希望学习他们。
这种人被称为什么呢?神?仙?
都不是。道教徒叫他们为,【真人】。
interesting.
非常非常有趣啊。这些人被叫做真人,那么普通人是什么?
脑补一下Neo突破自己然后在最后飞起来的时候,普通人的表情。于此处黑客帝国全剧终,导演给他们的表情留了白。
当你突破这个世界的时候,不管你能在这个世界有多么厉害,摇山撼海夸神通,目上无尘目下空,你都不会再去珍视了,因为那于你而言不过是…盒子里的世界。
There is no spoon.

来源:知乎

一人我饮酒醉 醉把佳人成双对 两眼 是独相随只求他日能双归

娇女轻扶琴 燕嬉紫竹林 痴情红颜心甘情愿 千里把君寻.

说红颜我痴情笑 曲动琴声妙 我轻狂高傲懵懂无知只怪太年少

弃 江山 忘天下 斩断情丝无牵挂 千古留名传佳话 两年征战以白发

一生征战何人陪 谁是谁非谁相随 戎马一生为了谁 能爱几回恨几回

败 帝王 斗苍天 夺得皇位以成仙 豪情万丈天地间 续写另类帝王篇

红尘事我以斩断 久经战场人心乱 当年扬名又力万 是这一战我无遗憾

相思 我愁断肠 眼中我泪两行 我多年为君一统天下 戎马把名扬

烟雨 我平凡事 此生 我怀大志 我为了家人回眸一笑立下这毒誓

百花 我出芬芳 回首 我曲流觞 我回眸沧海一首忧歌感触梨花香

将军出征人在外 归来之日谁还在 兄弟把酒论豪迈 驰骋疆场求一败

这次走我何时归 寒 风起 心似灰 冷风吹起樱花飞 触景生情心伤悲

琴声悠悠在回荡 一首幽歌为你唱 沧海桑田难遗忘 酒醒燕归来无恙

百花绽放出芬芳 再次回首曲流伤 回眸感触昙花香 一首忧歌笑沧桑

仰望窗外烟雨朦胧 想你当初那笑容 佳人一别月下逢 牡丹花开百花丛

情 已过 义难断 提笔写下江山乱 孤枕难眠梦相伴 花飞花舞花飘散

紫金楼 风起玄 挥舞霸刀几万年 悠悠岁月心缠绵 如何忘记你容颜

恍然如梦烟雨间 雨碎落叶舞翩翩 烟雨飘渺断崖边 待我转世化成仙

为何你要说离别 留我一人寻彩蝶 浮生若梦三字决 留下三字这心结

这 情花 为你摘 一颗心门为你开 平凡事我了尘埃 寂寥之心谁能猜

一别红颜多年后 多年情 在守候 断情之曲谁人奏 思念红颜人消瘦

海誓山盟烟雨楼 苦苦相思两处愁 三声誓言的缘由 只因一生无所求

梦里梦外千百年 可曾记得那誓言 今生情 来世缘 难忘二字为红颜

千 百里 相思雨 相 思雨 落谷底 红尘往事梦一曲 期盼三字风云起

脑中浮现一幕幕 一幕幕 江湖路 谁懂我心痛苦处 三声誓言以颠覆

梦里 谁独相思 为何要寻一相知 梦外 我望明月 只为一人情难却

企业版

vs_enterprise.exe –layout c:\vs2017offline

专业版

vs_professional.exe –layout c:\vs2017offline

社区版

vs_community.exe –layout c:\vs2017offline

企业版 Enterprise:NJVYC-BMHX2-G77MM-4XJMR-6Q8QF

专业版 Professional:KBJFW-NXHK6-W4WJM-CRMQB-G3CDH

来自 OSCHINA

昨天,Gitlab.com发生了一个大事,某同学误删了数据库,这个事看似是个低级错误,不过,因为Gitlab把整个过程的细节都全部暴露出来了,所以,可以看到很多东西,而对于类似这样的事情,我自己以前也干过,而在最近的两公司中我也见过(Amazon中见过一次,阿里中见过至少四次),正好通过这个事来说说一下自己的一些感想和观点吧。我先放个观点:你觉得有备份系统就不会丢数据了吗?

事件回顾

整个事件的回顾Gitlab.com在第一时间就放到了Google Doc上,事后,又发了一篇Blog来说明这个事,在这里,我简单的回顾一下这个事件的过程。 首先,一个叫YP的同学在给gitlab的线上数据库做一些负载均衡的工作,在做这个工作时的时候突发了一个情况,Gitlab被DDoS攻击,数据库的使用飙高,在block完攻击者的IP后,发现有个staging的数据库(db2.staging)已经落后生产库4GB的数据,于是YP同学在Fix这个staging库的同步问题的时候,发现db2.staging有各种问题都和主库无法同步,在这个时候,YP同学已经工作的很晚了,在尝试过多个方法后,发现db2.staging都hang在那里,无法同步,于是他想把db2.staging的数据库删除了,这样全新启动一个新的复制,结果呢,删除数据库的命令错误的敲在了生产环境上(db1.cluster),结果导致整个生产数据库被误删除。(陈皓注:这个失败基本上就是 “工作时间过长” + “在多数终端窗口中切换中迷失掉了”) 在恢复的过程中,他们发现只有db1.staging的数据库可以用于恢复,而其它的5种备份机制都不可用,第一个是数据库的同步,没有同步webhook,第二个是对硬盘的快照,没有对数据库做,第三个是用pg_dump的备份,发现版本不对(用9.2的版本去dump 9.6的数据)导致没有dump出数据,第四个S3的备份,完全没有备份上,第五个是相关的备份流程是问题百出的,只有几个粗糙的人肉的脚本和糟糕的文档,也就是说,不但是是人肉的,而且还是完全不可执行的。(陈皓注:就算是这些备份机制都work,其实也有问题,因为这些备份大多数基本上都是24小时干一次,所以,要从这些备份恢复也一定是是要丢数据的了,只有第一个数据库同步才会实时一些) 最终,gitlab从db1.staging上把6个小时前的数据copy回来,结果发现速度非常的慢,备份结点只有60Mbits/S,拷了很长时间(陈皓注:为什么不把db1.staging给直接变成生产机?因为那台机器的性能很差)。数据现在的恢复了,不过,因为恢复的数据是6小时前的,所以,有如下的数据丢失掉了:

  • 粗略估计,有4613 的项目, 74 forks, 和 350 imports 丢失了;但是,因为Git仓库还在,所以,可以从Git仓库反向推导数据库中的数据,但是,项目中的issues等就完全丢失了。
  • 大约有±4979 提交记录丢失了(陈皓注:估计也可以用git仓库中反向恢复)。
  • 可能有 707 用户丢失了,这个数据来自Kibana的日志。
  • 在1月31日17:20 后的Webhooks 丢失了。

因为Gitlab把整个事件的细节公开了出来,所以,也得到了很多外部的帮助,2nd Quadrant的CTO – Simon Riggs 在他的blog上也发布文章 Dataloss at Gitlab 给了一些非常不错的建议:

  • 关于PostgreSQL 9.6的数据同步hang住的问题,可能有一些Bug,正在fix中。
  • PostgreSQL有4GB的同步滞后是正常的,这不是什么问题。
  • 正常的停止从结点,会让主结点自动释放WALSender的链接数,所以,不应该重新配置主结点的 max_wal_senders 参数。但是,停止从结点时,主结点的复数连接数不会很快的被释放,而新启动的从结点又会消耗更多的链接数。他认为,Gitlab配置的32个链接数太高了,通常来说,2到4个就足够了。
  • 另外,之前gitlab配置的max_connections=8000太高了,现在降到2000个是合理的。
  • pg_basebackup 会先在主结点上建一个checkpoint,然后再开始同步,这个过程大约需要4分钟。
  • 手动的删除数据库目录是非常危险的操作,这个事应该交给程序来做。推荐使用刚release 的 repmgr
  • 恢复备份也是非常重要的,所以,也应该用相应的程序来做。推荐使用 barman (其支持S3)
  • 测试备份和恢复是一个很重要的过程。

看这个样子,估计也有一定的原因是——Gitlab的同学对PostgreSQL不是很熟悉。 随后,Gitlab在其网站上也开了一系列的issues,其issues列表在这里 Write post-mortem (这个列表可能还会在不断更新中)

从上面的这个列表中,我们可以看到一些改进措施了。挺好的,不过我觉得还不是很够。

相关的思考

因为类似这样的事,我以前也干过(误删除过数据库,在多个终端窗口中迷失掉了自己所操作的机器……),而且我在amazon里也见过一次,在阿里内至少见过四次以上(在阿里人肉运维的误操作的事故是我见过最多的),但是我无法在这里公开分享,私下可以分享。在这里,我只想从非技术和技术两个方面分享一下我的经验和认识。

技术方面

人肉运维 一直以来,我都觉得直接到生产线上敲命令是一种非常不好的习惯。我认为,一个公司的运维能力的强弱和你上线上环境敲命令是有关的,你越是喜欢上线敲命令你的运维能力就越弱,越是通过自动化来处理问题,你的运维能力就越强。理由如下: 其一,如果说对代码的改动都是一次发布的话,那么,对生产环境的任何改动(包括硬件、操作系统、网络、软件配置……),也都算是一次发布。那么这样的发布就应该走发布系统和发布流程,要被很好的测试、上线和回滚计划。关键是,走发布过程是可以被记录、追踪和回溯的,而在线上敲命令是完全无法追踪的。没人知道你敲了什么命令。 其二,真正良性的运维能力是——人管代码,代码管机器,而不是人管机器。你敲了什么命令没人知道,但是你写个工具做变更线上系统,这个工具干了什么事,看看工具的源码就知道了。 另外、有人说,以后不要用rm了,要用mv,还有人说,以后干这样的事时,一个人干,另一个人在旁边看,还有人说,要有一个checklist的强制流程做线上的变更,还有人说要增加一个权限系统。我觉得,这些虽然可以work,但是依然不好,再由如下: 其一、如果要解决一个事情需要加更多的人来做的事,那这事就做成劳动密集型了。今天我们的科技就是在努力消除人力成本,而不是在增加人力成本。而做为一个技术人员,解决问题的最好方式是努力使用技术手段,而不是使用更多的人肉手段。人类区别于动物的差别就是会发明和使用现代化的工具,而不是使用更多的人力。另外,这不仅仅因为是,人都是会有这样或那样的问题(疲惫、情绪化、急燥、冲动……),而机器是单一无脑不知疲惫的,更是因为,机器干活的效率和速度是比人肉高出N多倍的。 其二、增加一个权限系统或是别的一个watch dog的系统完全是在开倒车,权限系统中的权限谁来维护和审批?不仅仅是因为多出来的系统需要多出来的维护,关键是这个事就没有把问题解决在root上。除了为社会解决就业问题,别无好处,故障依然会发生,有权限的人一样会误操作。对于Gitlab这个问题,正如2nd Quadrant的CTO建议的那样,你需要的是一个自动化的备份和恢复的工具,而不是一个权限系统。 其三、像使用mv而不rm,搞一个checklist和一个更重的流程,更糟糕。这里的逻辑很简单,因为,1)这些规则需要人去学习和记忆,本质上来说,你本来就不相信人,所以你搞出了一些规则和流程,而这些规则和流程的执行,又依赖于人,换汤不换药,2)另外,写在纸面上的东西都是不可执行的,可以执行的就是只有程序,所以,为什么不把checklist和流程写成代码呢?(你可能会说程序也会犯错,是的,程序的错误是consistent,而人的错误是inconsistent) 最关键的是,数据丢失有各种各样的情况,不单单只是人员的误操作,比如,掉电、磁盘损坏、中病毒等等,在这些情况下,你设计的那些想流程、规则、人肉检查、权限系统、checklist等等统统都不管用了,这个时候,你觉得应该怎么做呢?是的,你会发现,你不得不用更好的技术去设计出一个高可用的系统!别无它法。

关于备份

一个系统是需要做数据备份的,但是,你会发现,Gitlab这个事中,就算所有的备份都可用,也不可避免地会有数据的丢失,或是也会有很多问题。理由如下: 1)备份通常来说都是周期性的,所以,如果你的数据丢失了,从你最近的备份恢复数据里,从备份时间到故障时间的数据都丢失了。 2)备份的数据会有版本不兼容的问题。比如,在你上次备份数据到故障期间,你对数据的scheme做了一次改动,或是你对数据做了一些调整,那么,你备份的数据就会和你线上的程序出现不兼容的情况。 3)有一些公司或是银行有灾备的数据中心,但是灾备的数据中心没有一天live过。等真正灾难来临需要live的时候,你就会发现,各种问题让你live不起来。你可以读一读几年前的这篇报道好好感受一下《以史为鉴 宁夏银行7月系统瘫痪最新解析》 所以,在灾难来临的时候,你会发现你所设计精良的“备份系统”或是“灾备系统”就算是平时可以工作,但也会导致数据丢失,而且可能长期不用的备份系统很难恢复(比如应用、工具、数据的版本不兼容等问题)。 我之前写过一篇《分布式系统的事务处理》,你还记得下面这张图吗?看看 Data Loss 那一行的,在Backups, Master/Slave 和 Master/Master的架构下,都是会丢的。 所以说,如果你要让你的备份系统随时都可以用,那么你就要让它随时都Live着,而随时都Live着的多结点系统,基本上就是一个分布式的高可用的系统。因为,数据丢失的原因有很多种,比如掉电、磁盘损坏、中病毒等等,而那些流程、规则、人肉检查、权限系统、checklist等等都只是让人不要误操作,都不管用,这个时候,你不得不用更好的技术去设计出一个高可用的系统!别无它法。(重要的事,得再说一篇) 另外,你可以参看我的另一篇《关于高可用系统》,这篇文章中以MySQL为例,数据库的replication也只能达到 两个9。 AWS 的 S3 的的高可用是4个加11个9的持久性(所谓11个9的持久性durability,AWS是这样定义的,如果你存了1万个对象,那么丢一个的时间是1000万年),这意味着,不仅仅只是硬盘坏,机器掉电,整个机房挂了,其保证可以承受有两个设施的数据丢失,数据还是可用的。试想,如果你把数据的可用性通过技术做到了这个份上,那么,你还怕被人误删一个结点上的数据吗?

非技术方面

故障反思 一般说来,故障都需要反思,在Amazon,S2以上的故障都需要写COE(Correction of Errors),其中一节就是需要Ask 5 Whys,我发现在Gitlab的故障回顾的blog中第一段中也有说要在今天写个Ask 5 Whys。关于Ask 5 Whys,其实并不是亚马逊的玩法,这还是算一个业内常用的玩法,也就是说不断的为自己为为什么,直到找到问题的概本原因,这会逼着所有的当事人去学习和深究很多东西。在Wikipedia上有相关的词条 5 Whys,其中罗列了14条规则:

  1. 你需要找到正确的团队来完成这个故障反思。
  2. 使用纸或白板而不是电脑。
  3. 写下整个问题的过程,确保每个人都能看懂。
  4. 区别原因和症状。
  5. 特别注意因果关系。
  6. 说明Root Cause以及相关的证据。
  7. 5个为什么的答案需要是精确的。
  8. 寻找问题根源的步骤,而不是直接跳到结论。
  9. 要基础客观的事实、数据和知识。
  10. 评估过程而不是人。
  11. 千万不要把“人为失误”或是“工作不注意”当成问题的根源。
  12. 培养信任和真诚的气氛和文化。
  13. 不断的问“为什么”直到问题的根源被找到。这样可以保证同一个坑不会掉进去两次。
  14. 当你给出“为什么”的答案时,你应该从用户的角度来回答。

工程师文化 上述的这些观点,其实,我在我的以住的博客中都讲过很多遍了,你可以参看《什么是工程师文化?》以及《开发团队的效率》。其实,说白了就是这么一个事——如果你是一个技术公司,你就会更多的相信技术而不是管理。相信技术会用技术来解决问题,相信管理,那就只会有制度、流程和价值观来解决问题。 这个道理很简单,数据丢失有各种各样的情况,不单单只是人员的误操作,比如,掉电、磁盘损坏、中病毒等等,在这些情况下,你设计的那些流程、规则、人肉检查、权限系统、checklist等等统统都不管用,这个时候,你觉得应该怎么做呢?是的,你会发现,你不得不用更好的技术去设计出一个高可用的系统!别无它法。(重要的事得说三遍) 事件公开 很多公司基本上都是这样的套路,首先是极力掩盖,如果掩盖不了了就开始撒谎,撒不了谎了,就“文过饰非”、“避重就轻”、“转移视线”。然而,面对危机的最佳方法就是——“多一些真诚,少一些套路”,所谓的“多一些真诚”的最佳实践就是——“透明公开所有的信息”,Gitlab此次的这个事给大家树立了非常好的榜样。AWS也会把自己所有的故障和细节都批露出来。 事情本来就做错了,而公开所有的细节,会让大众少很多猜测的空间,有利于抵制流言和黑公关,同时,还会赢得大众的理解和支持。看看Gitlab这次还去YouTube上直播整个修复过程,是件很了不起的事,大家可以到他们的blog上看看,对于这样的透明和公开,一片好评。 (全文完)

来源:酷壳

阿里他爸?

旧金山——雅虎(Yahoo)或将自己的互联网业务以48亿美元的价格卖给威瑞森通讯公司(Verizon Communications),这笔交易的命运可能尚不确定。但是如果它成为现实,雅虎亦为公司剩下的业务做好了计划。

周一,该公司在一份监管备案文件中称,交易完成后,它将更名为Altaba。

此外,该公司目前半数以上的董事会成员将退出,包括首席执行官玛丽莎·梅耶尔(Marissa Mayer)在内。

为什么叫Altaba呢?

如果与威瑞森公司的交易能够完成,雅虎所剩的最大单笔资产就是在中国电子商务巨头阿里巴巴公司(Alibaba)所持的15%股份,Altaba这个名字其实就是在“阿里巴巴”的基础上稍作修改。Altaba还将持有雅虎日本35.5%的股份(雅虎的一名发言人拒绝作出评论)。

不过,Altaba当然是一个不同寻常的名字。它碰巧还很接近Al-Taba,那是巴基斯坦的一家剪刀制造公司的名字。

该公司在监管备案文件中称,更名后仍将留下的董事包括帮助推动公司改革的激进投资人杰弗里·史密斯(Jeffrey Smith);前投资银行家托尔·布雷厄姆(Tor Braham)和凯瑟琳·J·弗里德曼(Catherine J. Friedman);芯片制造公司博通(Broadcom)的前首席财务官埃里克· 勃兰特(Eric Brandt);以及媒体公司IAC的前首席财务官托马斯·麦金纳尼(Thomas McInerney)。

即将退位的董事包括梅耶尔;雅虎董事长梅纳德·韦伯(Maynard Webb);以及雅虎创始人之一大卫·费罗(David Filo)。韦伯将成为更名后的Altaba的荣退主席。

当然,所有这些变化取决于雅虎能否真的把自己最重要的互联网业务卖给威瑞森,要知道,雅虎曾两次遭遇黑客袭击,导致信息泄露,第二次袭击影响了10多亿用户的帐户。

威瑞森的高管曾公开表示,他们在权衡自己的选择,包括支付的金额可能会少于已达成一致的48亿美元。上周,威瑞森的产品创新和新业务主管玛妮·沃尔登(Marni Walden)在谈起这项交易的命运时说,“今天,我不能坐在这里确定地说会发生什么,因为我们还不知道。”

不过,隶属于威瑞森的美国在线(AOL)的首席执行官蒂姆·阿姆斯特朗(Tim Armstrong)在接受CNBC采访时称,他感到乐观。

“我依然对达成这项交易充满希望,我觉得,与此同时,我们会看看雅虎调查的结果,”他说。

来源:纽时中文

这篇文章来源于Quroa的一个问答《What are some time-saving tips that every Linux user should know?》—— Linux用户有哪些应该知道的提高效率的技巧。我觉得挺好的,总结得比较好,把其转过来,并加了一些自己的理解。 首先,我想告诉大家,在Unix/Linux下,最有效率技巧的不是操作图形界面,而是命令行操作,因为命令行意味着自动化。如果你看过《你可能不知道的Shell》以及《28个Unix/Linux的命令行神器》你就会知道Linux有多强大,这个强大完全来自于命令行,于是,就算你不知道怎么去做一个环保主义的程序员,至少他们可以让你少熬点夜,从而有利于你的身体健康和性生活。下面是一个有点长的列表,正如作者所说,你并不需要知道所有的这些东西,但是如果你还在很沉重地在使用Linux的话,这些东西都值得你看一看。 (注:如果你想知道下面涉及到的命令的更多的用法,你一定要man一点。对于一些命令,你可以需要先yum或apt-get来安装一下,如果有什么问题,别忘了Google。如果你要Baidu的话,我仅代表这个地球上所有的生物包括微生物甚至细菌病毒和小强BS你到宇宙毁灭)

基础

  • 学习 Bash 。你可以man bash来看看bash的东西,并不复杂也并不长。你用别的shell也行,但是bash是很强大的并且也是系统默认的。(学习zsh或tsch只会让你在很多情况下受到限制)

  • 学习 vim 。在Linux下,基本没有什么可与之竞争的编辑器(就算你是一个Emacs或Eclipse的重度用户)。你可以看看《简明vim攻略》和 《Vim的冒险游戏》以及《给程序员的Vim速查卡》还有《把Vim变成一个编程的IDE》等等。

  • 了解 ssh。明白不需要口令的用户认证(通过ssh-agent, ssh-add),学会用ssh翻墙,用scp而不是ftp传文件,等等。你知道吗?scp 远端的时候,你可以按tab键来查看远端的目录和文件(当然,需要无口令的用户认证),这都是bash的功劳。

  • 熟悉bash的作业管理,如: &, Ctrl-Z, Ctrl-C, jobs, fg, bg, kill, 等等。当然,你也要知道Ctrl+(SIGQUIT)和Ctrl+C (SIGINT)的区别。

  • 简单的文件管理 : ls 和 ls -l (你最好知道 “ls -l” 的每一列的意思), less, head, tail 和 tail -f, ln 和 ln -s (你知道明白hard link和soft link的不同和优缺点), chown, chmod, du (如果你想看看磁盘的大小 du -sk *), df, mount。当然,原作者忘了find命令。

  • 基础的网络管理: ip 或 ifconfig, dig。当然,原作者还忘了如netstat, ping, traceroute, 等

  • 理解正则表达式,还有grep/egrep的各种选项。比如: -o, -A, 和 -B 这些选项是很值得了解的。

  • 学习使用 apt-get 和 yum 来查找和安装软件(前者的经典分发包是Ubuntu,后者的经典分发包是Redhat),我还建议你试着从源码编译安装软件。

日常

  • 在 bash 里,使用 Ctrl-R 而不是上下光标键来查找历史命令。

  • 在 bash里,使用 Ctrl-W 来删除最后一个单词,使用 Ctrl-U 来删除一行。请man bash后查找Readline Key Bindings一节来看看bash的默认热键,比如:Alt-. 把上一次命令的最后一个参数打出来,而Alt-* 则列出你可以输入的命令。

  • 回到上一次的工作目录: cd – (回到home是 cd ~)

  • 使用 xargs。这是一个很强大的命令。你可以使用-L来限定有多少个命令,也可以用-P来指定并行的进程数。如果你不知道你的命令会变成什么样,你可以使用xargs echo来看看会是什么样。当然, -I{} 也很好用。示例:

1
2
3
find . -name *.py | xargs grep some_function

cat hosts | xargs -I{} ssh [email protected]{} hostname
  • pstree -p 可以帮你显示进程树。(读过我的那篇《一个fork的面试题》的人应该都不陌生)

  • 使用 pgrep 和 pkill 来找到或是kill 某个名字的进程。 (-f 选项很有用).

  • 了解可以发给进程的信号。例如:要挂起一个进程,使用 kill -STOP [pid]. 使用 man 7 signal 来查看各种信号,使用kill -l 来查看数字和信号的对应表

  • 使用 nohup 或 disown 如果你要让某个进程运行在后台。

  • 使用netstat -lntp来看看有侦听在网络某端口的进程。当然,也可以使用 lsof。

  • 在bash的脚本中,你可以使用 set -x 来debug输出。使用 set -e 来当有错误发生的时候abort执行。考虑使用 set -o pipefail 来限制错误。还可以使用trap来截获信号(如截获ctrl+c)。

  • 在bash 脚本中,subshells (写在圆括号里的) 是一个很方便的方式来组合一些命令。一个常用的例子是临时地到另一个目录中,例如:

1
2
3
# do something in current dir
(cd /some/other/dir; other-command)
# continue in original dir
  • 在 bash 中,注意那里有很多的变量展开。如:检查一个变量是否存在: ${name:?error message}。如果一个bash的脚本需要一个参数,也许就是这样一个表达式 input_file=${1:?usage: $0 input_file}。一个计算表达式: i=$(( (i + 1) % 5 ))。一个序列: {1..10}。 截断一个字符串: ${var%suffix} 和 ${var#prefix}。 示例: if var=foo.pdf, then echo ${var%.pdf}.txt prints “foo.txt”.

  • 通过 <(some command) 可以把某命令当成一个文件。示例:比较一个本地文件和远程文件 /etc/hosts: diff /etc/hosts <(ssh somehost cat /etc/hosts)

  • 了解什么叫 “here documents” ,就是诸如 cat <<EOF 这样的东西。

  • 在 bash中,使用重定向到标准输出和标准错误。如: some-command >logfile 2>&1。另外,要确认某命令没有把某个打开了的文件句柄重定向给标准输入,最佳实践是加上 “</dev/null”,把/dev/null重定向到标准输入。

  • 使用 man ascii 来查看 ASCII 表。

  • 在远端的 ssh 会话里,使用 screen 或 dtach 来保存你的会话。(参看《28个Unix/Linux的命令行神器》)

  • 要来debug Web,试试curl 和 curl -I 或是 wget 。我觉得debug Web的利器是firebug,curl和wget是用来抓网页的,呵呵。

  • 把 HTML 转成文本: lynx -dump -stdin

  • 如果你要处理XML,使用 xmlstarlet

  • 对于 Amazon S3, s3cmd 是一个很方便的命令(还有点不成熟)

  • 在 ssh中,知道怎么来使用ssh隧道。通过 -L or -D (还有-R) ,翻墙神器。

  • 你还可以对你的ssh 做点优化。比如,.ssh/config 包含着一些配置:避免链接被丢弃,链接新的host时不需要确认,转发认证,以前使用压缩(如果你要使用scp传文件):

1
2
3
4
5
6
TCPKeepAlive=yes
ServerAliveInterval=15
ServerAliveCountMax=6
StrictHostKeyChecking=no
Compression=yes
ForwardAgent=yes
  • 如果你有输了个命令行,但是你改变注意了,但你又不想删除它,因为你要在历史命令中找到它,但你也不想执行它。那么,你可以按下 Alt-# ,于是这个命令关就被加了一个#字符,于是就被注释掉了。

数据处理

  • 了解 sort 和 uniq 命令 (包括 uniq 的 -u 和 -d 选项).

  • 了解用 cut, paste, 和 join 命令来操作文本文件。很多人忘了在cut前使用join。

  • 如果你知道怎么用sort/uniq来做集合交集、并集、差集能很大地促进你的工作效率。假设有两个文本文件a和b已解被 uniq了,那么,用sort/uniq会是最快的方式,无论这两个文件有多大(sort不会被内存所限,你甚至可以使用-T选项,如果你的/tmp目录很小)

1
2
3
4
5
cat a b | sort | uniq > c   # c is a union b 并集

cat a b | sort | uniq -d > c   # c is a intersect b 交集

cat a b b | sort | uniq -u > c   # c is set difference a - b 差集
  • 了解和字符集相关的命令行工具,包括排序和性能。很多的Linux安装程序都会设置LANG 或是其它和字符集相关的环境变量。这些东西可能会让一些命令(如:sort)的执行性能慢N多倍(注:就算是你用UTF-8编码文本文件,你也可以很安全地使用ASCII来对其排序)。如果你想Disable那个i18n 并使用传统的基于byte的排序方法,那就设置export LC_ALL=C (实际上,你可以把其放在 .bashrc)。如果这设置这个变量,你的sort命令很有可能会是错的。

  • 了解 awk 和 sed,并用他们来做一些简单的数据修改操作。例如:求第三列的数字之和: awk ‘{ x += $3 } END { print x }’。这可能会比Python快3倍,并比Python的代码少三倍。

  • 使用 shuf 来打乱一个文件中的行或是选择文件中一个随机的行。

  • 了解sort命令的选项。了解key是什么(-t和-k)。具体说来,你可以使用-k1,1来对第一列排序,-k1来对全行排序。

  • Stable sort (sort -s) 会很有用。例如:如果你要想对两例排序,先是以第二列,然后再以第一列,那么你可以这样: sort -k1,1 | sort -s -k2,2

  • 我们知道,在bash命令行下,Tab键是用来做目录文件自动完成的事的。但是如果你想输入一个Tab字符(比如:你想在sort -t选项后输入字符),你可以先按Ctrl-V,然后再按Tab键,就可以输入字符了。当然,你也可以使用$’t’。

  • 如果你想查看二进制文件,你可以使用hd命令(在CentOS下是hexdump命令),如果你想编译二进制文件,你可以使用bvi命令(http://bvi.sourceforge.net/ 墙)

  • 另外,对于二进制文件,你可以使用strings(配合grep等)来查看二进制中的文本。

  • 对于文本文件转码,你可以试一下 iconv。或是试试更强的 uconv 命令(这个命令支持更高级的Unicode编码)

  • 如果你要分隔一个大文件,你可以使用split命令(split by size)和csplit命令(split by a pattern)。

系统调试

  • 如果你想知道磁盘、CPU、或网络状态,你可以使用 iostat, netstat, top (或更好的 htop), 还有 dstat 命令。你可以很快地知道你的系统发生了什么事。关于这方面的命令,还有iftop, iotop等(参看《28个Unix/Linux的命令行神器》)

  • 要了解内存的状态,你可以使用free和vmstat命令。具体来说,你需要注意 “cached” 的值,这个值是Linux内核占用的内存。还有free的值。

  • Java 系统监控有一个小的技巧是,你可以使用kill -3 发一个SIGQUIT的信号给JVM,可以把堆栈信息(包括垃圾回收的信息)dump到stderr/logs。

  • 使用 mtr 会比使用 traceroute 要更容易定位一个网络问题。

  • 如果你要找到哪个socket或进程在使用网络带宽,你可以使用 iftop 或 nethogs。

  • Apache的一个叫 ab 的工具是一个很有用的,用quick-and-dirty的方式来测试网站服务器的性能负载的工作。如果你需要更为复杂的测试,你可以试试 siege。

  • 如果你要抓网络包的话,试试 wireshark 或 tshark。

  • 了解 strace 和 ltrace。这两个命令可以让你查看进程的系统调用,这有助于你分析进程的hang在哪了,怎么crash和failed的。你还可以用其来做性能profile,使用 -c 选项,你可以使用-p选项来attach上任意一个进程。

  • 了解用ldd命令来检查相关的动态链接库。注意:ldd的安全问题

  • 使用gdb来调试一个正在运行的进程或分析core dump文件。参看我写的《GDB中应该知道的几个调试方法

  • 学会到 /proc 目录中查看信息。这是一个Linux内核运行时记录的整个操作系统的运行统计和信息,比如: /proc/cpuinfo, /proc/xxx/cwd, /proc/xxx/exe, /proc/xxx/fd/, /proc/xxx/smaps.

  • 如果你调试某个东西为什么出错时,sar命令会有用。它可以让你看看 CPU, 内存, 网络, 等的统计信息。

  • 使用 dmesg 来查看一些硬件或驱动程序的信息或问题。

作者最后加了一个免责声明:Disclaimer: Just because you can do something in bash, doesn’t necessarily mean you should. ;) (全文完)

来源:酷壳

算法面试可能是微软搞出来的面试方法,现在很多公司都在效仿,而且我们的程序员也乐于解算法题,我个人以为,这是应试教育的毒瘤!我在《再谈“我是怎么招程序员”》中比较保守地说过,“问难的算法题并没有错,错的很多面试官只是在肤浅甚至错误地理解着面试算法题的目的。”,今天,我想加强一下这个观点——我反对纯算法题面试!(注意,我说的是纯算法题)

我再次引用我以前的一个观点——

能解算法题并不意味着这个人就有能力就能在工作中解决问题,你可以想想,小学奥数题可能比这些题更难,但并不意味着那些奥数能手就能解决实际问题。

好了,让我们来看一个示例(这个示例是昨天在微博上的一个讨论),这个题是——“找出无序数组中第2大的数”,几乎所有的人都用了O(n)的算法,我相信对于我们这些应试教育出来的人来说,不用排序用O(n)算法是很正常的事,连我都不由自主地认为O(n)算法是这个题的标准答案。我们太习惯于标准答案了,这是我国教育最悲哀的地方。(广义的洗脑就是让你的意识依赖于某个标准答案,然后通过给你标准答案让你不会思考而控制你)

功能性需求分析

试想,如果我们在实际工作中得到这样一个题 我们会怎么做?我一定会分析这个需求,因为我害怕需求未来会改变,今天你叫我找一个第2大的数,明天你找我找一个第4大的数,后天叫我找一个第100大的数,我不搞死了。需求变化是很正常的事。分析完这个需求后,我会很自然地去写找第K大数的算法——难度一下子就增大了。

很多人会以为找第K大的需求是一种“过早扩展”的思路,不是这样的,我相信我们在实际编码中写过太多这样的程序了,你一定不会设计出这样的函数接口—— Find2ndMaxNum(int* array, int len),就好像你不会设计出 DestroyBaghdad(); 这样的接口,而是设计一个DestoryCity( City& ); 的接口,而把Baghdad当成参数传进去!所以,你应该是声明一个叫FindKthMaxNum(int* array, int len, int kth),把2当成参数传进去。这是最基本的编程方法,用数学的话来说,叫代数!最简单的需求分析方法就是把需求翻译成函数名,然后看看是这个接口不是很二?!

(注:不要纠结于FindMaxNum()或FindMinNum(),因为这两个函数名的业务意义很清楚了,不像Find2ndMaxNum()那么二)

非功能性需求分析

性能之类的东西从来都是非功能性需求,对于算法题,我们太喜欢研究算法题的空间和时间复杂度了。我们希望做到空间和时间双丰收,这是算法学术界的风格。所以,习惯于标准答案的我们已经失去思考的能力,只会机械地思考算法之内的性能,而忽略了算法之外的性能

如果题目是——“从无序数组中找到第K个最大的数”,那么,我们一定会去思考用O(n)的线性算法找出第K个数。事实上,也有线性算法——STL中可以用nth_element求得类似的第n大的数,其利用快速排序的思想,从数组S中随机找出一个元素X,把数组分为两部分Sa和Sb。Sa中的元素大于等于X,Sb中元素小于X。这时有两种情况:1)Sa中元素的个数小于k,则Sb中的第k-|Sa|个元素即为第k大数;2) Sa中元素的个数大于等于k,则返回Sa中的第k大数。时间复杂度近似为O(n)。

搞学术的nuts们到了这一步一定会欢呼胜利!但是他们哪里能想得到性能的需求分析也是来源自业务的!

我们一说性能,基本上是个人都会问,请求量有多大?如果我们的FindKthMaxNum()的请求量是m次,那么你的这个每次都要O(n)复杂度的算法得到的效果就是O(n*m),这一点,是书呆子式的学院派人永远想不到的。因为应试教育让我们不会从实际思考了。

工程式的解法

根据上面的需求分析,有软件工程经验的人的解法通常会这样:

1)把数组排序,从大到小。

2)于是你要第k大的数,就直接访问 array[k]。

排序只需要一次,O(n*log(n)),然后,接下来的m次对FindKthMaxNum()的调用全是O(1)的,整体复杂度反而成了线性的。

其实,上述的还不是工程式的最好的解法,因为,在业务中,那数组中的数据可能会是会变化的,所以,如果是用数组排序的话,有数据的改动会让我重新排序,这个太耗性能了,如果实际情况中会有很多的插入或删除操作,那么可以考虑使用B+树。

工程式的解法有以下特点:

1)很方便扩展,因为数据排好序了,你还可以方便地支持各种需求,如从第k1大到k2大的数据(那些学院派写出来的代码在拿到这个需求时又开始挠头苦想了)

2)规整的数据会简化整体的算法复杂度,从而整体性能会更好。(公欲善其事,必先利其器)

3)代码变得清晰,易懂,易维护!(学院派的和STL一样的近似O(n)复杂度的算法没人敢动)

争论

你可能会和我有以下争论,

  • 如果程序员做这个算法题用排序的方式,他一定不会像你想那么多。是的,你说得对。但是我想说,很多时候,我们直觉地思考,恰恰是正确的路。因为“排序”这个思路符合人类大脑处理问题的方式,而使用学院派的方式是反大脑直觉的。反大脑直觉的,通常意味着晦涩难懂,维护成本上升。

  • 就是一道面试题,我就是想测试一下你的算法技能,这也扯太多了。没问题,不过,我们要清楚我们是在招什么人?是一个只会写算法的人,还是一个会做软件的人?这个只有你自己最清楚。

  • 这个算法题太容易诱导到学院派的思路了。是的这道“找出第K大的数”,其实可以变换为更为业务一点的题目——“我要和别的商户竞价,我想排在所有竞争对手报价的第K名,请写一个程序,我输入K,和一个商品名,系统告诉我应该订多少价?(商家的所有商品的报价在一数组中)”——业务分析,整体性能,算法,数据结构,增加需求让应聘者重构,这一个问题就全考了。

  • 你是不是在说算法不重要,不用学?千万别这样理解我,搞得好像如果面试不面,我就可以不学。算法很重要,算法题能锻炼我们的思维,而且也有很多实际用处。我这篇文章不是让大家不要去学算法,这是完全错误的,我是让大家带着业务问题去使用算法。问你业务问题,一样会问到算法题上来。

小结

看过这上面的分析,我相信你明白我为什么反对纯算法面试题了。原因就是纯算法的面试题根本不能反应一个程序的综合素质

那么,在面试中,我们应该要考量程序员的那些综合素质呢?我以为有下面这些东西:

  1. 会不会做需求分析?怎么理解问题的?
  2. 解决问题的思路是什么?想法如何?
  3. 会不会对基础的算法和数据结构灵活运用?

另外,我们知道,对于软件开发来说,在工程上,难是的下面是这些挑战:

  • 软件的维护成本远远大于软件的开发成本。
  • 软件的质量变得越来越重要,所以,测试工作也变得越来越重要。
  • 软件的需求总是在变的,软件的需求总是一点一点往上加的。
  • 程序中大量的代码都是在处理一些错误的或是不正常的流程。

所以,对于编程能力上,我们应该主要考量程序员的如下能力:

  1. 设计是否满足对需求的理解,并可以应对可能出现的需求变化。
  2. 程序是否易读,易维护?
  3. 重构代码的能力如何?
  4. 会不会测试自己写好的程序?

所以,这段时间,我越来越倾向于问应聘者一些有业务意义的题,而且应增加或更改需求来看程序员的重构代码的能力,写完程序后,让应聘者设计测试案例。

比如:解析加减乘除表达式,字符串转数字,洗牌程序,口令生成器,通过ip地址找地点,英汉词典双向检索……

总之,我反对纯算法面试题!

(全文完)

来源:酷壳

2012年的时候写过一篇叫《程序算法与人生选择》的文章,我用算法来类比如何做选择,说白了就是怎么去计算,但是并没有讲程序员可以发展的方向有哪些。 所以,就算是有这些所谓的方法论,我们可能对自己的发展还是会很纠结和无所事从,尤其是人到了30岁,这种彷徨和迷惑越来越重。虽然我之前也写过一篇《编程年龄和编程技能》的文章,但是还是有很多做技术的人对于自己能否在年纪大时还能去做技术感到没有信心。我猜测,这其中,最大的问题的是,目前从事技术工作的种种负面的经历(比如经常性的加班,被当成棋子或劳动力等等),让人完全看不到希望和前途,尤其是随着年纪越来越大,对未来的越来越没有信心。

同时,也是因为在GIAC的大会被问到,程序员老了怎么办?而在年底这段时间,也和几个朋友在交流中不断地重复谈到个人发展的这个话题。我的人生过半,活到“不惑”的年纪,自然经常性的对什么事都会回头看看总结归纳,所以,在交谈过程中和交谈过后,自己也有一些思考想记录下来。因为我本人也是在这条路上的人,所以,谈不上给他人指导,我同样也是在瞎乱折腾同样每天在思考自己要去哪儿的“一尘世间迷途老生”。况且,我的经历和眼界非常有限,因此,下面的这些关于个人发展的文字和思考必然是受我的眼界和经历所局限的。也欢迎大家补充和指正。

这些东西不一定对,也不一定就是全部,期许可以让你在年底的时候有所思考,在明年的时候有所计划。

一个重要阶段和标志

在讲个人发展之前,我需要先说一下人生中的一个非常重要的阶段——20到30岁!

这个阶段的首要任务,就是提升自己学习能力和解决难题的能力。**这是一个非常非常关键的时间段!这个时间段几乎决定着你的未来。**

30岁以前,这个时间段,应该是人学习和积累的时间段,这个时间段,就是努力学习的时间段。这个时间段,你一定要把时间花在解决问题的技能上。就是说,你一定要练就成的技能是——你能解决大多数人不能解决的问题。使蛮力埋头加班苦干,当一个搬砖老黄牛的是肯定没有前途的。如果你不幸呆在了一个搬砖的地方,天天被业务压得喘不过气来,我建议你宁可让你的项目延期被老板骂,也要把时间挤出来努力学习基础知识,多掌握一些技术(很多技术在思路上是相通的),然后才能有机会改变自己目前的状况。因为,比起你的个人未来,项目延期被老板骂、绩效不好拿不到奖金,都不是什么事儿。

总结一下,你在30岁前,工作5-7年,你需要拥有:

  • 高效的学习能力。这意味着——基础知识扎实、触类旁通、读英文文档不费劲、有寻找前沿知识的能力、能够看到问题和技术的本质、善于思辩、能独立思考。

  • 解决问题的能力。这意味着——你要高效的学习能力、见过很多的场景、犯过或是处理很多错误、能够防火而不是救火。

如果你拥有这两个能力的现象是—— 在团队或身边的人群中的显现出Leadership

Leadership并不是当领导和经理,而是一种特征,这种特征有如下两个简单的表象:

  • 帮人解问题。团队或身边中大多数人都在问:“这问题怎么办?”,而总是你能站出来告诉大家这事该怎么办?

  • 被人所依赖。团队或身边中大多数人在做比较关键的决定时,都会来找你咨询你的意见和想法。

一但你在在30岁之间出现了Leadership这样的特征,那么,你会进入一个正循环的阶段:

  • 因为你学习能力强,所以,你会有更多的机会解决难题。
  • 你有更多的机会解决难题,你就会学更多的东西,于是你就会更强。
  • 上面这个循环,只要循环上几年,就会让你人生的各种可能性大大的增加。

【 注意 】

  • 要达到这样的特质,需要找到自己的长处、以及适合自己的环境。就像鱼的特长是呆在水里,让鱼儿去追求陆上动物的刺激生活并不靠谱。

  • 一般说来,有这样的潜质的人,在学校中就应该要出现。如果你在大学中还没有出现这样的潜质,那么,你在工作当中要加倍努力了(注:所谓的加倍努力,不是让你使蛮力加班,而是让你多学习成长,使蛮力拼命是弥补不了能力、思维、眼界上的缺陷的)。

  • Leadership也有范围的,比如,身边的朋友,工作中的团队/部分,圈内,整个行业。Leadership的范围越大,你的个人发展的选择性就越高。反之则越小。

  • 如果已到了30岁左右,还是没有出现这样的特征。那么,可能未来你也很难有这样的Leadership了。而你的个人发展的可能性可能也就不多了(sigh…)

读到这里,我必需要说一下,如果你已开始显现出你的Leadership,那么你才谈得上个人发展,这篇文章后续的内容也可能才会对你有意义

个人发展的三个方向

以我个人短浅的经历和视野,目前只看到的人的发展有如下三个大方向(他们之间可能会有重叠):

1)在职场中打拼

2)去经历有意义有价值的事

3)追求一种自由的生活

这三个方向,我个人或多或少都体验过,我也见过身边的很多人走这三个方向走的比较成功。也许还有别的方向,没办法,现在,我的视野就这么大,所以,我在这里,我主要就是谈谈这三个方向。Again,人有资格去走这三个方向的前提是——已有了上面我说的Leadership那种特质!

一、在职场中发展

在职场中发展应该是绝大多数人的选择。通过加入公司来达到人生的发展。

我们经常可以看到很多所谓的“职业规划”,但是大多数职业规划只不过人力资源搞出来的东西,和实际其实是有很大出入的。我的人生经历中,有18年左右是在公司中度过的,在过银行,小公司,大公司,民营公司,外国公司,传统IT公司,互联网公司,不同的公司完全有不同的玩法和文化,我的经历还算丰富,但也不算特别成功,这里只分享一些我在职场中的心得(不一定对,仅供参考)。

1、去顶尖公司

去顶尖公司的一个目的就是让你的Leadership的范围的可能性扩大

因为公司和公司的差距也不小,所以,就算你在低端公司里是骨干份子,但在高端公司里可能只是一个普通员工(就像中国足球队的主力到了英超可能都无法入选)。所以,在职场中,如果你要让你的个人价值最大化的话,你一定要去顶尖的公司。因为顶尖公司里有非常不错的工作方法和场景,这并不是能看书或是交流得来的,这是必需要去亲身体验的。所以说,在顶尖公司掌握的技能,开阔的眼界,通常来说都会比低端公司的要多得多。

另外,每个公司的工作级别都是有相互对标的,比如:阿里的P几对应于百度的T几。国内的一线公司职位还相当,但是如果和国外一线公司的比,那就有差距了,而且差距还很大。比如,Google或Facebook的某个高级工程师,可能就对应于阿里的P8/P9甚至更高。

是的,对于职场来说,如果你在顶尖公司是骨干,那么,你去低端公司,则有很大机会会成为他们高管和核心。就好像你在Facebook里干三五年成为他们的技术骨干,那么你到BAT去成成为高管概率是非常大的。反过来,如果你毕业主去了BAT成为了一个螺丝钉,在天天加班中度过你的青春,你干个十年能成为BAT的高管的概率可能会非常的低。

2、去真正的创业公司

去顶尖公司和去创业公司在某些时候并不冲突。不过,这里我想讲的是,一个技术能力强的人在大公司可能会被埋没掉。因为大公司业务成功后,

  • 成功的公司在招聘各种高级技术人才都不会成为问题,于是少你一个不少,多你一个不多。

  • 成功的公司其整个技术体系已经完成,Legacy的问题也比较多,所以,可以供你发挥的余地不大。

  • 成功的公司更多的可能会想要稳定的系统,稳定必然会产生保守,而保守则产生不思进取。

所以,对于中高级人才来说,在大公司里的能产生的个人价值,可能远远不如那些求贤若渴、没有包袱、可以尽情施展、相对更为灵活和自由的创业型公司。

不过,去创业公司需要小心仔细的挑选和评估,创业公司的不确定因素很多,也和创始人的因素太大了,所以,你需要小心了解创始人和他们的业务情况,想法和理念差不多才能更好的共事。

好多创业公司其实并不是真正的创业公司,他们创业有很大的侥幸和驱利心理,要小心甄别。因为那不是真正的创业公司。

3、职业生涯的发展阶段

首先,有一个不争事实——整个社会是会把最重要的工作交给30岁左右的这群人的。也就是说,30岁左右这群人是这个社会的做事的中坚力量。

所以,这是一个机遇!如果你有了Leadership,你就一定能在这个时间段内赶得上这个机遇——公司和领导对你寄于信任和厚望,并把重要的团队和工作交给你。

于是,你的30岁到40岁就成了一个职业生涯的发展期,也就是你的事业上升期。如果你到40岁都没有赶上,那么你的职业生涯也就这样了,老有所成的人是少数。

在你事业的上升期,你需要更多的软技能,比如:

  • 带领产品和业务的发展的能力
  • 推行自己喜欢的文化的能力
  • 项目管理的能力——在任务重、时间紧中求全
  • 沟通和说服别人的能力
  • 解决冲突的能力
  • 管理和发展团队的能力
  • 解决突发事件的应急能力
  • …… ……

另外,你还要明白在职场里的几个冷酷的事实:

  • 你开始要关心并处理复杂的人事。尤其在大公司,大量的人都是屁股决定脑袋,利益关系复杂,目标不一致,每个人心里都有不一样的想法。这个时候再也不是talk is cheap, show me the code!而是,code is cheap,talk is the matter。你需要花大量的时间去思考和观察形形色色的人。需要耗费大量的精力在不同的人之间周旋,而不是花时间去创造些什么有价值的东西。

  • 你要开始学会使用各种政治手段。办公室政治不可避免,越大的公司越重,自从你开始成为一线的leader的那一天起,你就开始成为“里外不是人”的角色,需要在下属和领导,员工和公司之间周旋。随而你的级别越来越高,你需要使用更多的政治手段,你会学会审时度世的站队,学会迎合员工和领导,学会用官员的语言说话,学会此一时彼一时,学会妥协和交换,学会忍气吞声,学会在在适当的时机表现自己,学会波澜不惊,学会把自己隐藏起来,甚至你还会迷失自我,开始学会一些厚黑学,比如不得不在适当的时机在背后捅人刀子……你可能会成为一个你自己都讨厌的人

听上去真的好无聊,所以,你现在也明白为什么高层们都看上去很忙很累,而且抽不出时间来关心细节问题,因为,他们更多的是要协调整个组织和系统来运转,甚至还要四处周旋,各种博弈,没办法,这是职场的必需的东西!听起来是不是感觉人类很愚蠢?这真是没办法的事。如果你不想或是也没有能力玩这些东西,那么你需要去那些可以让技术人员安安心心做技术的公司。这类的公司,我见过Microsoft、Google、Amazon或是一些创业公司里都有。国内的大公司中也有让技术人员成长的职业成长线,但老实说,表面上看似是一个让人专心做技术的升职成长线,但其实还是管理岗位。

所以,技术人员在职场中的归宿有两条路 —— 到真正的技术公司成为一个专心做技术的人,或是在成为一个职业的经理人

二、追求人生的经历

先说三个故事,

  • 第一个,是在阿里的时候,有一天在内网里看到一个贴子,一个做产品的女孩说自己准备离职要去法国学烘培厨艺,引得大家热评。

  • 第二个,是在亚马逊的美国老板,他每年都要去报个培训班学一个技能,比如:厨艺、开双翼飞机、夜总会里的DJ……、甚至去华盛顿去学当一个政客。

  • 第三个,是在汤森路透工作时,一个英国的同事,有一天他说他离职了,和自己的老婆准备用余生去周游世界,我问他是不是有足够多的钱了?他和我说,钱不够,他俩口子的计划是,边旅游边打工,打工打够到下一站的钱就走。他还说,那种用假期去另一个城市的旅游太没意思了,如果你不在那个地方生活上一段时间 ,你怎么能算是好的旅游体验呢?好吧,无法反驳。

我是觉得他们把自己的人生过得如此有意思,令我很佩服。虽然跨界跨得有点猛,但是 Why Not?

在这里,我想说,去追求一种和众人不一样的人生经历也是一件挺好的事,我个人感觉,比起在职场里有趣地多多了。如果你厌倦了职场,其实为什么不去追求一下不同的人生经历呢。就算你不想去追求跨度比较大的人生经历,那么,在技术圈里,也有很多有价值有意思的经历也可以去的。追求刺激有意义的与众不同的经历的人,其实也能算是一种人生的成功,不是吗?

如果只说技术方面,我个人看到的去追求经历的人,有两种追求的人其实也很成功的:

  • 到技术创新的发源地去经历创新。计算机互联网各种技术的创新引擎,基本上来说,就是在美国了。我们赶上了这个时代,也选对了这个时代最火热的行业,那么,有什么理由不去这个时代的技术发动机那里去经历呢?在美国硅谷湾区,无论是大公司,还是创业公司,都在迸发着各式各样的创新,如果有能力有机会,为什么不努力去经历一下呢?不经历一下,老了不会觉得错过了是一种后悔吗?

  • 去经历下一个热点技术的发展。从IT,到互联网、再到移动互联网、云计算、大数据,再到未来的AI,VR,IoT……,技术创新的浪潮一波接一波的过来,你是想在那继续搬砖搬下去,是想迎浪而上去经历浪潮,还是想成为一个随波逐流的人?

打工也好,创业也好,在国内也好,在国外也好,这些都是形式,不是内容。内容则是你有没有和有想法的人去经历有意义有价值事?人生苦短,白驹过隙,我们技术人员最大的幸运就是生在这样一个刺激的时代,那么,你还有什么理由不去追逐这些前沿刺激的经历呢?

三、追求自由的生活

我相信“自由”这个事,是所有人的心中都会想去追求的。“生命诚可贵,爱情价更高,…… ”(哈哈)

但一说起自由,绝大多数人都想到的是“财富自由”或是“财务自由”,其实,并不完全是这样的,在自由的通路上,我个人的经历告诉我,其实,你会有很多的不同类型的自由。下面,是我对几个层次的“自由”的理解。

第一层自由——工作自由。人的第一层自由的境界是——“工作自由”,我到不是说你在工作单位上可以很自由,虽然有特例,但并不普遍。我想说的“工作自由”是——你不会有失业危机感了。也就是说,你成了各个公司的抢手货,你不但不愁找不到工作,而且你是完全不愁找不到好工作。试想一下,如果是工作来找你,一方面,你就有真正意义上的工作选择权了,另一方面,你都不愁工作了,你完全就可以随时离职去干你想干的事了。此时,你就达到了“工作自由”。

第二层自由——技能自由。工作自由已是不错,不过前提是你还是需要依赖于别人提供的工作机会。而技能自由则是你可以用自己的技能养活自己,而不需要去公司里工作。也就是所谓的自由职业者了,社会上,这样的人也不少,比如,一些健身体育教练、设计师、翻译者、作者……这些都可以算是自由职业者,程序员这个职业中只要不是搬砖的,有想法的,就有可以成为自由积业者的潜质,想一想,你拥有的编程能力,其实是一种创造的能力,也就是创造力,只要你Make Something People Want(YC创业公司的slogan),你是完全可以通过自己的技能来养活自己的。如果你通过某些自动化的东西,或是你在App上做了一个软件个体户,让自己的收入不断,甚至你做了一个开源软件,社区每个月都给你捐款捐到比你打工挣的还多,那么你就真正的有了技能自由了。

第三层自由——物质自由。我把财务自由换了一种说法。我个人觉得,除了有个好爸爸之外这种特例的情况,如果你想有物质自由的话,本质上来说,你一定要学会投资,投资不一定是你的钱,时间也是一种财富,年轻更是,你怎么投资你的时间还有你的青春?你要把你的投资投到什么样的事,什么样的人?对于投资这个事,风险也比较大。但是,人生不敢冒险可能才是最大的冒险。这个世界有很多技术不是你能看书学来的,而要只能在实战中学会的,比如:游泳。投资可能也是一种。只有真正懂投资的人,或是运气非常好的人,才可能实现物质自由。

追求自由的生活,其实也是个人发展道路上的一个不错的选择。通常来说,自由的人,能力都不差,钱也不会少。因为,他们懂得投资。

也就是说,拥有追求自由能力的的人,

  • 不但有领导力和创造力(也可指导大多数人并走在大多数人前面)
  • 同时他还懂得怎么投资(知道时间和精力和金钱应该投在什么地方)

(注:这里我没有提精神自由,老实说,精神上的自由我也不清楚是什么东西,因为我还没有见过,眼界有限,所以先按不表了,不然真成鸡汤文了)

总结

无论是在职场中打拼,还是追求精彩的经历,还是去实现自由,我觉得都是不错的个人发展的方向。

他们都有重叠,比如:

  • 你可以在职场中去追求那些刺激的经历的公司。
  • 同样也可以通过加入有潜力高速发展的公司来达到自由。
  • 你也可以通过追寻不一样的经历来达到人生的自由。
  • ……

总之,这里的逻辑是——

  • 能够去规划自己的个人发展的人,通常都是有很多机会和可能性的人

  • 有很多机会和可能性的人,通常都是有Leadership,喜欢冒险的人。

  • 有Leadership喜欢冒险的人,通常都是学习能力强,思维活跃,喜欢折腾,懂得“投资”的人。

  • 学习能力强思维活跃的人,通常来说,都是喜欢看书,喜欢实践和新鲜事物,不怕艰难和挑战,用智力而不是使蛮力的人。

  • 懂得“投资”的人,通常来说,他们更多的关注的是未来和长远的成长,而不是当下的KPI、奖金和晋升。

最后祝大家新年快乐,来年大展鸿图。

(全文完)

来源:酷壳

每年一到要找工作的时候,我就能收到很多人给我发来的邮件,总是问我怎么选择他们的offer,去腾讯还是去豆瓣,去外企还是去国内的企业,去创业还是去考研,来北京还是回老家,该不该去创新工场?该不该去thoughtworks?……等等,等等。今年从7月份到现在,我收到并回复了60多封这样的邮件。我更多帮他们整理思路,帮他们明白自己最想要的是什么。(注:我以后不再回复类似的邮件了)。

我深深地发现,对于我国这样从小被父母和老师安排各种事情长大的人,当有一天,父母和老师都跟不上的时候,我们几乎完全不知道怎么去做选择。而我最近也离开了亚马逊,换了一个工作。又正值年底,就像去年的那篇《三个故事和三个问题》一样,让我想到写一篇这样的文章。

几个例子

当我们在面对各种对选择的影响因子的时候,如:城市,公司规模,公司性质,薪水,项目,户口,技术,方向,眼界…… 你总会发现,你会在几个公司中纠结一些东西,举几个例子:

  • 某网友和我说,他们去上海腾讯,因为腾讯的规模很大,但却发现薪水待遇没有豆瓣高(低的还不是一点),如果以后要换工作的话,起薪点直接关系到了以后的高工资。我说那就去豆瓣吧,他说豆瓣在北京,污染那么严重,又没有户口,生存环境不好。我说去腾讯吧,他说腾讯最近组织调整,不稳定。我说那就去豆瓣吧,慢公司,发展很稳当。他说,豆瓣的盈利不清楚,而且用Python,自己不喜欢。我说,那就去腾讯吧,……

  • 还有一网友和我说,他想回老家,因为老家的人脉关系比较好,能混得好。但又想留在大城市,因为大城市可以开眼界。

  • 另一网友和我说,他想进外企,练练英语,开开眼界,但是又怕在外企里当个螺丝钉,想法得不到实施。朋友拉他去创业,觉得创业挺好的,锻炼大,但是朋友做的那个不知道能不能做好。

  • 还有一网友在创新工场的某团队和考研之间抉择,不知道去创新工场行不行,觉得那个项目一般,但是感觉那个团队挺有激情的,另一方面觉得自己的学历还不够,读个研应该能找到更好的工作。

  • 还有一些朋友问题我应该学什么技术?不应该学什么技术?或是怎么学会学得最快,技术的路径应该是什么?有的说只做后端不做前端,有的说,只做算法研究,不做工程,等等,等等。因为他们觉得人生有限,术业有专攻。

  • 等等,等等……

我个人觉得,如果是非计算机科班出生的人不会做选择,不知道怎么走也罢了,但是我们计算机科班出生的人是学过算法的,懂算法的人应该是知道怎么做选择的

排序算法

你不可能要所有的东西,所以你只能要你最重要的东西,你要知道什么东西最重要,你就需要对你心内的那些欲望和抱负有清楚的认识,不然,你就会在纠结中度过。

所以,在选择中纠结的人有必要参考一下排序算法。

  • 首先,你最需要参考的就是“冒泡排序”——这种算法的思路就是每次冒泡出一个最大的数。所以,你有必要问问你自己,面对那些影响你选择的因子,如果你只能要一个的话,你会要哪个?而剩下的都可以放弃。于是,当你把最大的数,一个一个冒泡出来的时候,并用这个决策因子来过滤选项的时候,你就能比较容易地知道知道你应该选什么了。这个算法告诉我们,人的杂念越少,就越容易做出选择。

  • 好吧,可能你已茫然到了怎么比较两个决策因子的大小,比如:你分不清楚,工资>业务前景吗?业务前景>能力提升吗?所以你完全没有办法进行冒泡法。那你,你不妨参考一个“快速排序”的思路——这个算法告诉我们,我们一开始并不需要找到最大的数,我们只需要把你价值观中的某个标准拿出来,然后,把可以满足这个价值的放到右边,不能的放到左边去。比如,你的标准是:工资大于5000元&&业务前景长于3年的公司,你可以用这个标准来过滤你的选项。然后,你可以再调整这个标准再继续递归下去。这个算法告诉我们,我们的选择标准越清晰,我们就越容易做出选择

这是排序算法中最经典的两个算法了,面试必考。相信你已烂熟于心中了。所以,我觉得你把这个算法应用于你的人生选择也应该不是什么问题。关于在于,你是否知道自己想要的是什么?

排序算法的核心思想就是,让你帮助你认清自己最需要的是什么,认清自己最想要的是什么,然后根据这个去做选择

贪婪算法

所谓贪婪算法,是一种在每一步选择中都采取在当前状态下最好或最优(即最有利)的选择(注意:是当前状态下),从而希望导致结果是最好或最优的算法。贪婪算法最经典的一个例子就是哈夫曼编码

对于人类来说,一般人在行为处事的时候都会使用到贪婪算法,

  • 比如在找零钱的时候,如果要找补36元,我们一般会按这样的顺序找钱:20元,10元,5元,1元。

  • 或者我们在过十字路口的时候,要从到对角线的那个街区时,我们也会使用贪婪算法——哪边的绿灯先亮了我们就先过到那边去,然后再转身90度等红灯再过街。

这样的例子有很多。对于选择中,大多数人都会选用贪婪算法,因为这是一个比较简单的算法,未来太复杂了,只能走一步看一步,在当前的状况下做出最利于自己的判断和选择即可。

有的人会贪婪薪水,有的人会贪婪做的项目,有的人会贪婪业务,有的人会贪婪职位,有的人会贪婪自己的兴趣……这些都没什么问题。贪婪算法并没有错,虽然不是全局最优解,但其可以让你找到局部最优解或是次优解。其实,有次优解也不错了。贪婪算法基本上是一种急功近利的算法,但是并不代表这种算法不好,如果贪婪的是一种长远和持续,又未尝不可呢?

动态规划

但是我们知道,对于大部分的问题,贪婪法通常都不能找出最优解,因为他们一般没有测试所有可能的解。因为贪婪算法是一种短视的行为,只会跟据当前的形式做判断,也就是过早做决定,因而没法达到最佳解。

动态规划和贪婪算法的最大不同是,贪婪算法做出选择,不能在过程优化。动态规划则会保存以前的运算结果,并根据以前的结果对当前进行选择,会动态优化功能。

动态规划算法至少告诉我们两个事:

1)承前启后非常重要,当你准备去做遍历的时候,你的上次的经历不但能开启你以后的经历,而且还能为后面的经历所用。你的每一步都没有浪费。

2)是否可以回退也很重要。这意思是——如果你面前有两个选择,一个是A公司一个是B公司,如果今天你选了A公司,并不是你完全放弃了B公司。而是,你知道从A公司退出来去B公司,会比从B公司退出来去A公司要容易一些。

比如说:你有两个offer,一个是Yahoo,一个是Baidu,上述的第一点会让我们思考,我以前的特长和能力更符合Yahoo还是Baidu?而Yahoo和Baidu谁能给我开启更大的平台?上述的第二点告诉我们,是进入Yahoo后如果没有选好,是否还能再选择Baidu公司?还是进入Baidu公司后能容易回退到Yahoo公司?

Dijkstra最短路径

最短路径是一个Greedy + DP的算法。相当经典。这个算法的大意如下:

1)在初始化的时候,所有的结点都和我是无穷大,默认是达不到的。

2)从离自己最近的结点开始贪婪。

3)走过去,看看又能到达什么样的结点,计算并更新到所有目标点的距离。

4)再贪婪与原点最短的结点,如此反复。

这个算法给我们带来了一些这样的启示:

  • 有朋友和我说过他想成为一个架构师,或是某技术领域的专家,并会踏踏实实的向这个目标前进,永不放弃。我还是鼓励了他,但我也告诉他了这个著名的算法,我说,这个算法告诉你,架构师或某领域的专家对你来说目前的距离是无穷大,他们放在心中,先看看你能够得着的东西。所谓踏实,并不是踏踏实实追求你的目标,而是踏踏实实把你够得着看得见的就在身边的东西干好。我还记得我刚参加工作,从老家出来的时候,从来没有想过要成为一个技术牛人,也从来没有想过我的博客会那么的有影响力,在做自己力所能及,看得见摸得着的事情,我就看见什么技术就学什么,学着学着就知道怎么学更轻松,怎么学更扎实,这也许就是我的最短路径。

  • 有很多朋友问我要不要学C++,或是问我学Python还是学Ruby,是不是不用学前端,等等。这些朋友告诉我,他们不可能学习多个语言,学了不用也就忘了,而且术业有专攻。这并没有什么不对的,只是我个人觉得,学习一个东西没有必要只有两种状态,一种是不学,另一种是精通。了解一个技术其实花不了多少时间,我学C++的目的其实是为了更懂Java,学TCP/IP协议其实是为了更懂Socket编程,很多东西都是连通和相辅相成的,学好了C/C++/Unix/TCP等这些基础技术后,我发现到达别的技术路径一下缩短了(这就是为什么我用两天时间就可以了解Go语言的原因)。这就好像这个算法一样,算法效率不高,也许达到你的目标,你在一开始花了很长时间,遍历了很多地方,但是,这也许这就是你的最短路径(比起你达不到要好得多

算法就是Trade-Off

你根本没有办法能得到所有你想得到的东西,任何的选择都意味着放弃——当你要去获得一个东西的时候,你总是需要放弃一些东西人生本来就是一个跷跷板,一头上,另一头必然下。这和我们做软件设计或算法设计一样,用时间换空间,用空间换时间,还有CAP理论,总是有很多的Trade-Off,正如这个短语的原意一样——你总是要用某种东西去交易某种东西

我们都在用某种东西在交易我们的未来,有的人用自己的努力,有的人用自己的思考,有的人用自己的年轻,有的人用自己的自由,有的人用自己的价值观,有的人用自己的道德…… …… 有的人在交换金钱,有的人在交换眼界,有的人在交换经历,有的人在交换地位,有的人在交换能力,有的人在交换自由,有的人在交换兴趣,有的人在交换虚荣心,在交换安逸享乐…… ……

每个人有每个人的算法,每个算法都有每个算法的purpose,就算大家在用同样的算法,但是每个人算法中的那些变量、开关和条件都不一样,得到的结果也不一样。我们就是生活在Matrix里的一段程序,我们每个人的算法决定着我们每个人的选择,我们的选择决定了我们的人生

(全文完)

来源:酷壳

我以前写过一篇“我是怎么招聘程序员的”的文章(在CSDN那里有很多人进行了回复)。今天,我想再谈谈关于招聘和面试这方面的东西,主要是以下这些原因:

所以,我很想把自己的这些新的想法再次写下来的。还是和以前一样,这篇文章同样是献给面试官的。我认为,面试的好坏完全在面试官而不是面试的人。下面是我对“我是怎么招聘程序员的”一文中的一些加强性的观点。(关于一些点评,请参看本文下篇

为了让我的文章有连续性,请允许我重申一下前文的几个重要观点。

  • 只有应聘者真实和自然的表现,才能了解到最真实的东西
  • 重要的不是知识,重要的是其查找知识的能力
  • 重要的不是那个解题的答案,而是解题的思路和方法

操作,知识,经验,能力

我们有很多的面试官似乎分不清,什么是操作能力,什么是知识,什么是经验,什么是能力,这导致了我们的面试官经常错误地对面试者下结论,我认为分不清这些事的人是没有资格做面试官的。所以,我有必要在这里把这个问题先讲清楚。

  • 操作

    。我们的面试官分不清楚什么是操作技能,什么是知识,他们甚至认为操作技能就是知识甚至经验。比如他们会 问如下的问题,请问Java中的 final是什么意思?怎么查看进程的CPU利用率?怎么编写一个管道程序?怎么查看进程的程序路径?VI中的拷贝粘贴命令是什么?包括面向对象的XX模 式是什么。等等。我以为,

    这些能够通过查况相关操作手册或是能够google到的东西只能说明这个人的操作技术,并不能说明他有知识或有经验

  • 知识。知识是一个人认知和学习的体现,可能会是一些基础概念和知识。比如这些问题:TCP和UDP的优缺点比 较,链表和哈希表的优缺点的比较。什么是堆什么是栈?进程间是怎么通信的?进程和线程的优缺点?同步和异步的优缺点?面向对象的XX设计模式的主要原则是 什么,等等。我以为,“知其然”只是操作技术,“知其所以然”才是真正的知识。知识不够并不代表他不能工作,会操作技能就可以应付工作,但是知识的欠缺一定会限制你的经验和能力,同样会影响你的开发质量。

  • 经验。经验通常跟一个人的经历有关系。一个人的知识范围,一个人经历过的事,通常会成为一个人经验的体现。面 试中,我们会问这些问题:你解决过最难的问题是什么?你是怎么设计这个系统的?你是怎么调试和测试你的程序的?你是怎么做性能调优的?什么样的代码是好的 代码?等等。对于工作年限不长的人来说,经历和做过的事的确会成为其经验的主要因素,尤其是业务上的有行业背景的东西。但是,我更以为,经验可能更多的是你对知识的运用和驾驭,是你对做过事情的反思和总结,是你对他人的学习,观察和交流

  • 能力。一个人的能力并不会因为知道东西少而不行,也不会因为没有经验而没有能力。一个人的能力是他做事情的一种态度,性格,想法,思路,行为,方法和风格只要有热情,有想法,有好的行为方法,以及好的行事风格,那么知识和经验对他来说只是一个时间问题。 比如:学习能力,专研精神,分析能力,沟通能力,组织能力,问题调查能力,合作能力等等。所以,对于一个新手来说,也许他的知识和经验有限,但并不代表他 能力上有问题,但是对于一个老手来说,如果其存在知识和经验欠缺的问题,那么通常都是其能力的问题。你可能暂时怀才不遇,但我不相信你会长期怀才不遇。如 果是的话,那么你必然些问题其让你的能力发挥不出来。而此时,“没有经历过”只会是你“没有能力”的一个借口。

我不否认这四样东西对于一个优秀的程序员来说都很重要。但是,通过上述的分析,我们可以知道,能力和经验和知识需要分开对待。当然,这些东西是相辅相成的,你的能力可以让你获得知识,你的知识可以让你更有经验,你的经验又会改变你的想法和思路,从而改善你的能力。在面试中,我们需要清楚的认识到,应聘者的操作技能,知识和经验只是其能力的必要条件,并不是充要条件,而我们更应该关注于应聘者的能力

  • 如果面试只是考查这个人的操作技能的话,那么这个面试完全失败。这是一个没有资格的面试官。
  • 如果面试只是在考查这个人的知识和经验的话,那么成功了一半。因为你了解了基础知和做过的事,但这并不代表你完全了解他的真正能力。
  • 如果你能够在了解这个人的知识和经验的过程中重点关注其能力(态度、性格、想法,思路,行为,方法和风格),并能正确地评估这个人的能力,那么你的面试算是非常成功的。

也许用这四个词来描述定套东西并不太合适,但我相信你明白我想表达的。另外,我想说的是,我们不是出个题来考倒应聘者,而是要找到应聘者的亮点和长处

不要肤浅地认识算法题和智力题

很多公司都会在面试的时候给一些算法题或是一些智力题或是一些设计题,我相信算法题或是智力题是程序员们在面试过程中最反感的事了。很多人都很BS面试官问的算法题,因为他们认为面试官问的这些算法题或智力题在实际工作当中用不到。但我想在这里说,问难的算法智力题并没有错,错的很多面试官只是在肤浅甚至错误地理解着面试中的难题的目的。他们认为,能做出算法题和智力题的人就是聪明的人就是有能力的人,这种想法实在是相当的肤浅。

其实,能解难题并不意味着这个人就有能力就能在工作中解决问题,你可以想想,小学奥数题可能比这些题更难,但并不意味着那些奥数能手就有实际工作能力。你可 以想一想你们班考试得高分的同学并不一定就是聪明的人,也不一定就是有能力的人,相反,这样的人往往者是在应试教育下培养出来的书呆子。

所以,我认为解难题的过程更重要,你要主要是通过解题查看这个应聘者的思路,方法,运用到的知识,有没有一些经验,和你一起交互时和沟通得是否顺畅,等等,这些才是你重点要去观察的。当然,最终是要找到答案的。

我想,让面试者解决一个难题的真正思路是:

  • 看看他对知识的应用和理解。比如,他是否会用一些基础的数据结构和算法来解决算法题?
  • 看看他的整个解题思路和想法。答案是次要的,他的想法和行为才是重要的。
  • 看看他是如何和你讨论交流的。把面试者当成你未来的同事,当成你的工作伙伴,一起解题,一起讨论,这样可以看看大家是否可以在一起工作。

这些方面才是考查应聘者的能力(思路,方法、态度,性格等),并顺带着考查面试者的经验和知识。下面是一些面试的点:

  • 应聘者在解算法题时会不会分解或简化这个难题。这是分析能力。
  • 应聘者在解算法题 时会不会使用一些基础知识,如数据结构和基础算法。这是知识。
  • 应聘者在解题 时和你讨论的过程中你有没有感到应聘者的专研精神和良好的沟通。
  • 应聘者在对待这个算法题的心态和态度。如,面试面是否有畏难情绪。
  • 应聘者在解题时的思路和方法是否得当,是否是比较科学的方法?
  • 等等。

在解难题 的过程中考查应聘者的能力才是最终目的,而不是为难应聘者,不然,你只是一个傲慢而无知的面试官

模拟实际中的挑战和能力

作为面试官的你,你应该多想想你的工作,以及你的成长经历。这会对你的面试很有帮助。你在工作中解决问题的实际情况是什么?你写代码的实际情况是什么?你的成长经历是什么?你是怎么获得知识和能力的?你喜欢和什么样的人工作?相信你不难会发现你工作中的实际情况和面试的情况完全是两码事,那么,你怎么可以用这种与实际情况差别那么大的面试来评估一个人的能力呢

所以,最为理想的面试是一起工作一段时间。当然,这个在招聘过程中,操作起来几乎不可能,因此,这就要求我们的面试官尽可能地把面试的过程模拟成平时工作的 过程。大家一些讨论来解决一个难题,和应聘者一起回顾一下他已经做过的事情,并在回础的过程中相互讨论相互学习。下面举一个例子。

我们知道,对于软件开发来说,开发软件不难,难是的下面是这些挑战:

  1. 软件的维护成本远远大于软件的开发成本。
  2. 软件的质量变得越来越重要,所以,测试工作也变得越来越重要。
  3. 软件的需求总是在变的,软件的需求总是一点一点往上加的。
  4. 程序中大量的代码都是在处理一些错误的或是不正常的流程。

所以,当我们在考查应聘者的代码能力时候,我们为什么不能模拟这样的过程呢?比如,让应聘者实现一个atoi()的函数,实现起来应该很简单,然后 不断地往上加新的需求或新的案例,比如:处理符号,处理非数字的字母的情况,处理有空格的情况,处理十六进制,处理二进制,处理“逗号”,等等,我们要看 应聘者是怎么修改他的代码的,怎么写测试案例的,怎么重构的,随着要处理的东西越来越多,他的代码是否还是那么易读和清晰。如果只是考查编码能力,一个小时,就问这一个问题,足矣。真正的程序员每天都在和这样的事打交道的。

如果要考查应聘者的设计能力,同样可以如法泡制。不断地加新的功 能,新的需求。看看面试者的思路,想法,分 析的方法,和你的讨论是否流畅,说没说在 点上,思想清不清晰,会应用什么样的知识,他在设计这个系统时的经验是会是什么样的,面对不断的修改和越来越复杂的需求,他的设计是否还是那么好?

当然,因为时间比较短,所以,你不能出太复杂的问题,这需要你精心设计一些精制的有代表性的问题。

在上篇中,我们说到了一些认识人的方法(操作,知识,经验,能力),还有一些面试的方法(算法题,实际生产活动中的挑战),下面我们来说说,面试的风格,还有一些点评。

把应聘者当成你的同事

有些公司的面试官,在面试过程中问你一个算法题,然后等着你解答了,如果你给出一个答案,然后就会问你有没有更好的答案,如果你给出了正确的答案,他们就会问你一个更难的问题,如此循环下去。他们基本上很少给你提示,甚至不停地质问你,挑战你,搞得应聘者很紧张。

另外,有很多问题是没有标准答案的,或者说是,同一个答案的描述方法有多种,很多面试官会觉得你没有回答到他想要的答案,因此表现得有对你不屑,并表现出你不行的样子,并觉得你的能力有问题。真是可笑了。比如我一个朋友在回答什么是异步的问题时,举例说明了异步调用就是不能处理完就返回,并且需要传递一个回调函数给调用方以便完成后回调通知结果。这样的回答并没有错,但是这并不符合面试官心里想要的答案,面试官对此并不满意,进而认为我这个朋友还需要去多读读书。

我相信大多数面试官都会这样干的。我想问问这样的面试官,你们有没有用面试的方式对过你的同事?在你的工作场景中,你会不会用面试的风格和你的同事进行交流和说话?不妨让我们来问我们自己下面几个问题:

  • 你在工作当中遇到难题时你是怎么解决的?你会和人讨论吗?你只用15分钟就能得出最优解吗?
  • 你在工作当中解决难题时是否会有一个人在旁边质问你并给你压力吗?
  • 你在工作当中会为难你的同事吗?会让你的同事紧张吗?你觉得在紧张的状态下能做好工作吗?
  • 你在工作中觉得同事的回答并不是你想要的答案,不是符合你的答案,你会认为你的同事不行吗?
  • 你的成长过程是什么样的?在是压力和天天被人质问的情况下成长的吗?
  • 大家都知道学校里应试教育的弊端,你觉得你的面试是不是一种应试呢?

(看看这么多的应聘者们都在做各种各样的算法题,这不就是一种应试吗?)

想一想你的日常工作,问自己一下上面这些问题,想一想你自己的成长过程,想一想你和你的同事是怎么相处的,想一想你的日常工作中是什么样的,相信你自己也能得出结论的。

如果你把应聘者当成自己未来的同事,那么你的面试会有下面的收获:

  • 面试的气氛会很不错,应聘者会放松,表现自然,更接受于真实的状态。
  • 面试中的交流和互动(而不是一问一答)会让你更全面的考查和了解一个人。
  • 非应试的面试,会让你了解得更多。
  • 真实的了解一个人,你才能做出真正正确的结论。

向应聘者学习

下面有几个观点

  • 面试的过程是一个相互学习的过程,并不是你为难面试者的过程。
  • 一问一答是很一种呆板死板的过程,相互讨论相互学习,有良好的互动才是好的面试过程。
  • 面试官要证明的不是你有多强有多聪明,而是要挖掘应聘者的优势和能力。
  • 面试官用为自己的问题预设好一个标准答案,看看应聘者能为你带来什么。
  • 向来应聘的人学习,而不是刁难。

无论你多牛,要难倒你实在是太容易了。出难题不是目的,难倒人也很容易,出难题只不过是用来了解应聘者能力的一个手段,而不是面试的全部

我不知道你喜欢不喜欢一些竞技类的运动?比如踢球,打篮球,羽毛球,下象棋等,你一般想和什么样的人玩?是差的,还是强的?所以,能够从面试者那里学到东西,喜欢和面试者一起工作,这才是面试真正的目的

对于一个团队来说,如果大家都是一样的想法,一样的主张,一样的倾向,那么这个团队最终会是一个闭塞的团队,你如果不能真正接纳不同想法的人,不同主张的人,那么你也将失去进步的机会。如果你的团队总是在招入和你一样的人,那么你的团队怎么可能会有out-of-box的想法呢?世界因为不同而美好

另外,对于公司来说,如果你招进来的人还不如已经有的人,作为一个公司,你又怎么能有更好的人让你的公司进步呢

所以,面试应该是向面试者学习的一个过程。当然,如果你从他身上学不到什么,那么你就教他一些吧。这样,就算是面试不通过,面试者也会欣然接受的。不然,让面试者产生一些负面情绪,出去说一些不好的话,也有损你和公司的形象。

一些相关的点评

下面是我根据酷壳的一些面试题的文章后的回复、还有我朋友的经历,还有这篇有关豆瓣的产品经理的这篇文章的一些点评。大家可以看看我从这些地方看到东西靠不靠谱。

酷壳的面试题中的答复

先说酷壳的那篇“火柴棍式的面试题”,这个面试题其实很没什么意思。主要考查你对代码逻辑的了解程度。因为设置了回复可见答案,所以这篇文章的回复量达千把条。从回复中,我看到:

  • 一些朋友想不出来就直接看答案了。我可以看出,有一些朋友习惯获得知识,而不习惯独立思考。甚至有畏难情绪,从另一方面来说,可以看出我国的教育还真不是一般的差。
  • 一些朋友想不全。从这点来看,我觉得很正常,尤其是想出两种来的,我可以感觉到他们的努力思考了,可能还做了一些尝试。挺不错的。可惜我看不到你思考的方式,是在纸上画了画,还是编译了个程序跑了跑,还是别的什么。这样我会了解你更多。
  • 一些朋友给出的答案中有错的。这说明了这类朋友可能不喜欢做测试,时常想当然,或是做事比较冲动,并不足够严谨。这么简单的程序,验证能花多少精力呢?
  • 还有少数的朋友没有看明白题目要求。这说明了这类朋友太粗心了,在工作当中可能会表现为误解需求和别人的话。沟通有问题。

再说说那篇“火车运煤”的问题,这个面试题我觉得主要是看看大家的解题思路,表达能力。

  • 首先,我很惊喜有人很快就用数学做了解答,很不错,这个人的数学功底很不错。能用数学解题的人一般来说都是算法比较强的人。
  • 有人说抱怨我没有说火车可以调头回去,所以没有想到这样的方法。如果是在面试中我会做提示的。我不会因为你不知道调头这个潜规则而否定你的。当然,如果你能想到的话说明你的脑袋还是比较灵的。
  • 还有很多人说他的方法比较土,只运了400吨煤,416吨的或333吨,一看就是没有看提示的,我觉得这些人能够通过独立思考找到方法,这类的人其实已经不错了。顺着这个思路优化也只是时间的问题了。
  • 更可喜的是,我看到了有一些朋友在看到别人的更好的方法后和自己的方法进行了比较,并找到了为什么自己的方法不如他的原因。这样的人我认为是懂得“总结”和“比较”的,这样的人总是在不断地学习和改善自己的。
  • 还有人说到了动态规划,如果是在面试的时候,我很想向这位朋友学习一下用动态规划来解这题。
  • 还有朋友说到了火车调头只能在有站的地方。这个朋友一看要么就是搞需求分析的人,要么就是较真的人。需要进一步了解。但不管怎么样,这样的朋友的观察能力是很不错的。
  • 还有一些朋友给出的答案是正确的。但是表达方面比较复杂,有些没有看懂。可见,解题 的能力是有的,只是表达能力还有待提高。

豆瓣产品经理的面试

再说说豆瓣上的这篇文章,那篇文章里,面试官问了一个比较大的问题,那是仁者见仁,智者见智的问题,并且面试官并不满意应聘者给出的答案,并在用其主观意识强加一些东西给应聘者,并不断地和应聘者纠缠。后来,面试官回复到“重点测了两个问题:一是判别事情的标准和方法;二是在多种PK下产品经理的压力反应”。

下面是我观察到的:

  • 其一、这种似事而非的仁者见仁,智者见仁,一万人有一万个答案。所以,这种怎么答都可以的问题是很难有标准的,我认为豆瓣的面试官以这种问题来考查面试者的标准太有问题了。更好的问题是:比较一下新浪和twitter这两个产品。
  • 其二、多种想法PK的压力反应。这点没有问题,如果有机会我想问问这位面试官,豆瓣产品经理们的PK各自的想法时是以这种纠缠的方式吗?如果是这样的话,那我很为你们担忧啊。
  • 其三、很明显,应聘者不知道面试官想说什么,所以应聘者总是给出一些模棱两可的回答。回答得很政客,呵呵。
  • 其四、问的问题都是一些假设性的问题,假设技术人员不可沟通。人家说了,还没有见过不能沟通的情况。结果还要继续追问。这样你既要观察不到你想要的,也搞得大家不愉快。更好的问题的:“请你给一个你和一个很难沟通的人沟通的示例”,或是当应聘者说了“坚持己见”的时候,也应该追问“能给一个你坚持己见的例子吗?”。
  • 其五、整个面试过程完全是在谈一些虚的东西,就像天上的浮云,一点实实在在的东西都没有。比如下面这两个实实在在的问题:“你以前设计过什么产品?”,“你和你的技术团队是怎么合作的?”

这是一个完完全全失败的面试,这个面试官根本不懂面试,甚至工作方法也可能很有问题。也许他只是想找一个能够在工作中附和他的人。

朋友的面试

最后说说我那个朋友的面试,我的这个朋友学习能力很强,也很好专研,工作中解决了很多很困难甚至很底层的问题。他做软件开发时间并不长,但是他对这个行业很有热情,也很执着,并有着相当不错的技术功底。这天他遇到了一个面试官,根据朋友的描述,这位面试官,主要问题了三个问题,一个是关于异步的,一个是关于性能调优的,还有一个是关于学习能力的。

  • 问到异步的问题,我这个朋友说到了多线程中的异步调用,但是他可能问的是网络或是业务中的异步,要不然就是Linux 内核中的异步,当然他也没有说清楚,但他很不满意我朋友的答案,并让我朋友回去多看看书。
  • 问到性能调优的问题时,我这个朋友说了性能调优分三级,业务级,指令级和CPU级,并举例说了使用了一个叫VTune的性能分析工具。面试官却说原来你只懂Windows,有点不屑,并说他只会使用商业工具,更不屑。
  • 当我朋友向他澄清问题时,面试官只是摇头,叹气。并在应聘者作答的过程中不断的打断对方。

我的看法如下:

  • 对于异步来说,我认为这是一种设计或是一种想法,可能会有很多种不同的实现方式,在不同的场景中会有不同的用法。面试官并没有考查应聘者对异步方法的理解,也没有考查异步方法可以用来解决什么,异步方法的优势和劣势,等等。只是觉得应聘者没有给出他想要的答案。
  • 对于性调优的问题,我认为应聘者的思路和知识都很不错,还有使用VTune的经验。无论使用Windows还是Linux,无论使用商业的还是开源的Profiler,很多东西都是相通的,怎么能够因为这个东西不对自己的口味而下结论。为什么不向人家学习一下VTune呢?使用工具只是操作技能啊。
  • 面试官应该是用微笑来鼓励应聘者的,而不是用摇头和叹气,频繁打断对方也是一个相当不好的习惯。看来这个面试官很不能接受不同的东西。

这位有很不错的技术能力的人,看来并不适合做一个面试官,因为他面试的东西都只在知识层次,而且这位面试官有强烈的喜好和倾向,所以,他必然会错过那些有能力但并不合他口味的人。

哎,面对这样的面试官,大家伤不起啊!

(全文完)

来源:酷壳 酷壳