20160213153939本文译自Linkedin,作者 Ambra Benjamin。

作为一个面试官,拒绝人是我们工作中最糟糕的部分。相信我,就像求职者害怕接到拒绝电话一样,我也害怕打出这样的电话。虽然你也会遇到一些公司会详细解释原因,但多数情况下,你得到的将是简单的拒绝电话或者邮件,没有更多的详细解释。求职过程中你投入了不少精力和时间,结果却让人失望。但它们总归是有原因的。

不管你信不信,不解释被拒的原因总归是有合理的含义的。在一个热爱争论的社会,尤其是 90年 代后期 20 世纪初,企业为保护利益是高度敏感的,因此,许多企业给求职者的拒信上拒绝填写详细信息。很多企业不想做任何可能把企业置于负面的事情。企业不提供任何信息,这样一来前雇员就不能因为没有获得工作而批评他们,也不会对事情产生误解。即便是面试官一句简单的 “你不符合团队的文化”,都可能引起失望的求职者的一系列质疑。在我看来,任何时候,团队文化都是一个难以讨论清楚的概念。

面试者方面也有原因。对面试者来说,对面试结果进行反馈是个很容易掉进坑里的事情。很多时候面试的结果是相当主观的。技术或程序类面试,有比较清楚的正确或错误,但其它时候,我发现关于什么是正确答案具有很强的主观性。我面试过的求职者曾经用我发给另一个软件工程师的代码和我争论对错。一个求职者被拒可能有很多原因,很多原因并不是求职者想听到的。我发现,10 次中有 9 次,当我向求职者反馈了他们的面试结果后,他们变得非常有防御性,话题也变成他们试图证明我的观点是错的。如果把一个人的争论时间乘上面试的人数,每天我们就别指望能干别的了。

当求职者成熟而专业时,我通常会慎重地稍微给他们一些反馈,因为我们知道他们能够接受。有些面试者我们希望在给他们反馈后,下次他们能够有明显的提高和改进。但不幸的是,大多数人不能很好地接受反馈意见。这可能和文化有关,也可能和我们的教育有关。和求职者争论面试结果的正确与否显然不是个好主意。在我所从事的科技领域,有些公司为了防止求职者在 LinkedIn 上反复向面试官发邮件争论面试结果,甚至不会提供面试官的姓氏信息。现在信息渠道非常多,Twitter , Medium , Glassdoor , Reddit ,  Quora 等等,你不会知道求职者会在什么渠道发表对于面试的抱怨。

我很理解人们在倾注了精力后,很想知道面试结果却又得不到的失望。你要了解到,你之所以得不到面试结果,很大程度上是因为多数不专业的求职者毁掉了少数求职者本可以拥有的权利。所以当你发现自己属于能够接受面试结果的少数时,我的建议是不论是否满意面试结果,简单地说一句 “感谢您的意见” 就好。面试本就是不完美的过程。

原创文章,作者:Yuri,如若转载,请注明出处:http://36kr.com/p/5043247.html

转载自:http://mp.weixin.qq.com/s?__biz=MzA5OTAyNzQ2OA==&mid=401368207&idx=1&sn=6bb2b3fe6ece8f41e7f2e2a54f52e46c&scene=1&srcid=0113d03chnJkdvhm86dmBSyW#rd
2016-01-13 杨润青 译  Docker

在这篇文章中我们将会探讨2个主流的Docker编排框架:AWS的ECS(Elastic Container Service)和Google的Kubernetes。

3个月前,我们在nanit.com希望选择一个合适的Docker编排框架,ECS成为了我们的首选,毕竟,我们对AWS的服务较为熟悉,并且我们的基础设施都是建立在AWS的。经过一段时间的测试,我们发现ECS并不成熟,缺少一些我们需要的关键功能,因此我们开始尝试其他的框架:Kubernetes。令人意外的是,Kubernetes非常成熟,几乎支持我们需要的所有功能。对于我们来说,Kubernetes在ECS的主场完胜了ECS。接下来,就让我们一起来看看Kubernetes赢在哪些方面。

注意:ECS一直在更新,我们会尽可能的跟进这些内容,但部分内容可能被忽略了,希望读者不要介意。

构建集群(Cluster Setup)

ECS:为了启动一个ECS集群,用户需要设置一个Auto Scaling Group。用户可以编辑user-data来将EC2实例添加到指定的ECS集群上。当ASG被设置,实例启动之后,用户可以在ECS控制台看到这部分内容。现在,用户可以开始进行task-definition,方式类似于Docker-compose。

Kubernetes:想要在AWS上启动一个Kubernetes,用户需要先启动一个具有一定权限的EC2实例(通过IAM)。这将会创建多个AWS constructs来支持你的集群:VPC、ASG、一些安全组(Security Groups)和一个Kubernetes主实例。集群需要几分钟来启动,之后用户就能够在上面运行自己的容器。

比较结果:使用这两种框架来启动一个集群都非常的简单和友好。

启动基础服务(Basic Service Setup)

我们的任务是启动一个Nginx 镜像,并且让其他人能够访问这个Web服务。

ECS:首先,我们需要创建一个ELB(Elastic Load Balancer),它负责80端口的转发。然后,我们需要创建一个task-definition,它负责在80端口上启动一个Docker镜像。最后,需要创建一个Service,它会显示出有多少实例会同时运行。我们需要将它绑定到我们之前创建的ELB上。

Kubernetes:首先需要创建一个Replication Controller,它会显示出我们希望运行的Docker镜像和有多少镜像会同时运行。之后,我们需要创建一个Service object,这会启动一个ELB并且将ELB的流量转发到对应的容器上。

比较结果:Kubernetes的方式更舒服一些,更简洁。用户并不需要手工启动或者管理ELB。Kubernetes会完全负责管理:当用户创建了一个service,一个ELB会自动创建;当用户删除了一个service,它会自动从AWS上删除。

服务发现(Service Discovery)

当你使用了微服务架构和Docker,一个好的服务发现解决方案是至关重要的。Docker容器总是在不同虚拟机中迁移,用户必须有一个可靠的方法来发现在集群内和集群外的服务。

ECS:ECS并没有提供任何服务发现的解决方案。我能想到的最好方法就是构建一个内部加载平衡器(internal load balancer),并且将每一个service附加到一个平衡器上。平衡器的host name不会被改变,然后你就能够利用这个host name来作为服务的端点。其他的方法还有集成一个外部的程序,比如Consul。

Kubernetes:我认为这是Kubernetes的亮点之一。Kubernetes内置了一个完全的解决方案。它是一个插件,因此用户可以选择是否使用,但我强烈建议使用。它能够和namespace一起很好的工作。简单来说,当你创建了一个Kubernetes服务,比如说叫做redis,你就能够在集群的任何地方引用redis这个名字,即便是跨虚拟机。这就像是让docker网络跨越了特定的虚拟机,连通了整个集群。Namespaces允许你将多个服务归纳到一个具有逻辑的组中。现在假设我们有两个命名空间,分别是production和staging,他们都包含有一个redis的服务。一个在production命名空间下的容器可以通过redis来引用在production命名空间下的redis服务,同样的,在stagin命名空间下的容器也能通过redis来引用到位于stagine命名空间下的redis服务。这种自动化识别使得用户不需要花费时间去配置信息就能够构建一个隔离的环境,并且你可以随意在所有的命名空间中使用redis来引用对应的服务,接下来kunernetes会为你自动解析它们。

比较结果:毫无疑问,Kubernetes小胜一局。使用Kubernetes,用户完全不用关心服务发现的事情,全部交给Kubernetes来做就好了:)

部署(Deployments)

当我们升级一个服务的时候,即便还在部署,我们也想要确保它百分之百能用。我们的测试包括一个简单的NginX服务和一些简单的静态网页。我们启动了一个并发为30个请求的负载测试,并且在负载测试期间,我们会对该服务进行升级。

在部署期间,我们发现ECS丢失了比Kubernetes更多的请求。其中,Kubernetes丢失了0-2个请求,而ECS丢失了9-14个。

比较结果:说实话,我对ECS非常的失望。同样,我也对Kubernetes表示失望,但是它至少比ECS好多了。值得注意的是,Kubernetes 1.1.1版本应该会对轮询升级机制(rollong update mechanism)进行改善,还有一些其他的系统系能提升,这些改进都会使得这些数字变得更好看。

持久卷(Persistent Volumes)

我们经常需要挂载一些持久性的文件系统到一个指定的容器上,MySQL就是一个典型的例子。

ECS:ECS支持Docker原生的解决方案——用户可以启动一个数据容器,然后使用volumes-from命令来挂载它到其他容器上。就拿MySQL来看,你首先需要设置一个mysql-data容器,这个容器仅仅拥有一个数据卷。然后设置另外一个mysql-db容器,这个容器使用volumes-from命令来挂载之前创建的数据卷容器。这个方法看起来不错,但是它是host-sepicific的,这意味着你的mysql-db容器不能够在主机之间移动。你必须指定mysql-db容器在哪一个主机上运行,以此来防止容器被重新分配到其他主机上,最终失去了持久性。

Kubernetes:除了从一个指定的主机上挂载数据卷,Kubernetes还提供了一个选项:挂载一个EBS(Elastic Book Store)数据卷。这意味着一个容器的持久性存储可以在多个不同的虚拟机之间保留。你再也不需要强制你的MySQL容器必须运行在哪一个具体的虚拟机上。

注意:EBS同一时间只能被一个虚拟机挂载,这意味着如果有一个服务,它有两个运行在不同虚拟机的容器,他们将不能够挂载和共享这个EBS。

比较结果:即便Kubernetes的EBS挂载有一定的限制,但它依旧非常的独特和有用。

健康检查(Health-Checks)

确保拥有足够的服务容量是高可用性和冗余性的核心思想。健康检查就是用来确保服务不仅仅是运行的,并且它们还是健康和可操作的。

ECS:ECS使用ELB(Elastic Load Balancer)健康检查,这种方式有三个主要的缺点:

  1. ELB健康检查仅仅限于HTTP/TCP检查
  2. 如果你想要对一个不开放TCP端口的服务进行检查,这是不行的。仅仅是为了能够进行健康检查,你就必须运行一个HTTP/TCP服务器。
  3. 即便你拥有一个支持HTTP/TCP的服务,你还需要创建一个ELB,并将它绑定到这个服务上,这样才能进行健康检查。

Kubernetes:除了基于HTTP/TCP的健康检查,Kubernetes还提供了一种叫做Exec的方式。Exec可以让用户在容器中运行命令。如果命令结束,并且返回0则表示这个服务是健康的,否则这个服务很可能是不健康的,它会被其他的实例所替换。

比较结果:Kubernetes的方式更灵活,更简单配置。用户并不需要去启动一个冗余的HTTP/TCP服务器仅仅为了进行健康检查,并且即便服务没有绑定ELB,你也可以对它们进行健康检查。

端口管理(Port Management)

从我们的上篇文章中可以看出,端口管理在Docker中是比较困难的。我们想通过一个简单的例子来说明Kubernetes如何比ECS更优雅的解决了这个问题。我们拥有一台虚拟机和两个监听80端口的网站。我们不能够在同一个虚拟机上开2个80端口,因此我们需要寻找一个方法来解决这个问题。

ECS:用户必须手工确定两个服务没有使用同一个端口。我们只有一台虚拟机,因此只能运行一个开放80端口的容器。当我们想要开启第二个开放80端口的容器时,这是不行的,因为我们没有多余的虚拟机了。也就是说,能够开放多少个x端口的服务取决于拥有多少个虚拟机。在小型集群中,这是非常容易满足的条件,但是当你的服务数量变得越来越多时,这将成为一个头疼的问题,因为当你想要扩充容器时,你必须确认你还有足够的端口。

Kubernetes:Kubernetes非常优雅的解决了这个问题。它为每一个虚拟机上的容器都分配了一个随机的端口。然后它创建了2个ELB,一个将80端口转发到容器A的随机端口上,另外一个转发到容器B的随机端口上。一个内部的路由机制会负责将数据包转发到对应容器端口。

比较结果:Kubernetes使用虚拟端口的方式代替绑定原始端口的方法,很好的解决了这个头疼的问题。

记录(Logging)

没有什么系统不需要记录功能。

我从没有想过记录会成为一个大问题,但能够为你解决问题令我非常的高兴,即便这个问题非常简单。我们之前提到Kubernetes提供了一个服务发现的扩展功能,在这里,我想说的是记录的扩展功能。它含有两个不同的记录和度量收集(metric collection)的机制。第一种是著名的ELK方法,ELK会收集容器的所有记录,并且能够让用户通过Kibana接口来查询和可视化这些记录。第二种是InfluxDB,它使用Grafana作为可视化工具来查询系统信息,如CPU和内存使用情况。

比较结果:Kubernetes的扩展功能更胜一筹。当然,你会说我并不需要这些扩展,系统也能很好工作,但是,它们效果如此之好,并且能适用于99%的用例,为什么不使用呢?ECS并没有提供内置的记录功能,用户想要集成一个进去并不是很困难,但是这些并不能和Kubernetes提供的功能相提并论。

未知的云平台(Cloud Agnostic)

其实,Kubernetes和ECS之间并不存在竞争:)

ECS会专注于AWS平台,如果你已经在ECS上构建了你的基础架构,当你想要转移到其他云平台时,你将会遇到很多困难。

Kubernetes适用于多个云平台。你可以在AWS,Google Cloud,微软的ZURE,Rackspace等等上运行你的集群,并且运行效果或多或少都是相同的。在这里,或多或少指的是有一些功能只有部分云供应商提供。你必须确认你选择的新供应商能够支持Kubernetes中使用的功能,至少确保迁移是可能的。

开源软件(OSS)

Kubernetes是开源的项目,而ECS不是。这意味着,所有的一切,从源代码到未来的发展路线都是对你开放的。发现了漏洞?你可以创建一个issue或者直接提交一个pull 请求来修复它。新的功能会被添加到每一个新版本,其中的贡献人数和pull请求是惊人的。

ECS有着不同的性质,我不能够在网上找到关于它未来发展路线的规划。你不能够获得一个漏洞和issue的列表,你必须深入到论坛上去寻找想要的答案。并且你寻找的答案往往都是缺乏实际的,并不能够提供任何帮助(https://forums.aws.amazon.com/message.jspa?messageID=664865#664865)。也许这仅仅是因为我个人的糟糕经历,但是不管怎么说,这都是令人烦躁和失望的。

比较结果:就我个人而言,我更喜欢开源软件。我喜欢Kubernetes的开放性,每个人都能够参与讨论和贡献代码。我相信社区的力量会给我们带来一个更好的产品。

多可用区域(Multi-AZ)

当谈论到Kubernetes时,有一件事情困扰着我:它不支持AWS上的多可用区域集群(multiple availability-zones cluters)。这意味着所有EC2实例都集中在一个AZ上,这使得你的集群很可能会遭受到中断问题。

ECS有对Multi-AZ有很好的支持。

比较结果:在Kubernetes的issue上,已经有一些工作正在进行。我十分确定下个版本会很好的得到改善。因此ECS在这一点上的胜利并不会长久。

总结

很多公司都开始使用Doker作为他们的主要基础设置,传递机制(delivery mechanism)和编排框架(orchestration frameworks)成为了系统的核心,并且影响着我们开发,迁移,运行,升级的方式。当我想要比较ECS和Kubernetes时,我找不到类似的文章。所以我认为把我们的经验公布出来非常的重要,这样其他人能够站在我们的肩膀上看的更远。

对于nanit.com来说,Kubernetes毫无疑问获得了胜利。如果你有任何的异议,请告诉我理由,我非常想要知道这些内容:)

转载自:http://www.techug.com/how-to-plan

k1

不久前我发表了一篇文章,“月薪3万的程序员都避开了哪些坑”,在我的微信订阅号“程序视界”、CSDN博客、简书等平台都受了非常广泛的关注,点击量和评论出奇的多。有一些朋友觉得很难做到,其实,月薪3万是可以一步一步谋划出来的。个中关键,从大的方面来说,有两点:

1. 个人商的挖掘与修

2. 职业机会的探索与把

在展开之前,我们需要先澄清三个问题:

  1. 商业价值包含哪些因素
  2. 职业机会包哪些要素
  3. 内生涯与外生涯是什么

本文整体上分为两部分,第一部分,是和大家一起弄明白上面三个概念;第二部分,我们会一起研究如何通过商业价值的挖掘、内生涯的修炼以及职业机会的寻找来实现薪水月薪3万的目标。

本文为万字长文,如果你没耐心看这么这么多干货,可以跳转到最后,那里有一个归纳总结,是压缩饼干式的超级干货,可能合你的胃口。

的基本概念

小米在发展过程中,挖过两个比较著名的人物,一个是谷歌Android副总裁胡戈·巴拉,一个是新浪总编陈彤。我们来看两个问题:

1. 小米看上了这两个人什么?

2. 这两个人看上了小米什么?

商业价值要素

胡戈·巴拉身上有几个很有价值的点,这是他能加盟小米的关键:

1. 在谷歌工作5年

2. Android产品管理副总裁

3. Android操作系统团队最具代表性的公众人物之一,他曾经频繁出席谷歌的新闻发布会以及谷歌的I/O开发者大会。比如Nexus 7平板电脑就是由他登台演示。

4. 熟悉海外市场

相信这也是小米看中胡戈·巴拉的重要原因。而这些原因,其实就是胡戈·巴拉身上体现出来的商业价值。具体来看,谷歌的工作是其个人经历,为其积累了广泛而有价值的人脉,同时他也在Android产品管理方面有独到的知识技能

好啦,注意我加粗的四个关键词,这就是个人商业价值当中的四个要素。

个人商业价值中还有非常非常重要的一个要素,那就是是天赋。天赋指人与生俱来的某些特质。在胡戈·巴拉身上来讲,人际交往能力和个人形象气质就属于天赋。在姚明身上,他的身高算是天赋之一种,特别有助于他的蓝球事业。在罗纳尔多身上,他的爆发力就是天赋,所以你经常看到他突然加速把对方球员摔在身后然后狂奔几十米形成单刀射门的优势。如果一个人能发挥其天赋,将其与职业关联起来,必能自我实现,有所成就。

总结一下,商业价值包含五个要素:

  • 知识
  • 技能
  • 天赋
  • 经历
  • 人脉

我们每个人身上都有这些东西,如何挖掘出来,如何着重培养某方面的价值,就是我们能不能获取高薪水的关键。

职业机会

现在我们看看胡戈·巴拉为什么会选择小米。我猜测有这么几点:

1. 小米处在中国这个经济快速增长的发展中国家

2. 智能手机的发展在中国处于上升期

3. 小米公司上升势头强劲

4. 负责小米国际业务拓展

5. 薪水可观

第一点是很宏观环境的东西,只有宏观环境足够好时,机会才会多。这也是为什么现在小米等手机厂商发力印度的原因。

第二点是产业环境,在一个好的宏观环境里,一个好的、处于快速发展期的产业是最有吸引力的,到这样的产业中去,个人必将随着产业的发展而有所成就。所谓站在风口上猪都能飞起来,就是这个道理。

第三点是可以说是组织环境,一家处在好的宏观环境下好的产业环境里的公司,又正处于上升期,对个人来讲,是天赐良机啊。到这样的公司里,你就是躺着不动都可能比一般人达到的高度高。

其他都是小米提供给胡戈·巴拉的职位相关的东西,属于职业资源。另外还有一点,是八卦了,据说胡戈·巴拉的前女友阿曼达·罗森博格曾与布林交往,这也可能是胡戈·巴拉从谷歌离职的原因之一。这一点其实关系到的是家庭环境,一个人的家庭,可能成为他选择新职业的助力,也可能成为阻力。比如有很多学生毕业后就被父母通过人脉安排到银行、电力等国有企业工作,如果他们要跳槽,父母一般都会成为阻力。

好啦,现在职业机会的五个要素都出来了:

  • 宏观环境
  • 产业环境
  • 组织环境
  • 职业资源
  • 家庭环境

陈彤的事儿我们就不说了,咱得赶紧看内生涯与外生涯了。

内生涯与外生涯

内生涯与外生涯是职业规划中非常重要的一组概念,理清了它们,我们就知道在哪个方向上努力可以提升自己,进而提升薪资待遇。

内生涯与外生涯,最直接的区分,就是用你的身体,我们常说的身外之物,其实就是外生涯。我们常说的内在,就是内生涯。比如你现在是华为的软件工程师,负责相机模块开发,月薪20K,这属于外生涯;而你熟悉C++、Android的Camera框架、图像处理算法,这些就属于内生涯。

属于外生涯的那些身外之物,是别人、别的组织给予你的,很容易因为外界环境的变化而被剥夺。比如你曾经是诺基亚北京研发中心的开发人员,那2014年8月份诺基亚北京研发中心大裁员,你就会瞬间失去这个身份。

而我们归属于内生涯的那些内在之物,一旦拥有,就是你的,别人很难夺走。比如你掌握C++这门语言,熟悉了Android应用开发框架,精通数据库调优,你工作负责,为人诚信,勇于担当,这些知识或技能或心态,别人不可能从你这里拿走(除非他有黑衣人的记忆消除棒或者他是吸血鬼日记里的斯特凡或达蒙,拥有擦除记忆的法力)。

现在对内生涯和外生涯我们应该比较清楚了,那我们来总结一下它们都包含哪些内容。

外生涯包括(但不限于)职务目标、经济收入、工作内容、工作环境、工作时间、工作地点、企业文化、薪酬福利、通勤状况等。

内生涯包括(但不限于)知识、技能、工作经验、心理素质、内心情感、行为习惯、视野、观念、职业心态(爱与感恩、责任、忠诚、诚信、勇气、担当)、职业成熟度、心灵成长等。

如果你仔细品味内生涯包括的东西,就会发现,它们和个人商业价值的某些要素是重叠的,尤其是知识、技能、天赋这些东西。而外生涯包含的一些东西,其实也和个人商业价值相关,比如你的职务目标、工作内容、工作过的企业等,都是你的经历。你在选择一份新的职业时,不论内外,只要能体现商业价值的内容,都会被重度参考。

内生涯与外生涯的关系

我们知道了内生涯和外生涯都包括哪些内容,接下来就是它们之间的关系,弄明白它们之间的关系,就可以导出如何规划自己的职业发展与方向了。

内生涯和外生涯包含的一些东西,既可能是企业选择你的依据,也可能是你选择新职业时的目标,影响你的职业选择。比如你在22~24岁时可能更看重知识、技能、工作经验的积累,积累到一定程度,你的职务目标、薪酬就会自然上升,工作内容也可能发生变化。而当你的职务、工作内容,也会影响到你积累什么样的知识和技能。

举个我自己的例子,我2005年开始做软件开发,做了两三年,积累了C++、Windows开发、网络编程、MFC、WTL、Windows CE、多媒体等方面的知识和技能,2008年时开始带团队,工作内容分成开发和管理两部分,慢慢积累了项目管理和团队管理方面的知识和技能。在这个变化过程中,经济收入也发生了变化。当我再次选择职业时,我的知识、技能、曾经的工作经验、薪酬福利等,共同决定了我能找到什么样的职业:别的企业会看我的知识、技能、经历,我也会本着个人商业价值可持续发展的角度去选择职业机会。

OK,现在可以来说明内生涯和外生涯的关系了:

  • 内生涯决定外生涯
  • 外生涯拉内生涯

《花千骨》中有几段特别有意思的情节,可以印证内外生涯的关系。

花千骨投入长留,可她【仙资】有限,修行【飞剑术】,好久也飞不起来,在仙剑大会上败给霓漫天,却因缘际会得白子画收为徒弟,此时她作为【掌门首徒】,受到了很多人的质疑以及霓漫天的陷害。为了拿走花千骨掌门弟子的身份,霓漫天用涂了洗髓散(尹上漂提供)的毒针暗算花千骨,令其失去仙资。白子画耗费百年修为帮花千骨驱毒,不但恢复其仙资,还打通了她的【仙脉】,为其日后精进奠定坚实基础。

注意我标注重点的那些词,仙资、仙脉属于天赋,飞剑术属于技能,都是内生涯里面的东西;而掌门首徒则是身外之物,是别人赋予花千骨的一种身份,代表一种地位,是外生涯的东西。

只有飞剑术到一定程度,才有资格做掌门首徒。这是大部分人的看法,是内生涯决定外生涯的原则影响了人的看法。当内生涯低于外生涯时,如果个人不能很快通过修行提升内生涯,就会面临各种痛苦和压力:别人会质疑,为毛你嘛都不行还能当掌门首徒,尸位素餐,给我下来;自己也会怀疑,我到底是不是这块料啊,我如果真的不行怎么办呢。而一旦因为各种原因,内生涯真的配不上外生涯,那组织、他人就会采取措施剥夺你的外生涯。

古代的学而优则仕,也是内生涯决定外生涯的一种典型情况。其实我们身边也很多,普通的开发工程师知识、技能、经验修炼到一定程度,就可以做架构师、技术专家,这也是典型的内生涯决定外生涯。

当外生涯高于内生涯时,虽然有压力,但也会促使你提升自己的知识、技能等,使内生涯与外生涯匹配,最终内生涯超越外生涯,可以进一步在组织内或组织外发展,获得更高的外生涯。这就是外生涯拉动内生涯的一种表现。

说到这里我们再展开一下。当内生涯略高于外生涯时,工作会驾轻就熟,容易出成绩,感到轻松舒适。当内生涯高过外生涯一大截时,个人就会觉得怀才不遇,想谋求更高的发展,如果长时间处于失配状态,跳槽指数就会增高。当内生涯低于外生涯时,工作会感到吃力,需要不断提升自己。如果不能有效提升,就可能会被剥夺外生涯。

高薪的划之道

因为内生涯决定外生涯,所以,程序员要想获取高薪,最根本的策略是修炼内功,发挥自己的性格优势,挖掘自己的职业兴趣,找到适合自己的职业,发挥天赋,不断提升知识、技能,让自己的商业价值不断爬升

而一个人的商业价值能否提现出来,和所处平台又有非常大的关系。当你在一个好的宏观环境里,在一个前景光明的产业里,在一个处于上升期的企业里时,你的价值很容易就能体现出来,你能获取到的回报(外生涯)也会超越大多数人。所以,除了修炼内功,还要懂得如何寻找职业机会,让自己有用武之地。这就是程序员谋取高薪的指导性原则。

下面我们展开来讲如何修炼内功以及如何寻找职业机会

内功

内功的修炼,其实又分为三部分:

1. 发挥性格优势

2. 挖掘职业兴趣

3. 积累知识和技能

假如你现在已经是软件开发工程师,那我们就略过第一和第二两步了。

假如你虽然是软件开发工程师,但不确定是否适合做下去,那可以看看我发表在微信订阅号“程序视界”的文章,“如何快速定位自己热爱的工作(程序员版)”,肯定会有帮助。

假如你是还没入职场的小鲜肉,OK,可以来找我聊聊,我们可以一起来看看你是否适合做程序员。

搞了这么多假如,那我们要关注的就只有第三点了,积累知识和技能。哇哈哈哈哈,终于到正题了,走,西天!

积累知识和技能有两个原则:

  • 职业目标相关

有人说程序员是最爱项目符号列表的,凡事1、2、3……你看我这篇文章就能推断出,我一定是受了程序员工作经历的熏陶了。

职业目标相关性

这一点很容易理解,假如你就想做iOS应用开发,那你学C#估计就没什么用,学MFC就更没用了。一样知识,一种技能,只有它和你的目标相关时才是有用的。没用的知识对你来讲,再多都是枉然,假如一种知识不能落到应用上,那它就不是知识。我这是针对职业相关性来讲的哦,这句话写给那些爱抬杠的朋友们。

技能呢,其实又分为两类:

  • 专业技能
  • 通用技能

专业技能是对某种专业知识的应用能力,与特定职业相关。比如磨剪子镪菜刀(现在很少了),你不走街串巷干这个行当,基本就没用了。再比如你能用MFC在Windows下开发客户端应用,现在你要去做Android开发,那用处也不大。

通用技能是可迁移的,就是你会做的事。比如你超级会写PPT,这种技能到哪里都用得上啊。比如你很善于沟通,总能与别人达成一致;比如你善于当众演讲;比如你社交能力强;比如你很会指导别人;比如游泳……这些都是通用的技能,可以在不同的工作中广泛应用。

通用技能对于你能否找到理想工作至关重要。

我们从程序员的世界来看,那些很牛X的人,比如马克·扎克伯格,一开始也是程序员,后来呢,人家创立Facebook,他的创新、谈判、指导、说服等通用能力一定很强。另外他还会中文(语言技能也是通用技能,和驾驶一样),可以用中文和习大大流畅交谈。还有雷军,写了十年程序,现在在做什么呢?如果他只会使用C语言开发能这样吗?

所以,我们在积累技能时,既要立足于现在的职业,强化职业相关的专业技能,比如你做Web前端的,HTMP、CSS、JavaScript、各种JS框架(比如JQuery、AngularJS等)、前端框架如Bootstrap,都可以玩得很熟,这是专业技能,必须的,你做前端就会用得上;又要留意专业技能之外的通用技能,通用技能是一个程序员的软实力,比如发现自己的学习模式,培养自我学习的能力,比如与人沟通的能力,比如口头表达能力,比如写作能力,比如信息检索能力……

那么,问题来了,怎样才能知道,一个职业都需要什么样的知识、技能呢?有三种途径:

  • 内的位描述
  • 业内前辈访谈
  • 招聘网站的招聘信息

一般的企业都会有岗位(职位)描述,说明这个职位的职责,需要的知识、技能。有的企业还有一条晋升通道,比如软件开发工程师会有初级、中级、高级、资深、专家等级别,每个级别的任职资格说明里通常会有对技能水平的说明。这是我们第一个可以接触到的资料。比如我曾经待过的公司就有这种说明,高级开发工程师会要求你C++、概要设计、文档、数据库调优、授课、指导、管理等知识和能力。

第二种途径是找一个同岗位的前辈聊一聊,他很可能会给你和第一种途径不一样的视角,根据他的经验告诉你什么重要什么不重要,该培养什么不该培养什么。

第三种是非常有效的途径,不但可以弥补第一种途径的不足(有的公司会没有,有的公司会很简单而流于形式),还可以从中梳理出某个技术栈的发展态势。像智联招聘、拉钩、猎聘、大街网、51job等网站都会有大量软件开发工程师的招聘信息,可以结合我们自己的技术方向,拟定关键字进行搜索,然后看看别的企业对某个岗位都是什么要求。通过不断分析,就可以列出一张知识、技能清单来,拿着这个清单,就可以去有针对性的发展自己的技能,该自学的自学,该培训的培训,该参加开源项目的参加开源项目……

持续性

植物的顶芽优先生长而侧芽受抑制的现象,在植物学上称为顶端优势。为了维持顶端优势,可以人为干预植物的生长,比如一颗泡桐树,要想它长得又高又直又粗,就需要不断砍掉树干上的侧枝。

在企业管理领域存在顶端优势现象,处在优势的实权部门会抑制其它相关职能部门的发展,处于权力顶端的人往往抑制着处于下端的职权,处于优势的核心产品也会抑制其它产品的发展壮大……

对于程序员个人的知识和技能积累来讲,通常也需要维持顶端优势。

一个软件开发工程师,在自己知识图谱与技能树中,如果存在顶端优势现象,那当别人问你擅长什么时,你就可以信心满满地回答出来。而如果你的知识和技能还能在企业内超越其他程序员,形成群体内的比较优势或者顶端优势,那你的光芒一定照耀四方。

我承认,能做到第二步这种程度的人相对较少,所以,我们只讨论第一步:在自己的知识图谱与技能树中打造顶端优势

毋庸讳言,软件开发工程师跳槽频率比大部分职业的从业者高一些,在不同的企业不同的行业为不同的用户开发不同的产品时,用到的知识和技能通常是不同的。这就会导致一种情形:什么都懂一点,什么都不精深,什么都能干一点儿,什么都干不专业。而知识越精深越有价值,技能越熟练产出率越高,现在以及将来是专业主义时代(参见大前研一的《专业主义》),如果我们能沿着一个方向积累知识锻炼技能,那就可以形成竞争优势,随着不断用心打磨,就会产生顶端优势,就越来越能解决问题,不可替代性就会越来越强,商业价值就越来越高,薪酬福利自然越来越好。

所以,工作一段时间之后,就要思考自己的职业目标,梳理自己的知识和技能,选择几样,着重培养,持续精进,形成优势。

寻找职业机

修炼完内功,我们该来寻找外部机会了。

在向外看寻找机会时,有三个递进的层次需要注意:

  • 行(产)业
  • 企业
  • 职业

我们一个一个来讲。

行业选择

现在软件已经成为支撑各行各业发展的服务,几乎每个行业都会用到软件。行业里的企业在使用软件服务时,要么买现成的,要么自己开发。现成的软件,比如CRM、ERP、OA等,很多行业里的公司都用,也一般都是采购。除了采购软件,还有一些行业的公司选择自己开发,那这个时候就需要软件开发工程师,也就是程序员了。

必须注意的是,不同行业的程序员的平均薪酬待遇是相差很大的。行业越有前景,个人的发展越好回报越好。越赚钱的行业,处在它里面的程序员薪资水平越高。这是一般性规律,我们程序员在择业时也需要考虑。

以房地产行业为例,2003到2013是中国房地产黄金十年,处在这个行业里的从业人员,有很多都赚得盆满钵满。以商品房销售为例,售楼小姐曾经是收入非常高的职业,干上一两年,拿到的提成都能买几套房。房产中介也有同样的机会,我买学区房时,提供服务的房产中介,他们的片区经理,就是在那几年赚了两套房子,过上了相对丰裕的生活。而2013年后,房地产销售每况愈下,现在几乎是举步维艰,我们家楼下的房产中介每天门可罗雀,今天开一家,明天关两家。新建住宅也是人流稀少,销售惨淡。

再说说我曾经待过的电信行业,1995年到2012年是黄金阶段,其中1997到2005年,是固定电话业务和宽带业务大发展的时期,国内产生了华为、中兴、西安大唐电信、普天、UT斯达康、烽火等知名企业。我的前辈们说,1999、2000年左右,奖金比工资多,出差都是飞机,每天补助200左右。而我2002年加入西安大唐电信后不久,固话和程控交换业务开始走下坡路(2002年之后移动通信大发展),我们出差都是火车,坐卧铺都受限制,出差补助不但按城市分档还变少了,票据报销也很严格。所以,你进入一个产业的时机非常重要

那么,我们该怎样选择行业?

先看一张图:

从上面的产业曲线图中可以看出,一般产业都有形成、发展、成熟、衰退四个时期。我们在选择一个产业时,发展期进入是最好的,成熟期也可以,衰退期就要慎重考虑了,除非你已无太多要求,只想随便干两年退休。

所以,作为程序员,也不能只盯着技术,还要看行业大势。“女怕嫁错郎,男怕入错行”这种老话是很有道理的。

现在(2015年),最有发展前景的行业是互联网、金融、医疗、教育、新能源、智慧产业、高端制造等。而一些传统行业,比如煤炭、电力、房地产、石油,都在走下坡路。再说下房地产,别看那些楼盘死撑着不降价,其实一个月也不见得卖出一套房去,很多房地产厂商想跑路都跑不掉,工地停工,薪资拖欠,各种新闻不断。

企业选择

2002年到2012年,移动通信黄金十年,最赚钱的公司除了中国移动,还包括一大波2G手机厂商以及其他设备厂商,西安大唐电信没能及时转型,迅速没落,原来的产业园都卖给陕鼓动力了,而华为则顺利转型,依然强劲,到处买地建园区,如日中天。一个程序员,在西安大唐电信和在华为,这么些年的感受肯定不同!

与行业类似,企业有投入、成长、成熟、衰退这样的发展周期。我们选择企业时也需要考虑目标企业的当前状况,是在快速成长还是正在衰退。对不太有冒险精神的程序员来讲,最好的进入时机是快速成长期,此时企业飞速扩张,各种机会很多,产品要不断迭代要形成技术优势,对技术人员需求很大,职位上的晋升,技术上的积淀,都会有很多。对于想拿青春赌明天的程序员来讲,也可以在一个公司的投入期进入,如果这家公司能突围,那作为初期的核心人员,回报是难以想象的,你只要看看阿里巴巴的十八罗汉就知道了。

选择朝阳行业,选择非衰退期的企业,这是寻找职业机会时必须要首先考虑的,只要你选对了行业进对了企业,个人的成长和回报是早晚的事儿。

我们还要展开来说一下,行业是由若干从事同一类或相近性质产品生产的企业组成的,在这些企业当中,一定有龙头老大,一定有前三甲,一定有前五前十,选择排名靠前的企业,一般来讲会更好一些。因为实力越强的企业,占有的资源越多,市场覆盖越广,盈利能力越强,现金流越好。企业盈利,企业现金充裕,员工收益自然也大。

可我为什么说一般呢?因为一个行业还有细分,还存在一些垄断细分领域的企业,虽然在整个行业中综合实力排名不靠前,但因为卡位好,此山是我开此树是我栽,要想从此过留下买路财,你想干那个领域的事儿就绕不开它,所以它也能活得很滋润。选择这样的企业,也相当不错。

职业

选对了行业,选对了企业,接下来就是选择企业内的职业了。

前面我们说互联网行业很好,金融行业很好,互联网金融也很好,你进了这些行业中的某家企业,也不一定有什么大发展。因为这里面还有职业之分。比如你在Camera360做前台,比如你在网易做行政专员,比如你在腾讯做保洁,是不是回报没那么高呢?

在一个企业里,一定是创造价值最多、距离核心价值链最近的职位的员工拿到的薪水最多(你要说有例外那我就认为你是在抬杠,不解释)。

有人说对于程序员来讲,根本没得选择,因为到哪个企业里都是做开发啊。

其实不然,还是有得选的。

比如你到一个房地产公司去做网站前端开发,你觉得怎么样?房地产公司最重要的部门是什么?肯定不是维护网站的技术部啊,你作为一个软件开发工程师,很可能受到的尊重拿到的薪水远不如销售人员。

对互联网公司来讲,最重要的是产品,那就对应有两个职位——产品经理和软件开发——很受重视。所以你到这样的公司里去做软件开发,就和到房地产公司感觉不一样。

再说说我们前文提到的华为,华为内部有核心网、终端、大数据等不同的部门,你觉得哪块的软件开发待遇更好?我猜是大数据和终端。

现在再来想,是不是有得选?

补充一点:其实我们在选择行业和企业时,还要考虑宏观环境里的地域因素。比如你在西安,互联网氛围就不太好;比如你在郴州,整个软件行业就很差……所以有时为了更好的发展,有些程序员会选择到机会更多的城市,比如北京、上海、深圳等。而如果你不想换城市(像笔者一样),有时就得妥协。

没有一滴水分的总结

我写文章经常放而不收,下笔千言离题万里,遭人诟病,这次我要学乖一点,来总结归纳一下。要点如下(符号列表,又见符号列表,符号列表让没有逻辑的我显得有条理):

  • 个人的商业价值体现在知识、技能、经历、天赋、人脉等方面
  • 宏观环境、产业、组织、职业、家庭等要素的综合会影响职业选择
  • 知识、技能、天赋、经验等属于内生涯,是你的内在质量,没人可以剥夺
  • 职务、薪酬福利、工作环境、工作内容等属于外生涯
  • 内生涯决定外生涯,外生涯可以拉动内生涯
  • 通过对知识、专业技能、通用技能等的不断积累,形成顶端优势,可以找到更好的外生涯目标
  • 累积知识和技能时,注意职业目标相关性和持续性
  • 要想高回报,选择前景好的行业里处于投入期、成长期的企业,在企业内选择靠近核心价值链的职位

提问的智慧

艾瑞克.史蒂文.雷蒙德(Eric Steven Raymond)

瑞克.莫恩(Rick Moen)

修订历史
修订版 3.92013年4月23日esr
修正链接
修订版 3.82012年6月19日esr
修正链接
修订版 3.72010年12月6日esr
对于英语为第二语言人士的有益建议
修订版 3.72010年11月2日esr
几种翻译不见了
修订版 3.62008年3月19日esr
小更新及新链接
修订版 3.52008年1月2日esr
勘误及一些翻译链接
修订版 3.42007年3月24日esr
新章节:“关于代码的问题”
修订版 3.32006年9月29日esr
增加凯.尼格曼(Kai Niggemann)的一个好建议
修订版 3.22006年1月10日esr
加入瑞克.莫恩(Rick Moen)编写的内容
修订版 3.12004年10月28日esr
文档“谷歌是你的朋友!”
修订版 3.02004年2月2日esr
主要新增在网页论坛应有的礼节

原文:How To Ask Questions The Smart Way
翻译:王刚 <yafrank at 126 dot com >
时间:2013年10月26日

弃权申明

许多项目的网站在如何取得帮助的部分链接了本文,这没有关系,也正是我们想要的。但如果你是该项目生成此链接的网管,请在链接附近显著位置注明:我们不提供该项目的服务支持!

我们已经领教了没有此说明带来的痛苦,我们将不停地被一些白痴纠缠,他们认为既然我们发布了本文,那么我们就有责任解决世上所有的技术问题。

如果你是因为需要帮助正在阅读本文,然后就带着可以直接从作者那取得帮助的印象离开,那么 就不幸成了我们所说的白痴之一。 别向 我们 提问,我们不会理睬的。 我们只是在这教你如何从那些真正懂得你软硬件问题的人那里取得帮助,但 99.9% 的时间我们不会是那些人。除非你非常地 确定 本文的作者是你遇到问题方面的专家,请不要打搅,这样大家都更开心一点。

引言

黑客 的世界里,你所提技术问题的解答很大程度上取决于你提问的方式与解决此问题的难度,本文将教你如何提问才更有可能得到满意的答复。

开源程序的应用已经很广,你通常可以从其他更有经验的用户而不是黑客那里得到解答。这是好事,他们一般对新手常有的毛病更容忍一点。然尔,使用我们推荐的方法,象对待黑客那样对待这些有经验的用户,通常能最有效地得到问题的解答。

第一件需要明白的事是黑客喜欢难题和激发思考的好问题。假如不是这样,我们也不会写本文了。如果你能提出一个有趣的问题让我们咀嚼玩味,我们会感激你。好问题是种激励与礼物,帮助我们发展认知,揭示没有注意或想到的问题。在黑客中,“好问题!” 是非常热烈而真挚的赞许。

此外,黑客还有遇到简单问题就表现出敌视或傲慢的名声。有时,我们看起来还对新手和愚蠢的家伙有条件反射式的无礼,但事情并不真是这样。

我们只是毫无歉意地敌视那些提问前不愿思考、不做自己家庭作业的人。这种人就象时间无底洞──他们只知道索取,不愿意付出,他们浪费了时间,这些时间本可用于其它更有趣的问题或更值得回答的人。我们将这种人叫做 “失败者(loser)” (由于历史原因,我们有时将“loser”拼写为“lusers” 。)

我们意识到许多人只是想使用我们写的软件,他们对学习技术细节没有兴趣。对大多数人而言,计算机只是种工具,是种达到目的的手段而已。他们有自己的生活并且有更要紧的事要做,我们承认这点,也从不指望每个人都对这些让我们着迷的技术问题感兴趣。不过,我们回答问题的风格是为了适应那些真正对此有兴趣并愿意主动参与解决问题的人,这一点不会变,也不该变。如果连这都变了,我们就会在自己能做得最好的事情上不再那么犀利。

我们(大多数)是自愿者, 从自己繁忙的生活中抽时间来回答问题,有时会力不从心。因此,我们会毫不留情地滤除问题,特别是那些看起来象是失败者提的,以便更有效地把回答问题的时间留给那些胜利者。

如果你认为这种态度令人反感、以施惠者自居或傲慢自大,请检查你的假设,我们并未要求你屈服──事实上,假如你做了该做的努力,我们中的大多数将非常乐意平等地与你交流,并欢迎你接纳我们的文化。试图去帮助那些不愿自救的人对我们简直没有效率。不懂没有关系,但愚蠢地做事不行。

所以,你不必在技术上很在行才能吸引我们的注意,但你 必须 表现出能引导你在行的姿态──机 敏、有想法、善于观察、乐于主动参与问题的解决。如果你做不到这些使你与众不同的事情,我们建议你付钱跟别人签商业服务合同,而不是要求黑客无偿帮助。

如果你决定向我们求助,你不会想成为一名失败者,你也不想被看成一个失败者。得到快速有效回答的最好方法是使提问者看起来象个聪明、自信和有想法的人,并且暗示只是碰巧在某一特别问题上需要帮助。

(欢迎对本文指正,可以将建议发至 esr@thyrsus.comrespond-auto@linuxmafia.com。 请注意,本文不想成为一般性的 网络礼仪 指南,我一般会拒绝那些与引出技术论坛中有用的回答不特别相关的建议。)

提问前

在通过电邮、新闻组或论坛提技术问题以前,做以下事情:

  1. 尝试在你准备提问论坛的历史文档中搜索答案
  2. 尝试搜索互联网以找到答案
  3. 尝试阅读手册以找到答案
  4. 尝试阅读“常见问题文档”(FAQ)以找到答案
  5. 尝试自己检查或试验以找到答案
  6. 尝试请教懂行的朋友以找到答案
  7. 如果你是程序员,尝试阅读源代码以找到答案

提问时,请先表明你已做了上述事情,这将有助于建立你不是寄生虫与浪费别人时间的印象。最好再表述你从中 学到的东西 ,我们喜欢回答那些表现出能从答案中学习的人。

运用某些策略,比如用谷歌(Google)搜索你遇到的各种错误提示(既搜索 谷歌论坛,也搜索网页), 这样很可能直接就找到了解决问题的文档或邮件列表线索。 即使没有结果,在邮件列表或新闻组寻求帮助时提一句“我在谷歌中搜过下列句子但没有找到什么有用的东西” 也是件好事,至少它表明了搜索引擎不能提供哪些帮助。将搜索关键词与你的问题及可能的解决方案联系起来,还有助于引导其他有类似问题的人。

别着急,不要指望几秒钟的谷歌搜索就能解决一个复杂的问题。读一下常见问题文档。在向专家提问之前,先向后靠靠放松一下,再思考一下问题。相信我们,他们能从你的提问看出你做了多少阅读与思考,如果你是有备而来,将更有可能得到解答。不要将所有问题一股脑抛出,只因你的第一次搜索没有结果(或者结果太多)。

认真地思考,准备好你的问题。轻率的提问只能得到轻率的回答,或者压根没有。在提问时,你越是表现出在此前做过思考与努力去解决自己的问题,你越有可能得到真正的帮助。

注意别提错问题。如果提问基于错误的假设,某黑客多半会一边想 “愚蠢的问题……”,一边按将错就错的答案回复你,并且希望这种只是得到你自己“问的问题”而非真正所需的解答,给你一个教训。

永远不要假设你 有资格 得到解答。你没有这种资格,毕竟你没有为此服务付费。如果你能够提出有内容、有趣和激励思考的问题──那种毫无疑问能够向社区贡献经验,而不仅仅是消极地要求从别人那获取知识的问题,你将“挣到”答案。

另一方面,表明你有能力也乐意参与问题的解决是个很好的开端。“有没有人能指个方向?”,我这还差点什么?”,“我应该查哪个网站?”,通常要比 “请给出我可以用的完整步骤”更容易得到回复,因为你表明了只要有人能指个方向,你就很乐意完成剩下的过程。

提问时

仔细挑选论坛

要对在哪提问留心,如果你做了下述事情,多半会被一笔勾销或被看成“失败者”:

  • 张贴与论坛主题无关的问题
  • 在面向高级技术问题的论坛上张贴肤浅的问题,或者反之。
  • 在太多不同的新闻组同时张贴
  • 给既非熟人也没有义务解决你问题的人发送你私人的电邮

为保护通信的渠道不被无关的东西淹没,黑客会除掉那些没有找对地方的问题,你不会想让这种事落到自己头上的。

因此,第一步是找对论坛。谷歌和其它搜索引擎还是你的朋友,可以用它们搜索你遇到困难的软硬件问题最相关的项目网站。那里通常都有项目的常见问题(FAQ)、邮件列表及文档的链接。如果你的努力(包括 阅读 FAQ)都没有结果,这些邮件列表就是最后能取得帮助的地方。项目的网站也许还有报告臭虫的流程或链接,如果是这样,去看看。

向陌生的人或论坛发送邮件极有可能是在冒险。譬如,不要假设一个内容丰富的网页的作者想充当你的免费顾问,不要对你的问题是否会受到欢迎做太乐观的估计──如果你不确定,向别处发或者压根别发。

在选择论坛、新闻组或邮件列表时,别太相信名字,先看看 FAQ 或者许可书以明确你的问题是否切题。发贴前先翻翻已有的帖子,这样可以让你感受一下那里行事的方式。事实上,张贴前在新闻组或邮件列表的历史文档中搜索与你问题相关的关键词是个极好的主意,也许就找到答案了。即使没有,也能帮助你归纳出更好的问题。

别象机关枪似的一次性“扫射”所有的帮助渠道,这就象大喊大叫一样会令人不快,温柔地一个一个来。

弄懂主题!最典型的错误之一是在某种致立于跨平台可移植的语言、库或工具的论坛中提关于 Unix 或 Windows 操作系统程序接口的问题。如果你不明白为什么这是大错,最好在搞清楚概念前什么也别问。

一般来说,在仔细挑选的公共论坛中提问比在私有论坛中提同样的问题更容易得到有用的回答。有几个道理支持这点,一是看潜在的回复者有多少,二是看论坛的参与者有多少,黑客更愿回答能启发多数人的问题。

可以理解,老练的黑客和一些流行软件的作者正在承受过多的不当消息。就象那根最后压垮骆驼背的稻草一样,你的加入也有可能使情况走向极端──已经好几次了,一些流行软件的作者退出了对自己软件的支持,因为伴随而来的涌入其私人邮箱的垃圾邮件变得无法忍受。

面向新手的论坛和互联网中继聊天(IRC)通常响应最快

本地的用户组织或者你所用的 Linux 发行版也许正在宣传新手取得帮助的论坛或 IRC 通道(在一些非英语国家,新手论坛很可能还是邮件列表),这些地方是开始提问的好去处,特别是当你觉得遇到的也许只是相对简单或者很普通的问题时。经过宣传的 IRC 通道是公开邀请提问的地方,通常可以得到实时的回复。

事实上,如果出问题的程序来自某发行版(这很常见),最好先去该发行版的论坛或邮件列表中提问,再到程序本身的项目论坛或邮件列表,(否则)该项目的黑客可能仅仅回复“ 我们的 代码”。

在任何论坛发贴以前,先看看有没有搜索功能。如果有,就试着用问题的几个关键词搜索一下,也许就有帮助。如果在此之前你已做过全面的网页搜索(你应该这样去做),还是再搜索一下论坛,搜索引擎有可能没来得及索引此论坛的全部内容。

通过论坛或 IRC 通道提供项目的用户支持有增长的趋势,电子邮件交流则更多地为项目开发者保留。所以先在论坛或 IRC 中寻求与该项目相关的帮助。

第二步,使用项目的邮件列表

当某个项目存在开发者邮件列表时,要向列表而不是其中的个别成员提问,即使你确信他能最好地回答你的问题。查一查项目的文档和主页,找到项目的邮件列表并使用它。采用这种办法有几个很好的理由:

  • 向个别开发者提的问题(如果)足够好,也将对整个项目组有益。相反,如果你认为自己的问题对整个项目组来说太愚蠢,这也不能成为骚扰个别开发者的理由。
  • 向列表提问可以分散开发者的负担,个别开发者(尤其是项目领导)也许太忙以至于没法回答你的问题。
  • 大多数邮件列表都要存档,那些存档将被搜索引擎索引,如果你向列表提问并得到解答,将来其它人可以通过网页搜索找到你的问题和答案,也就不用再次发问了。
  • 如果某些问题经常被问到,开发者可以利用此信息改进文档或软件本身,以使其更清楚。如果只是私下提问,就没有人能看到最常见问题的完整场景。

如果一个项目既有 “用户” 也有“开发者”(或 “黑客”)邮件列表或论坛,而你又不摆弄那些代码,向“用户”列表或论坛提问。不要假设自己会在开发者列表中受到欢迎,那些人多半会遭受你的噪音干扰。

然尔,如果你 确信 你的问题不一般,而且在“用户” 列表或论坛中几天都没有回复,可以试试“开发者”列表或论坛。建议你在张贴前最好先暗暗地观察几天,至少看看最近几天保存的帖子,以了解那的行事方式(事实上这是参与任何私有或半私有列表的好主意)

如果你找不到一个项目的邮件列表,而只能查到项目维护者的地址,只管向其发信。即便在这种情况下,也别假设(项目)邮件列表不存在。在你的电子邮件中陈述你已经试过但没有找到合适的邮件列表,也提及你不反对将自己的邮件转发给他人(许多人认为,即使没什么秘密,私人电子邮件也不应该被公开。通过允许将你的电子邮件转发他人,你给了相应人员处置你邮件的选择)。

使用有意义且明确的主题

在邮件列表、新闻组或论坛中,主题是你在五十个或更少的字以内吸引有资格专家注意的黄金机会,不要用诸如 “请帮我” (更别提大写的 “请帮我!!!!”,这种主题的消息会被条件反射式地删掉)之类的唠叨浪费机会。不要用你痛苦的深度来打动我们,相反,要在这点空间中使用超级简明扼要的问题描述。

使用主题的好惯例是“对象──偏差”(式的描述),许多技术支持组织就是这样做的。在“对象”部分指明是哪一个或哪一组东西有问题,在“偏差”部分则描述与期望的行为不一致的地方。

愚蠢:
救命啊!我的笔记本视频工作不正常!

明智:
X.org 6.8.1 扭曲鼠标光标,MV1005 型号的某显卡芯片组

更明智:
使用 MV1005 型号的某显卡芯片组在 X.org 6.8.1 的鼠标光标被扭曲

编写 “对象──偏差”式描述的过程有助于你组织对问题的细致思考。是什么被影响了?仅仅是鼠标光标或者还有其它图形?只在 X.org 中出现?或只是在其 6.8.1 版中?是针对某显卡芯片组?或者只是其中的 MV1005 型号?一个黑客只需描一眼就能够立即明白什么是你遇到的问题,什么是你自己的问题。

更一般地,想象一下在一个只显示主题的文档索引中查找。让你的主题更好地反映问题,可以使下一个搜索类似问题的人能够在文档中直接就找到答案的线索,而不用再次发贴提问。

如果你想在回复中提问,确保改变主题以表明你是在问一个问题,一个主题象 “Re: 测试” 或者 “Re: 新臭虫”的消息不太可能引起足够的注意。同时,将回复中与新主题不甚相关的引用内容尽量删除。

对于列表消息,不要直接点击回复(按钮)来开始一个全新的线索,这将限制你的观众。有些邮件阅读程序,比如 mutt,允许用户按线索排序并通过折叠线索来隐藏消息,这样做的人永远看不到你发的消息。

仅仅改变主题还不够。mutt 和其它一些邮件阅读程序还要检查邮件头主题以外的其它信息,以便为其指定线索,所以宁可发一个全新的邮件。

在论坛,因为消息与特定的线索紧密结合,并且通常在线索之外不可见,好的提问方式略有不同,通过回复提问并不要紧。不是所有论坛都允许在回复中出现分离的主题,而且这样做了基本上没有人会去看。不过,通过回复提问本身就是令人怀疑的做法,因为它们只会被正在查看该线索的人读到。所以,除非你 只想 在该线索当前活跃的人群中提问,还是另起炉灶比较好。

使问题容易回复

以“请向……回复”来结束问题多半会使你得不到回答。如果你觉得花几秒钟在邮件客户端设置一下回复地址都麻烦,我们也觉得花几秒钟考虑你的问题更麻烦。如果你的邮件客户端程序不支持这样做,换个好点的;如果是操作系统不支持所有这种邮件客户端程序,也换个好点的。

在论坛,要求通过电子邮件回复是完全无礼的,除非你确信回复的信息也许是敏感的(而且有人会为了某些未知的原因,只让你而不是整个论坛知道答案)。如果你只是想在有人回复线索时得到电子邮件提醒,可以要求论坛发送。几乎所有论坛都支持诸如“留意本线索”、“有回复发送邮件”等功能。

用清晰、语法、拼写正确的语句书写

经验告诉我们,粗心与草率的作者通常也粗心与草率地思考和编程(我敢打赌)。为这些粗心与草率的思考者回答问题没有什么好处,我们宁可将时间花在其它地方。

清楚、良好地表达你的问题非常重要。如果你觉得这样做麻烦,我们也觉得注意(你的问题)麻烦。花点额外的精力斟酌一下字句,用不着太僵硬与正式──事实上,黑客文化很看重能准确地使用非正式、俚语和幽默的语句。但它 必须 很准确,而且有迹象表明你是在思考和关注问题。

正确地拼写、使用标点和大小写,不要将“its”混淆为“it’s”,“loose”搞成“lose”或者将“discrete”弄成 “discreet”。不要全部用大写,这会被视为无礼的大声嚷嚷 (全部小写也好不到哪去,因为不易阅读。Alan Cox [注:著名黑客,Linux 内核的重要参与者] 也许可以这样做,但你不行。)

一般而言,如果你写得象个半文盲似的傻子,多半得不到理睬。也不要使用即时通讯中的简写,如将“you”简化为“u”会使你看起来象一个为了节约二次击键的半文盲式的傻子。更糟的是,如果象个小孩似地鬼画桃符那绝对是在找死,可以肯定没人会理你(或者最多是给你一大堆指责与挖苦)。

如果在非母语论坛提问,你的拼写与语法错误会得到有限的宽容,但懒惰完全不会被容忍(是的,我们通常看得出其中的差别)。同时,除非你知道回复者使用的语言,请使用英语书写。繁忙的黑客一般会直接删除用他们看不懂语言写的消息。在互联网上英语是工作语言,用英语书写可以将你的问题不被阅读就被直接删除的可能性降到最低。

如果你用英语书写但它是你的第二语言,最好提醒潜在的回复者语言上可能的困难以便绕过这个问题,比如:

  • 英语不是我的母语,请谅解拼写错误。
  • 如果您使用某某语言,请电邮/私聊我,也许我需要您的协助翻译我的问题。
  • 对于这个技术术语本身我很熟悉,但对于它的一些俚语或习惯表达方式就不太明白了。
  • 我已经同时用某某语及英语提问,如果您使用两者之一回复,我很乐意翻译。

使用易于读取且标准的文件格式发送问题

如果你人为地将问题搞得难以阅读,它多半会被忽略,人们更愿读易懂的问题,所以:

  • 使用纯文本而不是 HTML(超文本标注语言)( 关闭HTML 并不难)
  • 使用 MIME(多用途互联网邮件扩展)附件通常没有问题,前提是真正有内容(譬如附带的源文件或补丁),而不仅仅是邮件客户端程序生成的模板(譬如只是消息内容的拷贝)。
  • 不要发送整段只是单行句子但多次折回的邮件(这使得回复部分内容非常困难)。设想你的读者是在80个字符宽的文本终端阅读邮件,设置你的行折回点小于 80 列。
  • 但是,也 不要 用任何固定列折回数据(譬如日志文件拷贝或会话记录)。数据应该原样包含,使回复者确信他们看到的是与你看到的一样的东西。
  • 在英语论坛中,不要使用’Quoted-Printable’ MIME 编码发送消息。这种编码对于张贴非 ASCII 语言可能是必须的,但很多邮件程序并不支持。当它们分断时,那些文本中四处散布的 “=20”符号既难看也分散注意力,甚至有可能破坏内容的语意。
  • 永远不要 指望黑客们阅读使用封闭的专用格式编写的文档,诸如微软公司的 Word 或 Excel 文件等。大多数黑客对此的反应就象有人将还在冒热气的猪粪倒在你门口时你的反应一样。即使他们能够处理,也很厌恶这么做。
  • 如果你从使用视窗的电脑发送电子邮件,关闭问题颇多的微软“聪明引用”功能(在“工具” -> “自动纠正选项”的“输入时自动格式化”下去掉聪明引用的选框),以免在你的邮件中到处散布垃圾字符。
  • 在论坛,勿滥用“表情符号”和“HTML”功能(当它们提供时)。一两个表情符号通常没有问题,但花哨的彩色文本倾向于使人认为你是个无能之辈。过滥地使用表情符号、色彩和字体会使你看来象个傻笑的小姑娘。这通常不是个好主意,除非你只是对性而不是有用的回复更有兴趣。

如果你使用图形用户界面的邮件客户端程序(如网景公司的 Messenger、微软公司的 Outlook 或者其它类似的),注意它们的缺省配置不一定满足这些要求。大多数这类程序有基于菜单的“查看源码”命令,用它来检查发送文件夹中的消息,以确保发送的是没有多余杂质的纯文本文件。

描述问题应准确且有内容

  • 仔细、清楚地描述问题的症状
  • 描述问题发生的环境(主机、操作系统、应用程序,任何相关的),提供销售商的发行版和版本号(如:“Fedora Core 7”、“Slackware 9.1”等)
  • 描述提问前做过的研究及其理解。
  • 描述提问前为确定问题而采取的诊断步骤。
  • 描述最近对计算机或软件配置的任何相关改变。
  • 如果可能,提供在可控环境下重现问题的方法。

尽最大努力预测黑客会提到的问题,并提前备好答案。

如果你认为是代码有问题,向黑客提供在可控环境下重现问题的方法尤其重要。当你这么做时,得到有用且及时回复的可能性将大大增加。

西蒙.泰瑟姆(Simon Tatham)写过一篇 如何有效报告臭虫 的文章,我强烈推荐各位阅读。

量不在多,精炼则灵

你应该(写得)精炼且有内容,简单地将一大堆代码或数据罗列在求助消息中达不到目的。如果你有一个很大且复杂的测试样例让程序崩溃,尝试将其裁剪得越小越好。

至少有三个理由支持这点。第一,让别人看到你在努力简化问题使你更有可能得到回复。第二,简化问题使你更有可能得到 有用的 回复。第三,在提纯臭虫报告的过程中,你可能自己就找到了解决办法或权宜之计。

别急于宣称找到臭虫

当你在一个软件中遇到问题,除非你 非常、非常 的有根据,不要动辄声称找到了臭虫。提示:除非你能提供解决问题的源代码补丁,或者对前一版本的回归测试表现出不正确的行为,否则你都多半不够完全确信。对于网页和文档也如此,如果你(声称)发现了文档的“臭虫”,你应该能提供相应位置的替代文本。

记住,还有许多其它用户并未经历你遇到的问题,否则你在阅读文档或搜索网页时就应该发现了(你在报怨前已经做了这些,是吧 ?)。这也意味着很有可能是你弄错了而不是软件本身有问题。

编写软件的人总是非常辛苦地使它尽可能完美。如果你声称找到了臭虫,也就置疑了他们的能力,即使你是对的,也有可能会使其中的部分人感到不快。(此外,)在主题中嚷嚷“臭虫”也是特别不老练的。

提问时,即使你私下非常确信已经发现一个真正的臭虫,最好写得象是做错了什么。如果真的有臭虫,你会在回复中看到这点。这样做的话,如果真有虫子,维护者就会向你道歉,这总比你弄砸了然后欠别人一个道歉要强。

低声下气代替不了做自己的家庭作业

有些人明白他们不应该粗鲁或傲慢地行事并要求得到答复,但他们退到相反的低声下气的极端:“我知道我只是个可怜的新丁,一个失败者,但……”。这既使人困扰,也没有用,当伴随着对实际问题含糊的描述时还特别令人反感。

别用低级灵长类动物的办法浪费你我的时间,相反,尽可能清楚地描述背景情况和你的问题,这比低声下气更好地摆正了你的位置。

有时,论坛设有单独的初学者提问版面,如果你真的认为遇到了肤浅的问题,到那去就是了,但一样别低声下气。

描述问题症状而不是猜测

告诉黑客是什么导致了问题是没用的(如果你的诊断理论是了不起的东西,你还会向别人咨询求助吗?)。所以,确保只是告诉他们问题的原始症状,而不是你的解释和理论,让他们来解释和诊断。如果你认为陈述自己的猜测很重要,应清楚地说明这只是你的猜测并描述为什么它们不起作用。

愚蠢:
我在编译内核时接连遇到 SIG11 错误,怀疑主板上的某根电路丝断了,找到它们的最好办法是什么?

明智:
我组装的电脑(K6/233 CPU、FIC-PA2007 主板[威盛 Apollo VP2 芯片组]、Corsair PC133 SDRAM 256Mb 内存)最近在开机 20 分钟左右、做内核编译时频繁地报 SIG11 错,但在头 20 分钟内从不出问题。重启动不会复位时钟,但整夜关机会。更换所有内存未解决问题,相关的典型编译会话日志附后。

由于以上这点许多人似乎难以掌握,这里有句话可以提醒你:“所有的诊断专家都来自密苏里州”。美国国务院的官方座右铭则是“让我看看”(出自国会议员威勒德.D.范迪弗[Willard D. Vandiver]在1899年时的讲话:“我来自一个出产玉米、棉花、牛蒡和民主党人的国家,滔滔雄辩既不能说服我,也不会让我满意。我来自密苏里州,你必须让我看看。”)针对诊断者而言,这并不是怀疑,而只是一种真实而有用的需求,以便让他们看到与你看到的原始证据尽可能一致的东西,而不是你的猜测与总结。(所以,)让我们看看。

按时间先后罗列问题症状

刚出问题之前发生的事情通常包含有解决问题最有效的线索。所以,记录中应准确地描述你、电脑和软件在崩溃前都做了什么。在命令行处理的情况下,有会话日志(如运行脚本工具生成的)并引用相关的若干(如20)行记录会非常有帮助。

如果崩溃的程序有诊断选项(如-v详述开关),试着选择这些能在记录中增加排错信息的选项。记住,“多”不等于“好”。试着选取适当的排错级别以便提供有用的信息而不是将阅读者淹没在垃圾中。

如果你的记录很长(如超过四段),在开头简述问题随后按时间先后罗列详细过程也许更有用。这样,黑客在读你的记录时就知道该注意哪些内容了。

描述目标而不是过程

如果你想弄清楚如何做某事(而不是报告一个臭虫),在开头就描述你的目标,然后才陈述遇到问题的特定步骤。

经常出现这种情况,寻求技术帮助的人在脑袋里有个更高层次的目标,他们在自以为能达到目标的特定道路上被卡住了,然后跑来问该怎么走,但没有意识到这条路本身有问题,结果要费很大的劲才能通过。

愚蠢:
我怎样才能让某图形程序的颜色拾取器取得十六进制的 RGB 值?

明智:
我正试着用自己选定数值的颜色替换一幅图片的色表,我现在知道的唯一方法是编辑每个表槽,但却无法让某图形程序的颜色拾取器取得十六进制的 RGB 值。

第二种提法是明智的,它使得建议采用更合适的工具以完成任务的回复成为可能。

别要求私下回复电邮

黑客们认为问题的解决过程应该公开、透明,此过程中如果更有才能的人注意到不完整或者不当之处,最初的回复才能够、也应该被纠正。同时,作为回复者也因为能力和学识被其它同行看到而得到某种回报。

当你要求私下回复时,此过程和回报都被中止。别这样做,让 回复者 来决定是否私下回答──如果他真这么做了,通常是因为他认为问题编写太差或者太肤浅,以至于对其它人毫无意义。

对这条规则存在一条有限的例外,如果你确信提问可能会引来大量雷同的回复时,那么“向我发电邮,我将为论坛归纳这些回复”将是神奇的句子。试着将邮件列表或新闻组从洪水般雷同的回复中解救出来是非常有礼貌的──但你必须信守诺言。

提问应明确

漫无边际的问题通常也被视为没有明确限制的时间无底洞。最有可能给你有用答案的人通常也是最忙的人(假如只是因为他们承担了太多工作的话),这些人对于没有止境的时间无底洞极其敏感,所以他们也倾向于讨厌那些漫无边际的问题。

如果你明确了想让回复者做的事(如指点方向、发送代码、检查补丁或其它),你更有可能得到有用的回复。(因为)这样可以让他们集中精力并间接地设定了他们为帮助你需要花费的时间和精力上限,这很好。

要想理解专家生活的世界,可以这样设想:那里有丰富的专长资源但稀缺的响应时间。你暗中要求他们奉献的时间越少,你越有可能从这些真正懂行也真正很忙的专家那里得到解答。

所以限定你的问题以使专家回答时需要付出的时间最少──这通常与简化问题还不太一样。举个例,“请问可否指点一下哪有好一点的 X 解释?”通常要比“请解释一下 X”明智。如果你的代码不运行了,通常请别人看看哪有问题比叫他们帮你改正更明智。

关于代码的问题

别要求他人给你出问题的代码排错而不提及应该从何入手。张贴几百行的代码,然后说一声“它不能运行”会让你得不到理睬。只贴几十行代码,然后说一句“在第七行以后,本应该显示<x>,但实际出现的是<y>”非常有可能让你得到回复。

最精确描述代码问题的方法是提供一个能展示问题的最小测试样例。什么是最小测试样例?它是对问题的展现,只需要刚好能够重现非预期行为的代码即可。如何生成一个最小测试样例?如果你知道哪一行或哪一段代码会产生问题,将其复制并提供刚好够用的外围支撑代码以构成一个完整的样例(够用是指源码刚好能被编译器、解释器或任何处理它的程序所接受)。如果你不能将问题缩小到特定的段落,复制源码并去除那些与问题无关的代码段。你能提供的最小测试样例越小越好(参见 量不在多,精炼则灵 )。

生成一个非常小的最小测试样例并不总是可能,但尽力去做是很好的锻练,这有可能帮助你找到需要自己解决的问题。即使你找不到,黑客们喜欢看到你努力过,这将使他们更合作。

如果你只是想让别人帮忙审一下代码,在最开头就要说出来,并且一定要提到你认为哪一部分特别需要关注以及为什么。

别张贴家庭作业式问题

黑客们善于发现“家庭作业”式的问题。我们中的大多数人已经做了自己的家庭作业,那是该做的,以便从中学到东西。问一下提示没有关系,但不是要求完整的解决方案。

如果你怀疑自己碰到了一个家庭作业式的问题,但仍然无法解决,试试在用户组、论坛或(作为最后一招)在项目的“用户”邮件列表或论坛中提问。尽管黑客们看出来,一些老用户也许仍会给你提示。

删除无意义的要求

抵制这种诱惑,即在求助消息末尾加上诸如“有人能帮我吗?”或“有没有答案?”之类在语义上毫无意义的东西。第一,如果问题描述还不完整,这些附加的东西最多也只能是多余的。第二,因为它们是多余的,黑客们会认为这些东西烦人──就很有可能用逻辑上无误但打发人的回复,诸如“是的,你可以得到帮助”和“不,没有给你的帮助”。

一般来说,避免提“是或否”类型的问题,除非你想得到 “是或否”类型的回答

不要把问题标记为“紧急”, 即使对你而言的确如此

这是你的问题,不要我们的。宣称“紧急”极有可能事与愿违:大多数黑客会直接删除这种消息,他们认为这是无礼和自私地企图得到即时与特殊的关照。而且“紧急”或其它有类似含义的主题有可能触发垃圾过滤规则,潜在的回复者可能永远看不到你的问题!

有一点点局部的例外,如果你是在一些知名度很高、会使黑客们激动的地方使用程序,也许值得这样去做。在这种情况下,如果你有期限压力,也很有礼貌地提到这点,人们也许会有足够的兴趣快一点回答。

当然,这是非常冒险的,因为黑客们对什么是令人激动的标准多半与你的不同。譬如从国际空间站这样张贴没有问题,但代表感觉良好的慈善或政治原因这样做几乎肯定不行。事实上,张贴诸如“紧急:帮我救救这个毛绒绒的小海豹!”肯定会被黑客回避或光火,即使他们认为毛绒绒的小海豹很重要。

如果你觉得这不可思议,再把剩下的内容多读几遍,直到弄懂了再发贴也不迟。

礼貌总是有益的

礼貌一点,使用“”和“谢谢你的关注”或者“谢谢你的关照”,让别人明白你感谢他们无偿花时间帮助你。

坦率地讲,这一点没有语法正确、文字清晰、准确、有内容和避免使用专用格式重要(同时也不能替代它们)。黑客们一般宁可读有点唐突但技术鲜明的臭虫报告,而不是那种有礼但含糊的报告。(如果这点让你不解,记住我们是按问题能教我们什么来评价它的)

然尔,如果你已经谈清楚了技术问题,客气一点肯定会增加你得到有用回复的机会。

(我们必须指出,本文唯一受到一些老黑客认真反对的地方是以前曾经推荐过的“提前谢了”,一些黑客认为这隐含着事后不用再感谢任何人的暗示。我们的建议是要么先说 “提前谢了”,事后对回复者表示感谢,要么换种方式表达,譬如用“谢谢你的关注”或“谢谢你的关照”)。

问题解决后追加一条简要说明

问题解决后向所有帮助过的人追加一条消息,让他们知道问题是如何解决的并再次感谢。如果问题在邮件列表或新闻组中受到广泛关注,在那里追加此消息比较恰当。

最理想的方式是向最初提问的线索回复此消息,并在主题中包含“已解决”、“已搞定”或其它同等含义的明显标记。在人来人往的邮件列表里,一个看见线索 “问题 X”和“问题 X-已解决”的潜在回复者就明白不用再浪费时间了(除非他个人觉得“问题 X”有趣),因此可以利用此时间去解决其它问题。

追加的消息用不着太长或太复杂,一句简单的“你好──是网线坏了!谢谢大家──比尔”就比什么都没有要强。事实上,除非解决问题的技术真正高深,一条简短而亲切的总结比长篇大论要好。说明是什么行动解决了问题,用不着重演整个排错的故事。

对于有深度的问题,张贴排错历史的摘要是恰当的。描述问题的最终状态,说明是什么解决了问题,在此之后 才指明可以避免的弯路。应避免的弯路部分应放在正确的解决方案和其它总结材料之后,而不要将此消息搞成侦探推理小说。列出那些帮助过你的名字,那样你会交到朋友的。

除了有礼貌、有内容以外,这种类型的追帖将帮助其他人在邮件列表、新闻组或论坛文档中搜索到真正解决你问题的方案,从而也让他们受益。

最后,此类追帖还让每位参与协助的人因问题的解决而产生一种满足感。如果你自己不是技术专家或黑客,相信我们,这种感觉对于你寻求帮助的老手和专家是非常重要的。问题叙述到最后不知所终总是令人沮丧的,黑客们痒痒地渴望它们被解决。“挠痒痒”为你挣到的信誉将对你下次再次张贴提问非常非常的有帮助。

考虑一下怎样才能避免他人将来也遇到类似的问题,问问自己编一份文档或 FAQ 补丁会不会有帮助,如果是的话就将补丁发给维护者。

在黑客中,这种良好的后继行动实际上比传统的礼貌更重要,也是你善待他人而赢得声誉的方式,这是非常有价值的财富。

如何解读回答

“读读该死的手册”(RTFM)和“搜搜该死的网络”(STFW):如何明白你已完全搞砸

有一个古老而神圣的传统:如果你收到“读读该死的手册”(RTFM) 的回复,发信人认为你应该去“读读该死的手册”。他或她多半是对的,去读一下吧。

“读读该死的手册”(RTFM)有个年轻一点的亲戚,如果你收到“搜搜该死的网络”(STFW)的回复,发信人认为你应该“搜搜该死的网络”。那人多半也是对的,去搜一下吧。(更温和一点的说法是“谷歌是你的朋友!”)

在论坛,你也可能被要求去搜索论坛的文档。事实上,有人甚至可能热心地为你提供以前解决此问题的线索。但不要依赖这种关照,提问前应该先搜索一下文档。

通常,叫你搜索的人已经打开了能解决你问题的手册或网页,正在一边看一边敲键盘。这些回复意味着他认为:第一,你要的信息很容易找到。第二,自已找要比别人喂到嘴里能学得更多。

你不应该觉得这样就被冒犯了,按黑客的标准,回复者没有不理你就是在向你表示某种尊敬,你反而应该感谢他热切地想帮助你。

如果还不明白……

如果你看不懂回答,不要马上回复一个要求说明的消息,先试试那些最初提问时用过的相同工具(如手册、FAQ、网页、懂行的朋友等)试着搞懂回答。如果还是需要说明,展现你已经明白的。

譬如,假如我告诉你:“看起来象是某输入项有问题,你需要清除它”,接着是个 不好 的回帖:“什么是某输入项?”。而这是一个 很好 的跟帖:“是的,我读了手册,某某输入项只在 -z 和 -p 开关中被提到,但都没有涉及到如何清除它们,你指的是哪一个还是我弄错了什么?

对待无礼

很多黑客圈子中看似无礼的行为并不是存心冒犯。相反,它是直接了当、一针见血式的交流风格,这种风格对于更关注解决问题而不是使别人感觉舒服而混乱的人是很自然的。

如果你觉得被冒犯了,试着平静地反应。如果有人真的做了过格的事,邮件列表、新闻组或论坛中的前辈多半会招呼他。如果这 没有 发生而你却光火了,那么你发火对象的言语可能在黑客社区中看起来是正常的,而将被视为有错的一方,这将伤害到你获取信息或帮助的机会。

另一方面,你会偶而真的碰到无礼和无聊的言行。与上述相反,对真正的冒犯者狠狠地打击、用犀利的语言将其驳得体无完肤都是可以接受的。然尔,在行事之前一定要非常非常的有根据。纠正无礼的言论与开始一场毫无意义的口水战仅一线之隔,黑客们自己莽撞地越线的情况并不鲜见。如果你是新手或外来者,避开这种莽撞的机会并不高。如果你想得到的是信息而不是消磨时光,这时最好不要把手放在键盘上以免冒险。

(有些人断言很多黑客都有轻度的自闭症或阿斯伯格综合症,缺少用于润滑人类社会“正常”交往所需的脑电路。这既可能是真也可能是假。如果你自己不是黑客,兴许你认为我们脑袋有问题还能帮助你应付我们的古怪行为。只管这么干好了,我们不在乎。我们 喜欢 现在这个样子,并且一般都对病号标记有站得住脚的怀疑。)

在下一节,我们会谈到另一个问题,当行为不当时会受到的“冒犯”。

别象失败者那样反应

在黑客社区的论坛中有那么几次你可能会搞砸──以本文描述或类似的方式。你会被示众是如何搞砸的,也许言语中还会带点颜色。

这种事发生以后,你能做的最糟糕的事莫过于哀嚎你的遭遇、宣称被口头攻击、要求道歉、高声尖叫、憋闷气、威胁诉诸法律、向其雇主报怨、忘了关马桶盖等等。相反,你该这样去做:

熬过去,这很正常。事实上,它是有益健康与恰当的。

社区的标准不会自己维持,它们是通过参与者积极而 公开 地执行来维持的。不要哭嚎所有的批评都应该通过私下的邮件传送,这不是事情运作的方式。当有人评论你的一个说法有误或者提出不同看法时,坚持声称受到个人攻击也毫无益处,这些都是失败者的态度。

也有其它的黑客论坛,受过高礼节要求的误导,禁止参与者张贴任何对别人帖子挑毛病的消息,并声称“如果你不想帮助用户就闭嘴”。有思路的参与者纷纷离开的结果只会使它们变成了毫无意义的唠叨与无用的技术论坛。

是夸张的“友谊”(以上述方式)还是有用?挑一个。

记着:当黑客说你搞砸了,并且(无论多么刺耳地)告诉你别再这样做时,他正在为关心你和他的社区而行动。对他而言,不理你并将你从他的生活中滤除要容易得多。如果你无法做到感谢,至少要有点尊严,别大声哀嚎,也别因为自己是个有戏剧性超级敏感的灵魂和自以为有资格的新来者,就指望别人象对待脆弱的洋娃娃那样对你。

有时候,即使你没有搞砸(或者只是别人想象你搞砸了), 有些人也会无缘无故地攻击你本人。在这种情况下,报怨倒是 真的 会把问题搞砸。

这些找茬者要么是毫无办法但自以为是专家的不中用家伙,要么就是测试你是否真会搞砸的心理专家。其它读者要么不理睬,要么用自己的方式对付他们。这些找茬者在给自己找麻烦,这点你不用操心。

也别让自己卷入口水战,大多数口水战最好不要理睬──当然,是在你核实它们只是口水战、没有指出你搞砸的地方,而且没有巧妙地将问题真正的答案藏于其中之后(这也是可能的)。

提问禁忌

下面是些典型的愚蠢问题和黑客不回答它们时的想法。

问:我到哪可以找到某程序或 X 资源?
问:我怎样用 X 做 Y?
问:如何配置我的 shell 提示?
问:我可以用 Bass-o-matic 文件转换工具将 AcmeCorp 文档转为 TeX 格式吗?
问:我的{程序、配置、SQL 语句}不运行了
问:我的视窗电脑出问题了,你能帮忙吗?
问:我的程序不运行了,我认为系统工具X有问题
问:我安装 Linux 或 X 遇到困难,你能帮忙吗?
问:我如何才能破解超级用户口令/盗取通道操作员的特权/查看某人的电子邮件?
问:我到哪可以找到某程序或 X 资源?
答:在我找到它的同样地方,笨旦──在网页搜索引擎上。上帝啊,难道还有人不知道如何使用 谷歌 吗?
问:我怎样用 X 做 Y?
答:如果你想解决的是 Y,提问时别给出可能并不恰当的方法。这种问题说明提问者不但对 X 完全无知,也对要解决的 Y 问题糊涂,还被特定形势禁锢了思维。等他们把问题弄好再说。
问:如何配置我的 shell 提示?
答:如果你有足够的智慧提这个问题,你也该有足够的智慧去 “读读该死的手册”(RTFM),然后自己去找出来。
问:我可以用 Bass-o-matic 文件转换工具将 AcmeCorp 文档转为 TeX 格式吗?
答:试试就知道了。如果你试过,你既知道了答案,又不用浪费我的时间了。
问:我的{程序、配置、SQL 语句}不运行了
答:这不是一个问题,我也没有兴趣去猜你有什么问题──我有更要紧的事要做。看到这种东西,我的反应一般如下:

  • 你还有什么补充吗?
  • 噢,太糟了,希望你能搞定。
  • 这跟我究竟有什么关系?
问:我的视窗电脑出问题了,你能帮忙吗?
答:是的,把视窗垃圾删了,装个象 Linux 或 BSD 的开源操作系统吧。

注意:如果程序有官方的视窗版或者与视窗有交互(如 Samba),你 可以 问与视窗相关的问题,只是别对问题是由视窗操作系统而不是程序本身造成的回复感到惊讶,因为视窗一般来说太差,这种说法一般都成立。

问:我的程序不运行了,我认为系统工具 X 有问题
答:你完全有可能是第一个注意到被成千上万用户反复使用的系统调用与库文件有明显缺陷的人,更有可能的是你完全没有根据。不同凡响的说法需要不同凡响的证据,当你这样声称时,你必须有清楚而详尽的缺陷说明文档作后盾。
问:我安装 Linux 或 X 遇到困难,你能帮忙吗?
答:不行,我需要亲手操作你的电脑才能帮你排错,去向当地的 Linux 用户组寻求方便的帮助(你可以在 这里 找到用户组列表)

注意:如果安装问题与某 Linux 发行版有关,在针对的邮件列表、论坛或本地用户组织中提问也许是恰当的。此时,应描述问题的准确细节。在此之前,先用 “linux”和 所有 被怀疑的硬件 [作关键词] 仔细搜索。

问:我如何才能破解超级用户口令/盗取通道操作员的特权/查看某人的电子邮件?
答:想做这种事情说明你是个卑劣的家伙,想让黑客教你做这种事情说明你是个白痴。

好问题与坏问题

最后,我将通过举例来演示提问的智慧。同样的问题两种提法,一种愚蠢,另一种明智。

愚蠢:我在哪能找到关于 Foonly Flurbamatic 设备的东西?
这个问题在乞求得到 “搜搜该死的网络”(STFW) 式的回复。

明智: 我用谷歌搜索过“Foonly Flurbamatic 2600”,但没有找到什么有用的,有谁知道在哪能找到这种设备的编程信息?
这个人已经搜索过网络了,而且听起来他可能真的遇到了问题。

愚蠢: 我不能编译某项目的源代码,它为什么这么破?
提问者假设是别人搞砸了,太自大了。

明智: 某项目的源代码不能在某 Linux 6.2 版下编译。我读了常见问题文档,但其中没有与某 Linux 相关的内容。这是编译时的记录,我做错了什么吗?
提问者已经指明了运行环境,读了常见问题文档(FAQ),列出了错误,也没有假设问题是别人的过错,这家伙值得注意。

愚蠢: 我的主板有问题,谁能帮我?
某黑客对此的反应可能是:“是的,还需要帮你拍背和换尿布吗?”,然后是敲下删除键。

明智: 我在 S2464 主板上试过 X、Y 和 Z,当它们都失败后,又试了 A、B 和 C。注意我试 C 时的奇怪症状,显然某某东西正在做某某事情,这不是期望的行为。通常在 Athlon MP 主板上导致某某事情的原因是什么?有谁知道我还能再试点什么以确定问题?
相反地,这个人看来值得回答。他或她展现了解决问题的能力而不是坐等天上掉馅饼。

在最后那个问题中,注意“给我一个回答”与“请帮我看看我还能再做点什么测试以得到启发”之间细微但重要的差别。

事实上,最后那个问题基本上源于 2001 年 8 月 Linux 内核邮件列表(lkml)上的真实事件,是我(Eric)当时提了那个问题,我发现 Tyan S2462 主板有神秘的死机现象,邮件列表成员给我提供了解决此问题的关键信息。

通过这种提问方式,我给了别人可以咀嚼玩味的东西。我设法使之对参与者既轻松又有吸引力,也表明了对同行能力的尊敬并邀请他们与我一起协商。通过告诉他们我已经走过的弯路,我还表明了对他们宝贵时间的尊重。

事后,当我感谢大家并评论这次良好的经历时,一个 Linux 内核邮件列表的成员谈到,他认为我得到答案并不是因为我的名字挂在列表上,而只是因为我正确的提问方式。

黑客们在某种方面是非常不留情面的精英分子。我想在这事上他是对的,如果我 表现得 象个不劳而获的寄生虫,不管我是谁都会被忽略或斥责。他建议将整个事件作为对其它人提问的指导,这直接导致了本文的编写。

如果得不到回答

如果得不到回答,请不要认为我们不想帮你,有时只是因为被问到的小组成员的确不知道答案。没有回复不等于不被理睬,当然必须承认从外面很难看出两者的差别。

一般而言,直接将问题再张贴一次不好,这会被视为毫无意义的骚扰。耐心一点,知道你问题答案的人可能生活在不同的时区,有可能正在睡觉,也有可能你的问题一开始就没有组织好。

还有其它资源可以寻求帮助,通常是在一些面向新手的资源中。

有许多在线与本地的用户组织,虽然它们自己不编写任何软件,但是对软件很热心。这些用户组通常因互助和帮助新手而形成。

还有众多大小商业公司提供签约支持服务,别因为要付点钱才有支持就感到沮丧!毕竟,如果你车子的汽缸垫烧了,你多半还得花钱找个修理店把它弄好。即使软件没花你一分钱,你总不能指望服务支持都是免费的。

象 Linux 这样流行的软件,每个开发者至少有一万个以上的用户,一个人不可能应付这么多用户的服务要求。记住,即使你必须付费才能得到支持,也比你还得额外花钱买软件要少得多(而且对封闭源代码软件的服务支持与开源软件相比通常还要贵一点,也要差一点)。

如何更好地回答

态度和善一点。问题带来的压力常使人显得无礼或愚蠢,其实并不是这样。

对初犯者私下回复。 对那些坦诚犯错之人没有必要当众羞辱,一个真正的新手也许连怎么搜索或在哪找 FAQ 都不知道。

如果你不确定,一定要说出来! 一个听起来权威的错误回复比没有还要糟,别因为听起来象个专家好玩就给别人乱指路。要谦虚和诚实,给提问者与同行都树个好榜样。

如果帮不了忙,别妨碍。 不要在具体步骤上开玩笑,那样也许会毁了用户的安装──有些可怜的呆瓜会把它当成真的指令。

探索性的反问以引出更多的细节。 如果你做得好,提问者可以学到点东西──你也可以。试试将很差的问题转变成好问题,别忘了我们都曾是新手。

尽管对那些懒虫报怨一声“读读该死的手册”(RTFM)是正当的,指出文档的位置(即使只是建议做个谷歌关键词搜索)会更好

如果你决意回答,给出好的答案。 当别人正在用错误的工具或方法时别建议笨拙的权宜之计,应推荐更好的工具,重新组织问题。

请回答真正的问题!如果提问者已经做了自己该做的研究,并且说明尝试过X,Y,Z,A,B与C都没有得到想要的結果,那么回复试试A或B 或者给出一个内容为 试一下X,Y,Z,A,B或C的链接将极其无益!

帮助你的社区从中学习。当回复一个好问题时,问问自己 “如何修改相关文件或 FAQ 文档以免再次解答同样的问题?”,接着再向文档维护者发一份补丁。

如果你是在研究一番后才做出的回答,展现你的技巧而不是直接端出结果。毕竟“授人以鱼,不如授人以渔”。

相关资源

如果需要个人电脑、Unix 和互联网如何工作的基础知识,参阅 Unix 和互联网工作的基本原理

当你发布软件或补丁时,试着按 软件发布实践 操作。

鸣谢

伊夫林.米切尔(Evelyn Mitchell)贡献了一些愚蠢问题例子并启发了编写“如何更好地回答问题”这一节,米哈伊尔.罗门迪克(Mikhail Ramendik)贡献了一些特别有价值的建议和改进。

声明:本文没有任何褒贬或者对比各种编程语言的意思,请不要做无谓的语言之争。

我们这些80后程序员大部分人都是从delphi,C,C++开始接触编程的,然后等到了大学或者工作,因为生计或者其他种种原因,大家从事的行业开始有了变化,从而导致开发语言也有了一些变化,一些做后端的,开始使用Java,C++等等,一些做前端的开始用php,js等等。

然而,当我们用一门语言很久之后,就会对这门语言有了更多更深刻的了解,优点缺点、解决方案等等,而且大部分人会有一中喜新厌旧的心里,再加上市面上的新语言、新特性层出不绝,特别是看到那些你曾经花了很大精力想了各种奇淫技巧解决了一个问题,而在某些新语言中这只是一个普通特性,所以大家难免会心里痒痒,“我要不要学这个新语言,我要不要在工作环境中使用这个语言?”

这篇文章我就两方面讲下什么时候需要学一门编程语言,一个是学新语言是否真的对你的开发工作有帮助,一个是你的生活工作环境中是否允许你用新的语言。因为我是从事游戏服务器开发,主要语言是C++,而我打算学习C#,以下的内容就用这两门语言做例子。

学新语言是否真的对你的开发工作有帮助?

我们学习任何东西都是建立在有需要的情况下,如果知识不能转化成财富,估计很少有人会去上学。所以学一门新的编程语言是否对我们有帮助是很重要的,不过如果你只是单纯的兴趣,那倒是无所谓。学习新语言的原因基本分为下面几种:

  • 现在的语言太复杂,很多特性非常老,实现功能起来很纠结,需要一门简单实用的新语言快速解决问题,新语言简洁高效,特性强大
  • 现在的语言需要大量的第三方库,而新语言自带平常开发的大部分库
  • 现在的语言开发效率太低,新语言分分钟撸一个功能模块出来

上面的几点,总结起来就是现在的语言用起来很不爽,需要新语言来帮助我提高效率。

简单高效一直是现代编程语言的核心思想,通过C++ 11,14,17标准我们很明显的看出来,C++当初为了兼容C(挖C程序员的墙角),做了很多现在看来很纠结的东西,而新标准就是在改善这块东西。我们团队维护的NFrame C++版本,到了现在又开始用C#语言做一个,核心思想没变,只是单纯的换个语言,现在核心功能已经换完了,只花了两周多的时间,一个库都没依赖,只依赖了.Net Framework,杂七杂八架起来只有10M多,而C++版本库解压后有近1G,从开发和维护成本上来说,都是C#更胜一筹。再加上现在MS本身已经开始支持跨平台了,或者mono,跨平台根本不是问题。

这个例子可以看出,新的语言C#确实提高了我们的开发效率,而C#的Task等等特性和内容,已经将我们再C++上纠结的Actor模式完全替代了,让我们可以安心做功能设计,而不是纠结语言层面的实现问题。

而且新语言一般都是通杀的,web,UI,back-end等,基本都支持,C#,js,Java都是前后端通杀,适合大部分领域和行业。

//TODO

 

生活工作环境中是否允许你用新的语言?

俗话说兴趣是最好的老师,当你对某个事物有了兴趣之后,自然就有学习的动力了。但是我们都不是一个人在战斗,多多少少都会有合作的同事、朋友,小到自己的简单开源项目,大到公司的大项目,所以工作生活中都是多个人在合作,做任何事情都不能一意孤行,自己喜欢某种编程语言就大用特用,毕竟团队整体的效率才是执行力,现在已经不是个人英雄主义的时代了,保持合作交流才能有更大的进步。团队做出来的东西才是外面比较看重的,技术不是决定性因素,而项目产品才是提升自己价值的东西,离开团队这个平台,一身是铁打几根钉子?面面俱到方能做到完美。

 

暂时想到的就是这么多了,大家可以继续补充讨论。

此文是根据杨尚刚在【QCON高可用架构群】中,针对MySQL在单表海量记录等场景下,业界广泛关注的MySQL问题的经验分享整理而成,转发请注明出处。

杨尚刚,美图公司数据库高级DBA,负责美图后端数据存储平台建设和架构设计。前新浪高级数据库工程师,负责新浪微博核心数据库架构改造优化,以及数据库相关的服务器存储选型设计。

前言

MySQL数据库大家应该都很熟悉,而且随着前几年的阿里的去IOE,MySQL逐渐引起更多人的重视。

MySQL历史

  • 1979年,Monty Widenius写了最初的版本,96年发布1.0
  • 1995-2000年,MySQL AB成立,引入BDB
  • 2000年4月,集成MyISAM和replication
  • 2001年,Heikki Tuuri向MySQL建议集成InnoDB
  • 2003发布5.0,提供了视图、存储过程等功能
  • 2008年,MySQL AB被Sun收购,09年推出5.1
  • 2009年4月,Oracle收购Sun,2010年12月推出5.5
  • 2013年2月推出5.6 GA,5.7开发中

MySQL的优点

  • 使用简单
  • 开源免费
  • 扩展性“好”,在一定阶段扩展性好
  • 社区活跃
  • 性能可以满足互联网存储和性能需求,离不开硬件支持

上面这几个因素也是大多数公司选择考虑MySQL的原因。不过MySQL本身存在的问题和限制也很多,有些问题点也经常被其他数据库吐槽或鄙视

MySQL存在的问题

  • 优化器对复杂SQL支持不好
  • 对SQL标准支持不好
  • 大规模集群方案不成熟,主要指中间件
  • ID生成器,全局自增ID
  • 异步逻辑复制,数据安全性问题
  • Online DDL
  • HA方案不完善
  • 备份和恢复方案还是比较复杂,需要依赖外部组件
  • 展现给用户信息过少,排查问题困难
  • 众多分支,让人难以选择

看到了刚才讲的MySQL的优势和劣势,可以看到MySQL面临的问题还是远大于它的优势的,很多问题也是我们实际需要在运维中优化解决的,这也是MySQL DBA的一方面价值所在。并且MySQL的不断发展也离不开社区支持,比如Google最早提交的半同步patch,后来也合并到官方主线。Facebook Twitter等也都开源了内部使用MySQL分支版本,包含了他们内部使用的patch和特性。

数据库开发规范

数据库开发规范定义:开发规范是针对内部开发的一系列建议或规则, 由DBA制定(如果有DBA的话)。

开发规范本身也包含几部分:基本命名和约束规范,字段设计规范,索引规范,使用规范。

规范存在意义

  • 保证线上数据库schema规范
  • 减少出问题概率
  • 方便自动化管理
  • 规范需要长期坚持,对开发和DBA是一个双赢的事情

想想没有开发规范,有的开发写出各种全表扫描的SQL语句或者各种奇葩SQL语句,我们之前就看过开发写的SQL 可以打印出好几页纸。这种造成业务本身不稳定,也会让DBA天天忙于各种救火。

基本命名和约束规范

  • 表字符集选择UTF8 ,如果需要存储emoj表情,需要使用UTF8mb4(MySQL 5.5.3以后支持)
  • 存储引擎使用InnoDB
  • 变长字符串尽量使用varchar varbinary
  • 不在数据库中存储图片、文件等
  • 单表数据量控制在1亿以下
  • 库名、表名、字段名不使用保留字
  • 库名、表名、字段名、索引名使用小写字母,以下划线分割 ,需要见名知意
  • 库表名不要设计过长,尽可能用最少的字符表达出表的用途

字段规范

  • 所有字段均定义为NOT NULL ,除非你真的想存Null
  • 字段类型在满足需求条件下越小越好,使用UNSIGNED存储非负整数 ,实际使用时候存储负数场景不多
  • 使用TIMESTAMP存储时间
  • 使用varchar存储变长字符串 ,当然要注意varchar(M)里的M指的是字符数不是字节数;使用UNSIGNED INT存储IPv4 地址而不是CHAR(15) ,这种方式只能存储IPv4,存储不了IPv6
  • 使用DECIMAL存储精确浮点数,用float有的时候会有问题
  • 少用blob text

关于为什么定义不使用Null的原因

* 1.浪费存储空间,因为InnoDB需要有额外一个字节存储

* 2.表内默认值Null过多会影响优化器选择执行计划

关于使用datatime和timestamp,现在在5.6.4之后又有了变化,使用二者存储在存储空间上大差距越来越小 ,并且本身datatime存储范围就比timestamp大很多,timestamp只能存储到2038年

索引规范

  • 单个索引字段数不超过5,单表索引数量不超过5,索引设计遵循B+ Tree索引最左前缀匹配原则
  • 选择区分度高的列作为索引
  • 建立的索引能覆盖80%主要的查询,不求全,解决问题的主要矛盾
  • DML和order by和group by字段要建立合适的索引
  • 避免索引的隐式转换
  • 避免冗余索引

关于索引规范,一定要记住索引这个东西是一把双刃剑,在加速读的同时也引入了很多额外的写入和锁,降低写入能力,这也是为什么要控制索引数原因。之前看到过不少人给表里每个字段都建了索引,其实对查询可能起不到什么作用。

冗余索引例子

  • idx_abc(a,b,c)
  • idx_a(a) 冗余
  • idx_ab(a,b) 冗余

隐式转换例子

字段:remark varchar(50) NOT Null

MySQL>SELECT id, gift_code FROM gift WHERE deal_id = 640 AND remark=115127; 1 row in set (0.14 sec)

MySQL>SELECT id, gift_code FROM pool_gift WHEREdeal_id = 640 AND remark=‘115127’; 1 row in set (0.005 sec)

字段定义为varchar,但传入的值是个int,就会导致全表扫描,要求程序端要做好类型检查

SQL类规范

  • 尽量不使用存储过程、触发器、函数等
  • 避免使用大表的JOIN,MySQL优化器对join优化策略过于简单
  • 避免在数据库中进行数学运算和其他大量计算任务
  • SQL合并,主要是指的DML时候多个value合并,减少和数据库交互
  • 合理的分页,尤其大分页
  • UPDATE、DELETE语句不使用LIMIT ,容易造成主从不一致

数据库运维规范

运维规范主要内容

  • SQL审核,DDL审核和操作时间,尤其是OnlineDDL
  • 高危操作检查,Drop前做好数据备份
  • 权限控制和审计
  • 日志分析,主要是指的MySQL慢日志和错误日志
  • 高可用方案
  • 数据备份方案

版本选择

  • MySQL社区版,用户群体最大
  • MySQL企业版,收费
  • Percona Server版,新特性多
  • MariaDB版,国内用户不多

建议选择优先级为:MySQL社区版 > Percona Server > MariaDB > MySQL 企业版

不过现在如果大家使用RDS服务,基本还以社区版为主

Online DDL问题

原生MySQL执行DDL时需要锁表,且锁表期间业务是无法写入数据的,对服务影响很大,MySQL对这方面的支持是比较差的。大表做DDL对DBA来说是很痛苦的,相信很多人经历过。如何做到Online DDL呢,是不是就无解了呢?当然不是!

上面表格里提到的 Facebook OSC和5.6 OSC也是目前两种比较靠谱的方案

MySQL 5.6的OSC方案还是解决不了DDL的时候到从库延时的问题,所以现在建议使用Facebook OSC这种思路更优雅

下图是Facebook OSC的思路

后来Percona公司根据Facebook OSC思路,用perl重写了一版,就是我们现在用得很多的pt-online-schema-change,软件本身非常成熟,支持目前主流版本。

使用pt-online-schema-change的优点有:

  • 1.无阻塞写入
  • 2.完善的条件检测和延时负载策略控制

值得一提的是,腾讯互娱的DBA在内部分支上也实现了Online DDL,之前测试过确实不错,速度快,原理是通过修改InnoDB存储格式来实现。

使用pt-online-schema-change的限制有:

  • 改表时间会比较长(相比直接alter table改表)
  • 修改的表需要有唯一键或主键
  • 在同一端口上的并发修改不能太多

可用性

关于可用性,我们今天分享一种无缝切主库方案,可以用于日常切换,使用思路也比较简单

在正常条件下如何无缝去做主库切换,核心思路是让新主库和从库停在相同位置,主要依赖slave start until 语句,结合双主结构,考虑自增问题。

MySQL集群方案:

  • 集群方案主要是如何组织MySQL实例的方案
  • 主流方案核心依然采用的是MySQL原生的复制方案
  • 原生主从同步肯定存在着性能和安全性问题

MySQL半同步复制:

现在也有一些理论上可用性更高的其它方案

  • Percona XtraDB Cluster(没有足够的把控力度,不建议上)
  • MySQL Cluster(有官方支持,不过实际用的不多)

红框内是目前大家使用比较多的部署结构和方案。当然异常层面的HA也有很多第三方工具支持,比如MHA、MMM等,推荐使用MHA

sharding拆分问题

  • Sharding is very complex, so itʼs best not to shard until itʼs obvious that you will actually need to!
  • sharding是按照一定规则数据重新分布的方式
  • 主要解决单机写入压力过大和容量问题
  • 主要有垂直拆分和水平拆分两种方式
  • 拆分要适度,切勿过度拆分
  • 有中间层控制拆分逻辑最好,否则拆分过细管理成本会很高

曾经管理的单表最大60亿+,单表数据文件大小1TB+,人有时候就要懒一些

上图是水平拆分和垂直拆分的示意图

数据库备份

首先要保证的,最核心的是数据库数据安全性。数据安全都保障不了的情况下谈其他的指标(如性能等),其实意义就不大了。

备份的意义是什么呢?

  • 数据恢复!
  • 数据恢复!
  • 数据恢复!

目前备份方式的几个纬度:

  • 全量备份 VS 增量备份
  • 热备 VS 冷备
  • 物理备份 VS 逻辑备份
  • 延时备份
  • 全量binlog备份

建议方式:

  • 热备+物理备份
  • 核心业务:延时备份+逻辑备份
  • 全量binlog备份

借用一下某大型互联网公司做的备份系统数据:一年7000+次扩容,一年12+次数据恢复,日志量每天3TB,数据总量2PB,每天备份数据量百TB级,全年备份36万次,备份成功了99.9%。

主要做的几点:

  • 备份策略集中式调度管理
  • xtrabackup热备
  • 备份结果统计分析
  • 备份数据一致性校验
  • 采用分布式文件系统存储备份

备份系统采用分布式文件系统原因:

  • 解决存储分配的问题
  • 解决存储NFS备份效率低下问题
  • 存储集中式管理
  • 数据可靠性更好

使用分布式文件系统优化点:

* Pbzip压缩,降低多副本存储带来的存储成本,降低网络带宽消耗

* 元数据节点HA,提高备份集群的可用性

* erasure code方案调研

数据恢复方案

目前的MySQL数据恢复方案主要还是基于备份来恢复,可见备份的重要性。比如我今天下午15点删除了线上一张表,该如何恢复呢?首先确认删除语句,然后用备份扩容实例启动,假设备份时间点是凌晨3点,就还需要把凌晨3点到现在关于这个表的binlog导出来,然后应用到新扩容的实例上,确认好恢复的时间点,然后把删除表的数据导出来应用到线上。

性能优化

复制优化

MySQL复制:

  • 是MySQL应用得最普遍的应用技术,扩展成本低
  • 逻辑复制
  • 单线程问题,从库延时问题
  • 可以做备份或读复制

问题很多,但是能解决基本问题

上图是MySQL复制原理图,红框内就是MySQL一直被人诟病的单线程问题

单线程问题也是MySQL主从延时的一个重要原因,单线程解决方案:

  • 官方5.6+多线程方案
  • Tungsten为代表的第三方并行复制工具
  • sharding

上图是MySQL5.6 目前实现的并行复制原理图,是基于库级别的复制,所以如果你只有一个库,使用这个意义不大

当然MySQL也认识到5.6这种并行的瓶颈所在,所以在5.7引入了另外一种并行复制方式,基于logical timestamp的并行复制,并行复制不再受限于库的个数,效率会大大提升

上图是5.7的logical timestamp的复制原理图

刚才我也提到MySQL原来只支持异步复制,这种数据安全性是非常差的,所以后来引入了半同步复制,从5.5开始支持

上图是原生异步复制和半同步复制的区别。可以看到半同步通过从库返回ACK这种方式确认从库收到数据,数据安全性大大提高

在5.7之后,半同步也可以配置你指定多个从库参与半同步复制,之前版本都是默认一个从库

对于半同步复制效率问题有一个小的优化,就是使用5.6+的mysqlbinlog以daemon方式作为从库,同步效率会好很多

关于更安全的复制,MySQL 5.7也是有方案的,方案名叫Group replication 官方多主方案,基于Corosync实现

主从延时问题

原因:一般都会做读写分离,其实从库压力反而比主库大/从库读写压力大非常容易导致延时。

解决方案:

  • 首先定位延时瓶颈
  • 如果是IO压力,可以通过升级硬件解决,比如替换SSD等
  • 如果IO和CPU都不是瓶颈,非常有可能是SQL单线程问题,解决方案可以考虑刚才提到的并行复制方案
  • 如果还有问题,可以考虑sharding拆分方案

提到延时不得不提到很坑人的Seconds behind master,使用过MySQL的应该很熟悉

这个值的源码里算法

long time_diff= ((long)(time(0) – mi->rli.last_master_timestamp) – mi->clock_diff_with_master);

Secondsbehindmaster来判断延时不可靠,在网络抖动或者一些特殊参数配置情况下,会造成这个值是0但其实延时很大了。通过heartbeat表插入时间戳这种机制判断延时是更靠谱的

复制注意点:

  • Binlog格式,建议都采用row格式,数据一致性更好
  • Replication filter应用

主从数据一致性问题:

  • row格式下的数据恢复问题

InnoDB优化

成熟开源事务存储引擎,支持ACID,支持事务四个隔离级别,更好的数据安全性,高性能高并发,MVCC,细粒度锁,支持O_DIRECT。

主要优化参数:

  • innodbfileper_table =1
  • innodbbufferpool_size,根据数据量和内存合理设置
  • innodbflushlog_attrxcommit= 0 1 2
  • innodblogfile_size,可以设置大一些
  • innodbpagesize
  • Innodbflushmethod = o_direct
  • innodbundodirectory 放到高速设备(5.6+)
  • innodbbufferpool_dump
  • atshutdown ,bufferpool dump (5.6+)

上图是5.5 4G的redo log和5.6 设置大于4G redo log文件性能对比,可以看到稳定性更好了。innodblogfile_size设置还是很有意义的

InnoDB比较好的特性:

  • Bufferpool预热和动态调整大小,动态调整大小需要5.7支持
  • Page size自定义调整,适应目前硬件
  • InnoDB压缩,大大降低数据容量,一般可以压缩50%,节省存储空间和IO,用CPU换空间
  • Transportable tablespaces,迁移ibd文件,用于快速单表恢复
  • Memcached API,full text,GIS等

InnoDB在SSD上的优化:

  • 在5.5以上,提高innodbwriteiothreads和innodbreadiothreads
  • innodbiocapacity需要调大
  • 日志文件和redo放到机械硬盘,undo放到SSD,建议这样,但必要性不大
  • atomic write,不需要Double Write Buffer
  • InnoDB压缩
  • 单机多实例

也要搞清楚InnoDB哪些文件是顺序读写,哪些是随机读写

随机读写:

  • datadir
  • innodbdata file_path
  • innodbundo directory

顺序读写:

  • innodbloggrouphomedir
  • log-bin

InnoDB VS MyISAM:

  • 数据安全性至关重要,InnoDB完胜,曾经遇到过一次90G的MyISAM表repair,花了两天时间,如果在线上几乎不可忍受
  • 并发度高
  • MySQL 5.5默认引擎改为InnoDB,标志着MyISAM时代的落幕

TokuDB:

  • 支持事务 ACID 特性,支持多版本控制(MVCC)
  • 基于Fractal Tree Index,非常适合写入密集场景
  • 高压缩比,原生支持Online DDL
  • 主流分支都支持,收费转开源 。目前可以和InnoDB媲美的存储引擎

目前主流使用TokuDB主要是看中了它的高压缩比,Tokudb有三种压缩方式:quicklz、zlib、lzma,压缩比依次更高。现在很多使用zabbix的后端数据表都采用的TokuDB,写入性能好,压缩比高。

下图是我之前做的测试对比和InnoDB

上图是sysbench测试的和InnoDB性能对比图,可以看到TokuDB在测试过程中写入稳定性是非常好的。

tokudb存在的问题:

  • 官方分支还没很好的支持
  • 热备方案问题,目前只有企业版才有
  • 还是有bug的,版本更新比较快,不建议在核心业务上用

比如我们之前遇到过一个问题:TokuDB的内部状态显示上一次完成的checkpoint时间是“Jul 17 12:04:11 2014”,距离当时发现现在都快5个月了,结果堆积了大量redo log不能删除,后来只能重启实例,结果重启还花了七八个小时

MySQL优化相关的case

Query cache,MySQL内置的查询加速缓存,理念是好的,但设计不够合理,有点out。

锁的粒度非常大MySQL 5.6默认已经关闭

When the query cache helps, it can help a lot. When it hurts, it can hurt a lot.明显前半句已经没有太大用处,在高并发下非常容易遇到瓶颈。

关于事务隔离级别 ,InnoDB默认隔离级别是可重复读级别,当然InnoDB虽然是设置的可重复读,但是也是解决了幻读的,建议改成读已提交级别,可以满足大多数场景需求,有利于更高的并发,修改transaction-isolation。

上图是一个比较经典的死锁case,有兴趣可以测试下

关于SSD

关于SSD,还是提一下吧。某知名大V说过“最近10年对数据库性能影响最大的是闪存”,稳定性和性能可靠性已经得到大规模验证,多块SATA SSD做Raid5,推荐使用。采用PCIe SSD,主流云平台都提供SSD云硬盘支持。

最后说一下大家关注的单表60亿记录问题,表里数据也是线上比较核心的。

先说下当时情况,表结构比较简单,都是bigint这种整型,索引比较多,应该有2-3个,单表行数60亿+,单表容量1.2TB左右,当然内部肯定是有碎片的。

形成原因:历史遗留问题,按照我们前面讲的开发规范,这个应该早拆分了,当然不拆有几个原因:

  1. 性能未遇到瓶颈 ,主要原因
  2. DBA比较“懒“
  3. 想看看InnoDB的极限,挑战一下。不过风险也是很大的,想想如果在一个1.2TB表上加个字段加个索引,那感觉绝对酸爽。还有就是单表恢复的问题,恢复时间不可控。

我们后续做的优化 ,采用了刚才提到的TokuDB,单表容量在InnoDB下1TB+,使用Tokudb的lzma压缩到80GB,压缩效果非常好。这样也解决了单表过大恢复时间问题,也支持online DDL,基本达到我们预期。

今天讲的主要针对MySQL本身优化和规范性质的东西,还有一些比较好的运维经验,希望大家能有所收获。今天这些内容是为后续数据库做平台化的基础。我今天分享就到这里,谢谢大家。

QA

Q1:use schema;select * from table; 和select * from schema.table;两种写法有什么不一样吗?会对主从同步有影响吗?

对于主从复制来说执行效率上差别不大,不过在使用replication filter时候这种情况需要小心,应该要使用ReplicateWildIgnoreTable这种参数,如果不使用带wildignore,第一种方式会有问题,过滤不起作用。

Q2:对于用于MySQL的ssd,测试方式和ssd的参数配置方面,有没有好的建议?主要针对ssd的配置哈

关于SATA SSD配置参数,建议使用Raid5,想更保险使用Raid50,更土豪使用Raid 10

上图是主要的参数优化,性能提升最大的是第一个修改调度算法的

Q3:数据库规范已制定好,如何保证开发人员必须按照规范来开发?

关于数据库规范实施问题,也是有两个方面吧,第一、定期给开发培训开发规范,让开发能更了解。第二、还是在流程上规范,比如把我们日常通用的建表和字段策略固化到程序,做成自动化审核系统。这两方面结合 效果会比较好。

Q4:如何最大限度提高innodb的命中率?

这个问题前提是你的数据要有热点,读写热点要有交集,否则命中率很难提高。在有热点的前提下,也要求你的你的内存要足够大,能够存更多的热点数据。尽量不要做一些可能污染bufferpool的操作,比如全表扫描这种。

Q5:主从复制的情况下,如果有CAS这样的需求,是不是只能强制连主库?因为有延迟的存在,如果读写不在一起的话,会有脏数据。

如果有CAS需求,确实还是直接读主库好一些,因为异步复制还是会有延迟的。只要SQL优化的比较好,读写都在主库也是没什么问题的。

Q6:关于开发规范,是否有必要买国标?

这个国标是什么东西,不太了解。不过从字面看,国标应该也是偏学术方面的,在具体工程实施时候未必能用好。

Q7:主从集群能不能再细化一点那?不知道这样问合适不?

看具体哪方面吧。主从集群每个小集群一般都是采用一主多从方式,每个小集群对应特定的一组业务。然后监控备份和HA都是在每个小集群实现。

Q8:如何跟踪数据库table某个字段值发生变化?

追踪字段值变化可以通过分析row格式binlog好一些。比如以前同事就是通过自己开发的工具来解析row格式binlog,跟踪数据行变化。

Q9:对超大表水平拆分,在使用MySQL中间件方面有什么建议和经验分享?

对于超大表水平拆分,在中间件上经验不是很多,早期人肉搞过几次。也使用过自己研发的数据库中间件,不过线上应用的规模不大。关于目前众多的开源中间件里,360的atlas是目前还不错的,他们公司内部应用的比较多。

Q10:我们用的MySQL proxy做读负载,但是少量数据压力下并没有负载,请问有这回事吗?

少量数据压力下,并没有负载 ,这个没测试过,不好评价

Q11:对于binlog格式,为什么只推荐row,而不用网上大部分文章推荐的Mix ?

这个主要是考虑数据复制的可靠性,row更好。mixed含义是指如果有一些容易导致主从不一致的SQL ,比如包含UUID函数的这种,转换为row。既然要革命,就搞的彻底一些。这种mix的中间状态最坑人了。

Q12: 读写分离,一般是在程序里做,还是用proxy ,用proxy的话一般用哪个?

这个还是独立写程序好一些,与程序解耦方便后期维护。proxy国内目前开源的比较多,选择也要慎重。

Q13: 我想问一下关于mysql线程池相关的问题,什么情况下适合使用线程池,相关的参数应该如何配置,老师有这方面的最佳实践没有?

线程池这个我也没测试过。从原理上来说,短链接更适合用线程池方式,减少建立连接的消耗。这个方面的最佳配置,我还没测试过,后面测试有进展可以再聊聊。

Q14: 误删数据这种,数据恢复流程是怎么样的(从库也被同步删除的情况)?

看你删除数据的情况,如果只是一张表,单表在几GB或几十GB。如果能有延时备份,对于数据恢复速度是很有好处的。恢复流程可以参考我刚才分享的部分。目前的MySQL数据恢复方案主要还是基于备份来恢复 ,可见备份的重要性。比如我今天下午15点删除了线上一张表,该如何恢复呢。首先确认删除语句,然后用备份扩容实例启动,假设备份时间点是凌晨3点。就还需要把凌晨3点到现在关于这个表的binlog导出来,然后应用到新扩容的实例上。确认好恢复的时间点,然后把删除表的数据导出来应用到线上。

Q15: 关于备份,binlog备份自然不用说了,物理备份有很多方式,有没有推荐的一种,逻辑备份在量大的时候恢复速度比较慢,一般用在什么场景?

物理备份采用xtrabackup热备方案比较好。逻辑备份一般用在单表恢复效果会非常好。比如你删了一个2G表,但你总数据量2T,用物理备份就会要慢了,逻辑备份就非常有用了。

想和群内专家继续交流MySQL相关技术,请关注公众号后,回复arch,申请进群。

本文策划 庆丰@微博, 内容由王杰编辑,刘伟@途牛、陈刚@北京智识 校对与发布,其他多位志愿者对本文亦有贡献。读者可以通过搜索“ArchNotes”或长按下面图片,关注“高可用架构”公众号,查看更多架构方面内容,获取通往架构师之路的宝贵经验。转载请注明来自“高可用架构(ArchNotes)”公众号,敬请包含二维码!

提前多说一句:后续的文章不会是直接发一整篇文章出来,而是有点顺手笔记的意思,想到哪儿写到哪儿,可能会写不完一片,会用TODO来标识出来,也有可能会跳过某一段直接写后面,写完后可能还会重新在整理,大家请知晓。

继续阅读 Docker初窥

性能优化(图片来自网络)
性能优化(图片来自网络)

本文是为了记录下《QMWS》项目服务器在对外测试期间,性能表现和技术审核时的性能表现差距很大,从而做出的一些优化过程,期间还是比较头疼,接近两个连续通宵来修改。第一个通宵一直在查找问题和猜问题,找问题是如何出现的,第二天主要是解决对应的性能问题。

性能问题主要集中在:

内存使用过快

内存泄露

某些时间内协议过多

逻辑功能处理不当

其他网络消耗什么的暂时也没有考虑,下面详细说说这几个问题是如何引起的以及如何一步步解决的。

1.内存使用过快问题

我们项目使用的是C++后端,用了团队主程之前写的,后来我参与开发的一个开源的服务器数据管理框架NFrame,下面是github地址。

GitHub 仓库挂件 WordPress 插件

ketoo / NoahGameFrame

A fast, scalable, distributed game server engine/framework for C++, include actor library, network library,can be used as a real time multiplayer game engine ( MMO RPG/MOBA ), which support C#/Lua script/ Unity3d, Cocos2dx and plan to support Unreal.

https://github.com/ketoo/NoahGameFrame/wiki

这个框架就不多做介绍了,有兴趣可以从github pull下来研究研究,或者加群讨论。

这个框架的主要问题就是小的变量和内存申请太多了,导致产生了很多碎片,在linux系统上回收不够及时导致的,而且我们错误的估计了shared_ptr的能力了,智能指针确实能减少很多内存管理,但是生命周期却不好把握,所以我们临时用了大google的TCMalloc,每5分钟主动回收一次内存,确实解决了我们的问题。

2.内存泄漏

内存泄漏这块主要的问题还是代码上的漏洞,逻辑不够严谨,释放对象的时候因为一些判断导致对象没有被释放。还有就是一些数据管理上的问题,不是特别严重。

3.某些操作下逻辑处理过多

因为NFrame采用的是事件回调的方式来处理数据变动,我们会在自己感兴趣的属性(Property)和表(Record)数据上注册回调函数,从而做一些逻辑。这个时候就得特别注意逻辑需求了,因为某些时候属性会有多次变化,导致多次计算其他属性,我们遇到的问题就是当属性变化时计算多个武将的战斗力,如果某个操作导致了多个属性变化,就会导致成倍的战斗力计算,加重了逻辑负担。修改方式是去掉部分回调,在逻辑操作中特定的时候处理回调做的事情,从而降低调用次数。

4.逻辑功能处理不当

这个就是一些常见的问题了,经过重构整理以及性能测试就可以很好的看出来问题,就不多说了。

 

推荐的一些工具:

VLD C++内存泄漏检查工具

VTune C++性能内存检查工具,完美和VS IDE结合,非常好用

Valgrind linux下内存检查工具,缺点是没有IDE环境,报告不太容易看,不过分析还是蛮准确的

Border check(DevPartner) 自动化测试/覆盖性测试工具,大borland(估计很多人都没听过了)出品,业界一流产品

 

好的结果是问题基本已经排查到了,所以后续的版本测试基本没有特别大的性能问题,不过还是得争取高的压测结果。

PS:线上环境和本地测试还是有很大差距,前些天看到一个测试方法,觉得很有意思,与大家分享下。是通过线上开一台功能服务器A,然后再开一台同样的功能服务器B,A和B做的事情完全相同,A是对外服务,B是内部测试服务器,A多做一件事情,将收到的消息顺便转发到B,B再按照收到的协议做处理,这样通过观察B的数据和性能就能模拟线上环境,从而更容易发现问题处理问题,这个东西github上也有对应的项目,叫TCP Copy,有兴趣的朋友可以看看。

已经很久没有更新过博客了,主要原因还是因为老样子——事情太多了,每天都在瞎忙活。之前几个月一直都在忙结婚的事情,拍婚纱照什么的事情还是比较多,不过好的结局是在九月初在老家接了婚,完成人生一件非常重要的事情。

最近博客不更新主要的原因是:真的不知道写什么,写C++技术吧,写什么内容才能脱颖而出,毕竟网上文章一大把一大把的,写好了最多是持平,写差了就不好办了,脸面是小,误人子弟是大,所以一直在琢磨搞点什么呢?最近接触的东西都很杂,简单看了集中其他编程语言,发现都很优秀,C++还是太老了,发展也有点慢,导致我现在都想换域名了。

后面会写一篇关于为什么要换语言的文章,简单写写,没有褒贬任何语言的意思。后续的博文不会再关注语言了,得弄点高达上的东西了,语言的格局还是有点小。主要会集中在架构、分布式等稍微抽象点的东西,单纯的技术展示还不如在思想上有进步呢。

大概说下后面会分享的文章:服务器架构设计,分布式数据库设计,分布式思想、actor,其他语言。

C++并不是说直接就不用了或者放在箱底儿了,大多数时间还是C++,不过是不会再纠结语言或者类库的层面了,该是时候进一步了。

大家共勉,欢迎多沟通。

作者: 阮一峰

日期: 2015年9月18日

Nicholas C. Zakas 是全世界最著名的 JavaScript 程序员之一。

两年前,他写了一篇长文,回顾自己的职业生涯,提到七个对他来说最重要的建议。

我读完很受启发,决定做一点摘录。你可以先读下面的精简版,再去读全文

===============================

七个对我最好的职业建议(精简版)

作者:Nicholas C. Zakas

译者:阮一峰

原文网址:https://www.nczonline.net/blog/2013/10/15/the-best-career-advice-ive-received/

一、不要别人点什么,就做什么

我的第一份工作,只干了8个月,那家公司就倒闭了。我问经理,接下来我该怎么办,他说:

“小伙子,千万不要当一个被人点菜的厨师,别人点什么,你就烧什么。不要接受那样一份工作,别人下命令你该干什么,以及怎么干。你要去一个地方,那里的人肯定你对产品的想法,相信你的能力,放手让你去做。”

我从此明白,单单实现一个产品是不够的,你还必须参与决定怎么实现。好的工程师并不仅仅服从命令,而且还给出反馈,帮助产品的拥有者改进它。

二、推销自己

我进入雅虎公司以后,经理有一天跟我谈话,他觉得我还做得不够。

“你工作得很好,代码看上去不错,很少出Bug。但是,问题是别人都没看到这一点。为了让其他人相信你,你必须首先让别人知道你做了什么。你需要推销自己,引起别人的注意。”

我这才意识到,即使做出了很好的工作,别人都不知道,也没用。做一个角落里静静编码的工程师,并不可取。你的主管会支持你,但是他没法替你宣传。公司的其他人需要明白你的价值,最好的办法就是告诉别人你做了什么。一封简单的Email:”嗨,我完成了XXX,欢迎将你的想法告诉我”,就很管用。

三、学会带领团队

工作几年后,已经没人怀疑我的技术能力了,大家知道我能写出高质量的可靠代码。有一次,我问主管,怎么才能得到提升,他说:

“当你的技术能力过关以后,就要考验你与他人相处的能力了。”

于是,我看到了,自己缺乏的是领导能力,如何带领一个团队,有效地与其他人协同工作,取到更大的成果。

四、生活才是最重要的

有一段时间,我在雅虎公司很有挫折感,对公司的一些做法不认同,经常会对别人发火。我问一个同事,他怎么能对这种事情保持平静,他回答:

“你要想通,这一切并不重要。有人提交了烂代码,网站下线了,又怎么样?工作并不是你的整个生活。它们不是真正的问题,只是工作上的问题。真正重要的事情都发生在工作以外。我回到家,家里人正在等我,这才重要啊。”

从此,我就把工作和生活分开了,只把它当作”工作问题”看待。这样一来,我对工作就总能心平气和,与人交流也更顺利了。

五、自己找到道路

我被提升为主管以后,不知道该怎么做。我请教了上级,他回答:

“以前都是我们告诉你做什么,从现在开始,你必须自己回答这个问题了,我期待你来告诉我,什么事情需要做。”

很多工程师都没有完成这个转变,如果能够做到,可能就说明你成熟了,学会了取舍。你不可能把时间花在所有事情上面,必须找到一个重点。

六、把自己当成主人

我每天要开很多会,有些会议我根本无话可说。我对一个朋友说,我不知道自己为什么要参加这个会,也没有什么可以贡献,他说:

“不要再去开这样的会了。你参加一个会,那是因为你参与了某件事。如果不确定自己为什么要在场,就停下来问。如果这件事不需要你,就离开。不要从头到尾都静静地参加一个会,要把自己当成负责人,大家会相信你的。”

从那时起,我从没有一声不发地参加会议。我确保只参加那些需要我参加的会议。

七、找到水平更高的人

最后,让我从自己的经历出发,给我的读者一个建议。

“找到那些比你水平更高、更聪明的人,尽量和他们在一起,吃饭或者喝咖啡,向他们讨教,了解他们拥有的知识。你的职业,甚至你的生活,都会因此变得更好。”

(完)

原文出处:阮一峰的网络日志