[转自coolshell] 《REWORK》摘录及感想

《REWORK》摘录及感想

读了《Rework》这本书好多遍,每次读都有不同的感想。但从来没有把这些感想记录下来,今天把《Rework》书中的一些章节做一些摘录,并把我的一些感想总结出来。供大家参考。这是一本平生以来让我中毒很深的书,也是一本让我思考得很多的书。希望看到这篇文章的人都能好好地读读这本书。这本书并不难读,是一本你可以一口气不中断就可以读完的书。

现实世界

“这在现实世界里面行不通”,当你向人们介绍一个新创意时,人们总是这么回答你。这个“现实世界”听起来如此令人沮丧,……只有人耳熟能详,习以为常的事情才会胜利,即使是这些事情已经漏洞百出陈腐低效。

揭开“现实世界”这个锅盖,你会发现居住在里的人都充斥着悲观主义和失望的情绪。更糟的是,他们想将别人拖进他们的坟墓。如果你是充满希望和野心的人,他们会试着说服你,你的想法是不可能的。他们会说你在浪费时间。

“现实世界”并不存在,那只是人的一个借口。只是某些人为了开脱 自己的无所作为,跟你一点关系也没有。

感想:我经常会向一同事和朋友提及一些我的想法,朋友同事们经常会回答我——这个事某某人,某某团队做过了,没成功。或是对我说,你做这个事的时候,要小心这个要小心那个。我觉得,这个时候是最考验我们的时候了,要有一个清醒的头脑去分析别人的话,别人真不代表自己。这个世界上大多数人都是比较保守的,大多数都对这个现实世界都有或多或少的恐惧感。当然,你可以选择做大众,但是如果你想让你的人生有些不同,有些精彩,我还是建议你不要和大多数人想得一样,如果你和大多数人的想法一样,你必然会和大多数人一样的平庸。当然,如果你和大多数人不一样,你要么就是天才,要么就是傻瓜。要证明你自己是不是傻瓜,我们可以看看我们过去有没有过一些小成功或小成绩。如果有,那么就应该大胆地坚持自己的想法。

被高估的“从错误中学习”

你真的从错误和失败里面学到什么了吗?你也许学到了别再重蹈覆辙,但是这有什么意义吗?你仍然不知道接下来该做什么。

相反的应该从成功中汲取养分。成功給予真正靠得住的教材。

失败并不是成功的先决条件。自然规律是,逗留在过去的失败中是无法进化的,进化是建立在成功的基础上的

感想:我见过和很多人都在抱怨这不好那不好,但是他们其实并不知道什么是好的,因为——没有见过好的,你将永远不知道什么是好的。就好像你没有见过什么是汽车,你就只会整天在抱怨为什么骑自行车太累。回头想想我们的编程的这个过程也是一样,我们编程技能的提高基本上都是在看到别人的那些漂亮优雅的代码。所以,你一定要去看看那些优秀人干是怎么想的,怎么干的,去那些成功的公司开开眼界。另外,你应该多想想你过去做成功过什么事?那些才是你的长处,才是让你进化的前提。

计划就是瞎猜

除非你是算命先生,长期的商业计划是种幻想。有太多的事实证明那是超出你的掌控的:市场环境、对手、顾客、经济等等。做计划让你觉得一切尽在掌握但实际上你没有。

当你把计划变成猜测时,就等于进入一个危险的境地。做计划就是在用过去推导未来,等于给你戴上了眼罩。

感想:你有职业规划吗?如果你有的话,那么你就一定就错了。职业规划是一件很扯淡的事情。我和一些高手都交流过,其实这些人在当初都并不有什么职业规划的,要说有的话,也就是想把技术搞透搞精。这些人在一开始从来没有想过要当个什么经理或是什么架构师之类的东西,这些人就是对技术有非常大的热情,把身边的那些看得见够得着的事情做到好好地,并且保持不持续强大的好奇心努力地学习自己不懂的东西。一个坚定不移的决定和意志力会比任何的计划和职业规划都重要。你问问自己,想不想当程序员,能不能一辈子都当一个程序员,能不能写程序写一辈子?(关于做一辈子程序员这个事,大家可以看看我的新浪微博 ——没哪个行业能像计算机行业这么活跃、刺激和有趣了。不仅是新兴工业革命的主力,又渗入到所有的行业中,干一辈子值了。//@_你亲爱的偏执狂: 程序员首先是工程师,Professional,就跟律师,医生一样,给大家解决问题;但是另一面呢,又是艺术家,创造新奇好玩的东西。这样的职业做一辈子有什么问题?

拒绝壮大

规模越大你就得承受更大压力、需要更专业、拥有更强的能力。

有没有注意到,一个小公司希望自己变大时,大公司却想要变得灵活变通。记住,一旦你变大了就很难在不解雇人、不破坏士气、不改变你的整个商业路线的情况下收缩规模。

扩张不必成为你的目标。我们也不是仅在讨论你已有员工数。 还有花费、租金、IT 基础结构、设备等。这些事情不会碰巧发生。 你来决定是否承受这些。如果你决定去承受,你也将遇到新的头痛问题。花费那么多,你强迫自己构建一个复杂的生意,有一大堆困难而高压的事情要解决。

小公司并不是一个起步,小公司本身就是一个伟大的目标。

感想:很多人都会以为拥有一支成百上千人的团队而成为一个成功的标志。就像很多朋友和猎头都会问我管多少人,当我说,我就管个十人不到的团队时,他们似乎都会觉得我很平庸。他们中的一些人基本上就不会再问我在干些什么了,因为他们可能觉得这么少的人都干什么大事呢?。当然,我说了他们也不一定听得懂。人多可能恰恰说明你可能在干一个劳动密集型的事情,这并没有什么可自豪的。真正自豪的不是在战争中用人海战术让大量的人去当炮灰,而是用一个小分队端掉敌军的军火库或指挥部。所以,关键不是你有多少人,关键是你做的事是不是有非凡的意义,而且你用了最小当量的资源。这就好像建立一个高性能的网站一样,用成百上千的服务器不算本事,谁用的少才是本事

工作狂

工作狂的行为不但没有必要,而且愚蠢至极。过多的工作并不代表你对项目更关注,也不代表你作了更多的贡献,这仅仅意味着你干了更多的活而已。工作狂制造的麻烦比解决的麻烦多

工作狂往往不得要领。他们花大把大把的时间去解决问题,他们以为能靠蛮力来弥补思维上的惰性,其结果就是折腾出一堆粗糙无用的解决方案

如果你只是为了工作而工作,那么你就会丧失判断力。你的价值 观和决策方式都是扭曲。你没有能力去判断哪些工作值得做,哪些工作该放弃,最后搞得自己筋疲力尽,而一个筋疲力尽的人是无法作出明智的决定的。

工作狂不是英雄。他们不是在节约时间而是在浪费生命。真正的英雄早已想出了办法,搞定一切,然后回家了。

感想:这让我想到了那些为了冲业绩的业绩KPI的制订者们,很多时候,他们的价值观和决策真是的很扭曲的。他们生生地把一种技术密集型的工作变成了劳动密集型。他们其实就是在拼命地训练客户需要的那匹“更快的马”,而从来没有想过要去造个更快的交通工具。

另外,每当我在优秀员工的评比和员工的绩效考核中的跨团队比较中我们能听到很多很多的人说,XX员工工作任劳任愿,工作得很晚很晚,付出很大。老实说,我真的为这样的价值观感到悲哀。最后,我还想说说关于超时工作,我也经常学习和做自己的事情到深夜,我相信很多人也这样,但我们应该认真思考一下Rework中的这个观点,我们超时工作是在使用蛮力呢?还是在使用热情和兴趣呢?

挠自己的痒处

想要创造一款伟大的产品或者是某项卓越的服务,最直接、最简单的方法就是去做你自己想用的东西。设计你了解的产品——你就能很快发现它到到底好不好用。

最棒的是,“解决你实际遇到的问题”会让你爱上你做的事情。 你知道问题所在并且熟知解决它的价值。这是无法替代的。毕竟,你会充满希望的在接下来的日子里继续做。 甚至会占据你余生所有时间。所以,最好还是做自己真正关心的东西。

感想:这就是吃自己的狗食,做自己感兴趣的事。软件项目中,我最恨的就是那种闭门造车造出来的自己都不用的东西(不是从已有业务生长出来的东西),以及那些自己不动手就在边上指指点点的各种咨询师或是喜欢动用行政命令的高层管理者。

但是,在这里,我更想说说我所理解的另一层“挠自己痒处”——有天我和一前前同事聊天,她说她在那家公司十多年了,现在老了,虽然心不老还想折腾,但是对自己的能力没自信,求稳了。我听到很多朋友想对自己有个改变,比如有QA的同学想做开发,有生活在内地的朋友想来大城市的大公司里有更爽的经历,这些人明明想活得更有激情,但最终在现实面前认命妥协。我说既然有痒处,还比较痒,那就应该毫不犹豫革自己的命,轰轰烈烈地活一次。别等老了后悔当年没有勇气。“挠自己痒处”就是挑战自己,革自己的命,既然想了,就做吧,生命只有一次,值得我们轰轰烈烈地去为之付出。

“没时间”不是借口

人们最常用的借口是:“时间不够。”他们宣称很想开一家公司,学一种乐器,写一本书,等等,但时间不够用。拜托,如果你善加利用,时间总是有的。

把看电视或玩魔兽的时间腾出来完成你的创意;把10点上订改成11点上床,这不是怂恿你通宵达旦或是一天干足16个小时——我们要说的是,第周匀出一些业余时间来,就足够你去做些事情了。

当你拥有某种强烈的渴望时,你就能挤出时间来——不管你身上是否背负着其他责任。事实上,真相是大多数的渴望并不是那么强烈。于是他们拿时间当借口来自我开脱。别给自己错口。

另外,永远会有正当其时的时候,你总会觉得自己会么太年轻,要么太老,要么太忙,太穷,或是别的什么原因。如果你总是为遇到一个完美时机而发愁,那么,完美的时机绝对不会到来

感想:我在“挑战无处不在”中也表达过这样的观点,关于热情和态度,说白了就是不要给自己找借口。比如:“工作忙事多没时间学所以可以不懂”,“工作中没用到所以可以不懂”,“工作没有挑战,一直没有遇到合适的项目”等等。而且,如果你只能在万事俱备的情况下才能做事,那么,你还有什么价值呢?人的价值和竞争力就是在条件并不完美的时候还能搞定事情。

画沙为界,立场明确

坚定的信念能为你赢得超级粉丝,他们会为你马首是瞻,会舍身保护你,他们充满激情的口碑传播将胜过这世间一切的广告。

强大的主见,也是要付出代价的,在这个过程中,会有人诋毁你,说像傲慢,冷漠。没办法,这就是人生,有人喜欢你,就有人憎恨你。如果你的说法没有引起任何人的心烦意乱,只能说明你的推广力度可能还不够。(也可能代表你比较无趣)

对我们来说,我们的产品所不能处理的和我们的产品所能处理的一样令人感到骄傲

我们的产品不适合每一个人,没有关系,我们愿意为了那些更加深爱我们的客户而放弃另一部分客户。这就是我们的立场。

感想:我从来不想做一个大众脸。酷壳上有很多比较有争议的文章,也有很多人说我很极端,偏执,有优越感,清高……,说什么的都有,无所谓。我有一个做新闻编辑的太太,主辑要求文章要客观和没有观点,不温不火,本来好好的一篇有观点的文章被编辑过后只剩下了一堆食之无味的文字。我喜欢有鲜明的观点,因为鲜明的观点和立场能不但能让文章鲜活起来,而且还能迎来更多的不同意见和更多的思考(而不只是“顶”“赞”之类无意义的回复)。我并不希望我的观点是正确的,我只希望能和更多的人加入我一同思考,而思考最佳的催化剂就是争论。我从这个行为中收益到了很多很多。

找好退路无异于失败

你还常常听到:“你的退出战略是什么?(万一不成功,你怎么办)”甚至在你刚开始启动时就听到它。这些人不知道怎么开始就要想到怎么结束?急什么呢?如果在全情投入之前就想怎么撤出,这种逻辑不是一般的混乱。

你正打算恋爱一场就计划着分手?你在第一次约会时就签订婚前协议?你会在婚礼早上先约见离婚律师?那也太荒谬了吧。

你需要的是承诺战略而不是退出战略。你要考虑的是你的项目怎样发展和成功,而不是怎样撤退。如果整个战略是基于撤退的,一开始你就不会有机会成功。

感想:几年前,我有一个朋友被创新工场忽悠从美国退学回来创业,我非常质疑他退学创业这个事。他对我说,没事,反正就算失败我也不会失去什么。还有一个朋友一年前从美国回国创业,也对我说,就算没搞好也没什么。我都对他们说,如果你以为用试一试的态度就可以把一个事情搞成功,那么你让这世上那些Full Time全天候从事这个事情的并有一些积累的人情何以堪?如果你创业时都想好了失败,那就说你你对这个事没有必胜的信心,也说明连你自己都不相信这个事,你还干个什么劲啊?你与其把时间用在思考如果创业没成功你会怎么办上,你还如去思考一下如何做才有更大的胜算

条件受限是好事

“我没有足够的时间、钱、人手、经验”。不要现无谓的抱怨了。“少”不是什么坏事。“条件受限”貌似缺陷,实力优势。有限的资源能激发你在现有的条件下完成任务的能力。没有一点浪费空间,一切都需要你发挥最大的创造力。

你见过囚犯用肥皂和汤勺制作武器吗?你们是“创新”的典范。只有在条件受到限制时,我们才会发挥出“小材大用”的能力。

感想:我相信这世上很多事情都是被条件受限逼过去的。我回想到我以前经常在干的性能调优,想尽一切办法榨干系统资源这件事上,我就无法不赞同这句话。想想淘宝的TFS,就是一个因为条件受限到了不得不自己干的时候,被逼出来的东西。如果你没有足够多的人,你才会去想要怎么去优化工作和开发效率,于是才会逼着你去开发一些自动化的工具,而这些工具恰恰解放了生产力可以让你更快地干更多的事。只有条件受限,才会从劳动密集型中激发出知识密集型的东西。再回到以前我的那篇“是否需要专职的QA”一文说的到东西,如果你有很多很多帮你做测试的QA,你就不会去测试,你的团队也就不会有自动化测试等工具。这就好像在中国这个劳动力又多又廉价的大国下,基本上不需要你在技术上的创新,你只需要去不断地迁就这些低端用户,迁就这些用户越多,你还能有什么重大创新吗?真正的创新是帮助用户成长,而不是迁就用户。

与其做个半成品,不如做好半个产品

同时做N件事的结果就是:一大把绝妙的点子最后被转化成一个蹩脚的产品。

有舍才有得,砍掉多余的野心,你就会发现慢慢做一件正事要胜过毛毛躁躁地做一堆傻事。

很多东西都是越简短越好。拿起斧子动手砍吧,为了一个“伟 大”的起点,让我们把那些“挺不错”地枝节给砍掉吧。

感想:这正如“为什么中国的网页设计这么烂”中说的:“中国的学生只是去记忆东西而不是真正的理解。他们从来不花时间去思考,而只是贪婪地去获取更多的信息”。与其记忆那么多的东西,还不如好好理解部分的东西。还有一种说法是:“Done is better than Perfect!”,这句话某些时候说得也挺对的,尤其是对于那些完美地长期不能Done的项目。但是Done一个Ugly的东西还不如不做。所以平衡Done和Perfect的方式正好就是这句话——“与其做个半成品,不好做好半个产品”,因为,一个半成品会让人绝望,而半个好产品会让人有所期望,这就是其中的不同

关注不变因素

很多公司和人都关注即将到来的大事件。他们热衷于新鲜热辣的事物,追逐最新的潮流和技术

这是一条愚笨之路。一旦走上这条路,你就会关注时髦、放弃本质,把注意力放到不断变化的事物上,而不是持久不变的事物上。

你的事业的核心应该建立在不变的基础之上。你应该投资于那些人们现在需要,并且十年后仍然需要的事物上

要记住,时尚会凋零。只有当你聚焦于长久的功能时,你才会发现自己把握住了永不落伍的东西。

感想:一年多前,我在《来信、创业和移动互联网》中谈到过那个时尚的“移动互联网”,说了四个方向:阅读,分享交流,电商,推荐/提醒。大家可以看到现在地铁上已经不像以前很多人都在看报纸了,而是很多人都在看手机。而手机端的社交(分享和交流),电子商务,以及很多推荐、提醒都越来越火了。这些东西都是都是“常量”——十年前存在,未来十年也会存在,我们看到很多人太过着眼于手机上的应用,而不是那些不变的因素。今天还有两个巨火无比的流行词,一个是云计算,一个是大数据,那些一听到这两个词就会兴奋的人,我不知道他们有没有真正理解这两词?他们真正理解了云计算其实就是那个N多年前就提过的IT服务,关于大数据,我完全不知道为什么会火,你会因为听到中国人口有13亿你就会兴奋吗?老鼠的数量比较这个更多呢,呵呵。其实,数据无所谓大小之分,只有好数据和烂数据之分,还热数据和冷数据之分。十年前有两个更为流行的词:一个是计算网格,一个是数据网格,这两个词5年前就凋零了,今天的云计算和大数据,有多少人意识到了其中有什么相通的,或是其中的不变因素是什么?大数据和云计算其实都在描述两个东西,一个是超大规模的计算能力,另一个则是服务。还有一个词是“平台化”,这可能被大家忽略了,通过平台进行计算和数据服务,这才是那计算机存在以来基本不变的东西,无论你是移动互联网,还是互联网,不管是云计算,还是大数据,都需要一个平台提供服务

会议有毒

世人最可恨的打扰莫过于开会。原因是:

  • 会议中充斥着纸上谈兵和抽象的概念,大多是不切实际的。
  • 会议中能传达的信息量少之又少。
  • 人们在会议中容易跑题,堪比暴风雪里的芝加哥出租车还容易迷失方向。
  • 会议要求做充分的准备,但是大多数人没有时间准备这些。
  • 会议制定的议程常常是模糊的,根本就没有人真正清楚目标是什么。
  • 会议中难免会轮到那么一两个低能人士发言,于是大家的时间都浪费在他们的扯淡上了。
  • 会议具有自我繁殖功能。一次会议总能导致另外一次,以及再导出下一次,生生不息……

感想:这世上除了“他爹的TDD”开发模式,还有“他妈的TMD”开发,就是Team Meeting Driven,很多公司有太多太多的会要开了,开会基本上成了每天工作最主要的东西,对于一些管理者来说一星期中居然有80%时间都在开会。其实,这么多的会议并不意味着你在管理,只是意味着你对要管的东西完全不知道,需要通过开会来了解。很多会完全是没有议题的,大家坐在一起东拉西扯,非常非常地低效。我通常把这种会叫做“神仙会”,用个流行语来说,就是Cloud Meeting,大家神一要的各说各的,似乎,没有这种形式,不能证明参会者的存在,用会议来证明他们的存在,相当的可笑。对我来说,如果只是带一个或几个问题来开会,简直是就是扯谈,如果对于问题没有几个备选的解决方案和各方案的评估,完全没有必要开会。Amazon的会议是不会有PPT的,会议组织者会要要讨论的东西写好并打印出来,在会前给参会者把要讨论的东西打印出来,开会前10分钟左右,会场里没有任何声音,每个人都在读文档,全部人读完后,直接对议题发表自己的个人意见应该怎么干,然后很快形成共识,散会。

人人都得干活

在一个小团队里,你需要的是干活的人,而不是监工。每个人都得做事,没有人可以袖手旁观 。

这意味着你在招聘中要避免招到监工型的人物,这些人喜欢对别人谆谆教导。对于小团队来讲监工型的人就是累赘。

监工们还喜欢把人拖去开会。实际上,会议是监工们最好的朋友,因为只有在开会时才显得出他们的重要。

感想为什么会有办公室政治,那就是因为这个公司里有一部分人不干活,不做事,于是,他们就有大量地时间开始胡思乱想,他们花大量的时间不是想怎么去做事,而是想自己怎么更容易的打垮别人得到上面的认可,从而得到晋升。在大公司中这样的情况会比Startup的公司多得多。所以,如果你不想滋生办公室政治,那么你需要干两个事,第一个是最好不要变成大公司,第一个是让每个人都在实干。我最近看到其大公司,虽然很多东西不规范,而且很多东西在野蛮生长,有些事情也有点土,但绝大多数人都在实干,所以,只要每个人都在实干,就算干的方式不好,干出来的东西有问题,也比那些滋生办公室政治的公司强上几百倍

拒绝照搬 & 将你的产品去商品化

有时候,照猫画虎也是一种学习过程,就好像艺术系的学生通过临摹美术馆的作品来学习绘画。当你还是一个学生时,这种模仿是一种很有效的学习工具。不幸的是,商业战场上的模仿却不招人待见。而这也意味着你打算通过当盲从者或抄袭者的方式来建立你的事业,这注定是一个失败模式。

模仿的问题在于,简单的复制扼杀了深层的理解——而理解才能激发成长。你不但要知其然,还要知其所以然。而当你复制时,你会忽视这一点。你照搬的只是表面,而不是本质。

一旦你扬名立万,模模仿者会蜂拥而至,这就是生活。但你可以用一种绝佳的方式来保护自己不被 他们吞没:让你自己成为你的产品或服务的一部分。

感想:在《抄袭,腾讯 和 产品》中我谈到过这个事情,虽然我对抄袭和山寨很反感,但是我不得不承认这是这个世界的一部分,好的东西总是会被人复制的,这也不一定是一个坏事,这会让你更清楚认识到什么是真正产品的价值,什么是核心竞争力,你但凡有一点急功近利的想法你都要想一想那堆抄袭者,其中还不乏有钱有人的专业抄袭的公司。而面对被抄袭这样的事情,最好的解决方法是着眼着远期而不是短期——如果你着眼短期,你无疑会面对众多的抄袭和模仿者让你万劫不复,但是,如果你着眼长期,做一个3-5年需要花费大量精力才会成熟的产品,那么,那些急功近利的抄袭者会知难而退的,因为长期并不符合抄袭者的价值观

做得比对手少

传统智慧告诉我们,要想打败竞争者就要胜人一筹。如果人家有 4 个功能,你就得 5 个(或者 15 个,25 个)。如果人家花了$20,000,你就得花 $30,000。如果人家有 50 个员工,你就得要 100 个。

这样的冷战式的攀比思维会把人引上绝路。一旦被卷入“军备竞赛”,你就陷入了一场无止境的战争,这场战争会让你耗费大量的金钱、时间和动力。并且使你陷入长期的防御战中。处于防御状态的公司是没有预见力的;他们只能后知后觉,他们无法领跑,只能尾随。

那么你应该怎么做呢?比你的竞对手做得少,以此来打败他们。让自己去解决简单的问题,把那些纠结的、麻烦的、艰难的、讨厌的难题留给竞对手去解决。不要总想着去胜人一筹、去超过别人,试试相反的做法。

不要因为你的产品或服务不如别人的花哨就感到自惭形秽。把他们做得醒目高调,并引以为傲。就像对手那些强有力的销售他们多功能的产品一样销售你那简约的产品。

感想:一个最典型的例子就是iPad,它干得比Laptop少,比上网本少,就是一个很简单的上网和简单游戏的设备,但是他有非常简单的用户体验,让两三岁的儿童和六七十岁的老人都能很快上手。你相信吗?我花了好多年都没教会我父母用电脑以及手机里除了电话功能外的其它功能,但我只花了10分钟就教会他们使用iPad上网了。这就是“做得比对手少”的强大。只有简约的东西,才会显得更精致,才会显得更专业

谁在乎他们在干什么

不管怎样,终究是不值得过于关注你的竞争者。为什么?因为关注别人太多会让自己受到困扰。他们现在在做什么?他们下一步呢?我们该怎样作出回应?

每一个小小的动作都会被分析一下。那是一种可怕的心态。这会产生不可抗拒的压力和焦虑。这样的想法会滋长不好的东西。

这是没有意义的事情。竞争者的风景时时在变。你的竞争对手明天一个样儿,今天一个样儿。完全在你控制之外。去担心你所不能控制的事情有意义吗?

过于关注竞争者会混淆你的视野。当你一直吸收别人思想时, 你的机会则会减少。你变得反动而不是充满想象力。你只不过是将你竞对手的产品换了个包装。

如果你打算做一个“the iPod killer”或“the next Pokemon”,你已经死了。你是在承认你的竞争者所设定的参数。你没有跳出 Apple 的套路。他们制定了这个游戏规则。你不可能打败制定规则的那个人。你必须重新制定一个规则,而不是稍微改建一点点。

感想:这个社会浮躁之处就在于我们太多的观注了别人,人比人气死人。我们很多人都注意到了别人的风光,看到别人创业被注资,看到别人找到了好的工作,看到了别人不走正道而发达,看到了别人很轻松还挣得多,甚至看到别人的粉丝比自己多,等等,等等,这些东西让自己的心态变,变得非常地不淡定了。眼红也是魔鬼,因为眼红让人心理扭曲了的例子还少吗?不要在乎别人干了什么,你应该多看看自己的长处是什么,每个人都有每个人的路,你要做的是按照自己的节奏和自己擅长的方式行事,而不是小猫钓鱼

养成对客户说“不”的习惯

说“好的”很容易。我们很容易接受同意一个新功能、同意一个过于乐观的截止日期、笑纳一个平庸的设计。很快,一大堆你曾经说“yes”的事情就发生连锁反应,很多你不想要的东西越堆越高,甚至你都看不出原来想要的东西。

别相信“顾客永远是对的”这类的话。如果你是一个大厨,你的很多客人说你做的菜太咸或者太烫,你可以改。但是如果有一些挑剔的老主顾要求在宽面条里面加些香蕉,你千万不要理会他们,没关系。若是为了少数顾客的要求而毁了产品不值得。

你的目标是确保你的产品与就是和你合拍的产品,你就是你自己产品最踏实的粉丝。你是最信赖它的那个人。那样的话,你会说:“我想你也会爱它的,因为我爱它。”

感想:亨利福特说过:“如果我要问我的客户要什么,他们会告诉我他们要一匹更快的马”,所以,过份的迁就用户并不是一件好的事,相反会是一件很不好的事。互联网和电视节目一样都有一个万恶的KPI,电子节目那万恶的KPI是收视率,而互联网的万恶KPI是流量。于是很多公司为了流量开始不择手段,就像电视节目用庸俗化来提高收视率一样,我们的一些互联网产品也使用庸俗化的东西来提高流量。我们要做的是一个让人称道的有品质的产品,而不是一个只有访问量的产品

不要攀客户的高枝

也许你曾经见过这样的场景:一个顾客向一家公司投了很多钱。这家公司想要尽可能的取悦那个顾客。为了迎合这个客户的要求而改变自己的产品,渐渐地,你的产品就会脱离普遍客户的基础。

而且,突然有一天,这个大客户绝尘而去,公司则会背负一个包袱——这个产品是围绕着一个已经离开了的人设计的。而其他人没法用。

人在变,环境在变,你不可能满足所有人的所有要求。公司要对某一类型的客户全情投入,而不是对某个善变的客户唯唯诺诺

感想:你永远要找到自己的定位,你不可能满足所有的人。就像屌丝们喜欢的北京的动物园批发市场和高富帅们喜欢的北京燕莎商场一样,他们分别订位于不同的用户。你的产品从生下来的那一时刻就应该需要做好定位,是面对什么样的人群。而且,你也不可能实现所有人的需求的。有时候,失去一些客户并不是坏事,我们要做的是管理我们的客户,让客户认同我们,而不是被客户牵着走

一夜成名只是传说

你不会瞬间大红大紫,也不会一夜暴富,你所了解的那些道听途说的“一夜成名”的故事,深挖一点,你就能发现这些成功人士在到达引爆点之前,都已经在这个方向 上苦熬了很长时间。

把一夜成名的迷梦换成一步一个脚印的成长行动吧。道路很艰难,但你必须充满耐心。你得用功去做,在遇到伯乐前,你得努力很长时间。

感想:这和我在程序算法与人生选择一文中所说的那个最短路径的算法的类比一样,与其展望要当什么架构师或是要成为牛人的憧憬,不如把身边看得见够得着的东西学扎实,干出色。一夜成名只是一个传说,你知道酷壳是因为我写十多年的博客,你知道我是因为我积累了十多年的编程,看看酷壳以前介绍过的王平同学吧。很多事情都不是偶然的,都是有前兆的,还是我以前说过的那句话,“如果一件事情以前没有发生过,未来也不会发生”,比如:如果你在学校里,在工作里,你的同学和同事并不经常来向你请教询问你的意见,那么你基本上很难成为一个Leader

员工不是13岁

当你把员工当孩子看时,人们就会像孩子一样行事

当公司里事事都要上报审批时,你就创造出了一种无脑文化。你成功地制造出了老板和员工之间的对立关系。这种关系在咆哮着:“我不相信你!”

当你处处限制员工,比如禁上他们在上班时访问外部网站或是开小差,你会得到什么好处?什么也得不到。人们需要开小差,这有助于打破整日的枯燥单调,花点时间上上Youtube或Facebook不会失去什么。

如果你要监控你的员工,你得想想你要花多少时间和金钱来监管员工。你浪费了多少钱去安装监控软件?你浪费了多少人力资源去监视员工?你浪费了多少时间去写没有人会看的规章制度?看看这些成本,你很快就发现,对员工的不信任才是最大的开销

感想:我始终在跟我的团队成员说,最有效的管理就是自己管理自己,而不是还要专们的人来管你。不然的话,你一定会很难受的。如果你能管理好你的工作和任务,我们就不需要项目经理。如果你能管理得好你的做事的方法和流程,就不需要那些搞流程的。如果你能管理得好你的程序质量,我们就不需要QA来监管你…… 等等。其实,你们如果能管理得好自己,并能自我进化。你们甚至不需要一个经理。但是,你们可能会需要一个为你们跑腿打杂的人,其实,那个人就是经理

(全文完)

Docker Fundamental 2 – Quick start

How To Install and Use Docker on Ubuntu 16.04

UpdatedNovember 3, 2016 727.7kviews DOCKER UBUNTU UBUNTU 16.04

Introduction

Docker is an application that makes it simple and easy to run application processes in a container, which are like virtual machines, only more portable, more resource-friendly, and more dependent on the host operating system. For a detailed introduction to the different components of a Docker container, check out The Docker Ecosystem: An Introduction to Common Components.

There are two methods for installing Docker on Ubuntu 16.04. One method involves installing it on an existing installation of the operating system. The other involves spinning up a server with a tool called Docker Machine that auto-installs Docker on it.

In this tutorial, you’ll learn how to install and use it on an existing installation of Ubuntu 16.04.

Prerequisites

To follow this tutorial, you will need the following:

Note: Docker requires a 64-bit version of Ubuntu as well as a kernel version equal to or greater than 3.10. The default 64-bit Ubuntu 16.04 server meets these requirements.

All the commands in this tutorial should be run as a non-root user. If root access is required for the command, it will be preceded by sudoInitial Setup Guide for Ubuntu 16.04 explains how to add users and give them sudo access.

Step 1 — Installing Docker

The Docker installation package available in the official Ubuntu 16.04 repository may not be the latest version. To get the latest and greatest version, install Docker from the official Docker repository. This section shows you how to do just that.

First, add the GPG key for the official Docker repository to the system:

  • curl -fsSL https://download.docker.com/linux/ubuntu/gpg | sudo apt-key add –

Add the Docker repository to APT sources:

  • sudo add-apt-repository “deb [arch=amd64] https://download.docker.com/linux/ubuntu $(lsb_release -cs) stable”

Next, update the package database with the Docker packages from the newly added repo:

  • sudo apt-get update

Make sure you are about to install from the Docker repo instead of the default Ubuntu 16.04 repo:

  • apt-cache policy docker-ce

You should see output similar to the follow:

Output of apt-cache policy docker-ce
docker-ce:
  Installed: (none)
  Candidate: 17.03.1~ce-0~ubuntu-xenial
  Version table:
     17.03.1~ce-0~ubuntu-xenial 500
        500 https://download.docker.com/linux/ubuntu xenial/stable amd64 Packages
     17.03.0~ce-0~ubuntu-xenial 500
        500 https://download.docker.com/linux/ubuntu xenial/stable amd64 Packages

Notice that docker-ce is not installed, but the candidate for installation is from the Docker repository for Ubuntu 16.04. The docker-ce version number might be different.

Finally, install Docker:

  • sudo apt-get install -y docker-ce

Docker should now be installed, the daemon started, and the process enabled to start on boot. Check that it’s running:

  • sudo systemctl status docker

The output should be similar to the following, showing that the service is active and running:

Output
● docker.service - Docker Application Container Engine
   Loaded: loaded (/lib/systemd/system/docker.service; enabled; vendor preset: enabled)
   Active: active (running) since Sun 2016-05-01 06:53:52 CDT; 1 weeks 3 days ago
     Docs: https://docs.docker.com
 Main PID: 749 (docker)

Installing Docker now gives you not just the Docker service (daemon) but also the docker command line utility, or the Docker client. We’ll explore how to use the docker command later in this tutorial.

Step 2 — Executing the Docker Command Without Sudo (Optional)

By default, running the docker command requires root privileges — that is, you have to prefix the command with sudo. It can also be run by a user in the docker group, which is automatically created during the installation of Docker. If you attempt to run the docker command without prefixing it with sudo or without being in the docker group, you’ll get an output like this:

Output
docker: Cannot connect to the Docker daemon. Is the docker daemon running on this host?.
See 'docker run --help'.

If you want to avoid typing sudo whenever you run the docker command, add your username to the docker group:

  • sudo usermod -aG docker ${USER}

To apply the new group membership, you can log out of the server and back in, or you can type the following:

  • su – ${USER}

You will be prompted to enter your user’s password to continue. Afterwards, you can confirm that your user is now added to the docker group by typing:

  • id -nG
Output
sammy sudo docker

If you need to add a user to the docker group that you’re not logged in as, declare that username explicitly using:

  • sudo usermod -aG docker username

The rest of this article assumes you are running the docker command as a user in the docker user group. If you choose not to, please prepend the commands with sudo.

Step 3 — Using the Docker Command

With Docker installed and working, now’s the time to become familiar with the command line utility. Using docker consists of passing it a chain of options and commands followed by arguments. The syntax takes this form:

  • docker [option] [command] [arguments]

To view all available subcommands, type:

  • docker

As of Docker 1.11.1, the complete list of available subcommands includes:

Output

    attach    Attach to a running container
    build     Build an image from a Dockerfile
    commit    Create a new image from a container's changes
    cp        Copy files/folders between a container and the local filesystem
    create    Create a new container
    diff      Inspect changes on a container's filesystem
    events    Get real time events from the server
    exec      Run a command in a running container
    export    Export a container's filesystem as a tar archive
    history   Show the history of an image
    images    List images
    import    Import the contents from a tarball to create a filesystem image
    info      Display system-wide information
    inspect   Return low-level information on a container or image
    kill      Kill a running container
    load      Load an image from a tar archive or STDIN
    login     Log in to a Docker registry
    logout    Log out from a Docker registry
    logs      Fetch the logs of a container
    network   Manage Docker networks
    pause     Pause all processes within a container
    port      List port mappings or a specific mapping for the CONTAINER
    ps        List containers
    pull      Pull an image or a repository from a registry
    push      Push an image or a repository to a registry
    rename    Rename a container
    restart   Restart a container
    rm        Remove one or more containers
    rmi       Remove one or more images
    run       Run a command in a new container
    save      Save one or more images to a tar archive
    search    Search the Docker Hub for images
    start     Start one or more stopped containers
    stats     Display a live stream of container(s) resource usage statistics
    stop      Stop a running container
    tag       Tag an image into a repository
    top       Display the running processes of a container
    unpause   Unpause all processes within a container
    update    Update configuration of one or more containers
    version   Show the Docker version information
    volume    Manage Docker volumes
    wait      Block until a container stops, then print its exit code

To view the switches available to a specific command, type:

  • docker docker-subcommand –help

To view system-wide information about Docker, use:

  • docker info

Step 4 — Working with Docker Images

Docker containers are run from Docker images. By default, it pulls these images from Docker Hub, a Docker registry managed by Docker, the company behind the Docker project. Anybody can build and host their Docker images on Docker Hub, so most applications and Linux distributions you’ll need to run Docker containers have images that are hosted on Docker Hub.

To check whether you can access and download images from Docker Hub, type:

  • docker run hello-world

The output, which should include the following, should indicate that Docker in working correctly:

Output
Hello from Docker.
This message shows that your installation appears to be working correctly.
...

You can search for images available on Docker Hub by using the docker command with the searchsubcommand. For example, to search for the Ubuntu image, type:

  • docker search ubuntu

The script will crawl Docker Hub and return a listing of all images whose name match the search string. In this case, the output will be similar to this:

Output

NAME                              DESCRIPTION                                     STARS     OFFICIAL   AUTOMATED
ubuntu                            Ubuntu is a Debian-based Linux operating s...   3808      [OK]       
ubuntu-upstart                    Upstart is an event-based replacement for ...   61        [OK]       
torusware/speedus-ubuntu          Always updated official Ubuntu docker imag...   25                   [OK]
rastasheep/ubuntu-sshd            Dockerized SSH service, built on top of of...   24                   [OK]
ubuntu-debootstrap                debootstrap --variant=minbase --components...   23        [OK]       
nickistre/ubuntu-lamp             LAMP server on Ubuntu                           6                    [OK]
nickistre/ubuntu-lamp-wordpress   LAMP on Ubuntu with wp-cli installed            5                    [OK]
nuagebec/ubuntu                   Simple always updated Ubuntu docker images...   4                    [OK]
nimmis/ubuntu                     This is a docker images different LTS vers...   4                    [OK]
maxexcloo/ubuntu                  Docker base image built on Ubuntu with Sup...   2                    [OK]
admiringworm/ubuntu               Base ubuntu images based on the official u...   1                    [OK]

...

In the OFFICIAL column, OK indicates an image built and supported by the company behind the project. Once you’ve identified the image that you would like to use, you can download it to your computer using the pull subcommand, like so:

  • docker pull ubuntu

After an image has been downloaded, you may then run a container using the downloaded image with the run subcommand. If an image has not been downloaded when docker is executed with the runsubcommand, the Docker client will first download the image, then run a container using it:

  • docker run ubuntu

To see the images that have been downloaded to your computer, type:

  • docker images

The output should look similar to the following:

Output
REPOSITORY          TAG                 IMAGE ID            CREATED             SIZE
ubuntu              latest              c5f1cf30c96b        7 days ago          120.8 MB
hello-world         latest              94df4f0ce8a4        2 weeks ago         967 B

As you’ll see later in this tutorial, images that you use to run containers can be modified and used to generate new images, which may then be uploaded (pushed is the technical term) to Docker Hub or other Docker registries.

Step 5 — Running a Docker Container

The hello-world container you ran in the previous is an example of a container that runs and exits, after emitting a test message. Containers, however, can be much more useful than that, and they can be interactive. After all, they are similar to virtual machines, only more resource-friendly.

As an example, let’s run a container using the latest image of Ubuntu. The combination of the -i and -tswitches gives you interactive shell access into the container:

  • docker run -it ubuntu

Your command prompt should change to reflect the fact that you’re now working inside the container and should take this form:

Output
root@d9b100f2f636:/#

Important: Note the container id in the command prompt. In the above example, it is d9b100f2f636.

Now you may run any command inside the container. For example, let’s update the package database inside the container. No need to prefix any command with sudo, because you’re operating inside the container with root privileges:

  • apt-get update

Then install any application in it. Let’s install NodeJS, for example.

  • apt-get install -y nodejs

Step 6 — Committing Changes in a Container to a Docker Image

When you start up a Docker image, you can create, modify, and delete files just like you can with a virtual machine. The changes that you make will only apply to that container. You can start and stop it, but once you destroy it with the docker rm command, the changes will be lost for good.

This section shows you how to save the state of a container as a new Docker image.

After installing nodejs inside the Ubuntu container, you now have a container running off an image, but the container is different from the image you used to create it.

To save the state of the container as a new image, first exit from it:

  • exit

Then commit the changes to a new Docker image instance using the following command. The -m switch is for the commit message that helps you and others know what changes you made, while -a is used to specify the author. The container ID is the one you noted earlier in the tutorial when you started the interactive docker session. Unless you created additional repositories on Docker Hub, the repository is usually your Docker Hub username:

  • docker commit -m “What did you do to the image” -a “Author Name” container-id repository/new_image_name

For example:

  • docker commit -m “added node.js” -a “Sunday Ogwu-Chinuwa” d9b100f2f636 finid/ubuntu-nodejs

Note: When you commit an image, the new image is saved locally, that is, on your computer. Later in this tutorial, you’ll learn how to push an image to a Docker registry like Docker Hub so that it may be assessed and used by you and others.

After that operation has completed, listing the Docker images now on your computer should show the new image, as well as the old one that it was derived from:

  • docker images

The output should be similar to this:

Output
finid/ubuntu-nodejs       latest              62359544c9ba        50 seconds ago      206.6 MB
ubuntu              latest              c5f1cf30c96b        7 days ago          120.8 MB
hello-world         latest              94df4f0ce8a4        2 weeks ago         967 B

In the above example, ubuntu-nodejs is the new image, which was derived from the existing ubuntu image from Docker Hub. The size difference reflects the changes that were made. And in this example, the change was that NodeJS was installed. So next time you need to run a container using Ubuntu with NodeJS pre-installed, you can just use the new image. Images may also be built from what’s called a Dockerfile. But that’s a very involved process that’s well outside the scope of this article.

Step 7 — Listing Docker Containers

After using Docker for a while, you’ll have many active (running) and inactive containers on your computer. To view the active ones, use:

  • docker ps

You will see output similar to the following:

Output
CONTAINER ID        IMAGE               COMMAND             CREATED             STATUS              PORTS               NAMES
f7c79cc556dd        ubuntu              "/bin/bash"         3 hours ago         Up 3 hours                              silly_spence

To view all containers — active and inactive, pass it the -a switch:

  • docker ps -a

To view the latest container you created, pass it the -l switch:

  • docker ps -l

Stopping a running or active container is as simple as typing:

  • docker stop container-id

The container-id can be found in the output from the docker ps command.

Step 8 — Pushing Docker Images to a Docker Repository

The next logical step after creating a new image from an existing image is to share it with a select few of your friends, the whole world on Docker Hub, or other Docker registry that you have access to. To push an image to Docker Hub or any other Docker registry, you must have an account there.

This section shows you how to push a Docker image to Docker Hub. To learn how to create your own private Docker registry, check out How To Set Up a Private Docker Registry on Ubuntu 14.04.

To create an account on Docker Hub, register at Docker Hub. Afterwards, to push your image, first log into Docker Hub. You’ll be prompted to authenticate:

  • docker login -u docker-registry-username

If you specified the correct password, authentication should succeed. Then you may push your own image using:

  • docker push docker-registry-username/docker-image-name

It will take sometime to complete, and when completed, the output will similar to the following:

Output
The push refers to a repository [docker.io/finid/ubuntu-nodejs]
e3fbbfb44187: Pushed
5f70bf18a086: Pushed
a3b5c80a4eba: Pushed
7f18b442972b: Pushed
3ce512daaf78: Pushed
7aae4540b42d: Pushed

...

After pushing an image to a registry, it should be listed on your account’s dashboard, like that show in the image below.

New Docker image listing on Docker Hub

If a push attempt results in an error of this sort, then you likely did not log in:

Output
The push refers to a repository [docker.io/finid/ubuntu-nodejs]
e3fbbfb44187: Preparing
5f70bf18a086: Preparing
a3b5c80a4eba: Preparing
7f18b442972b: Preparing
3ce512daaf78: Preparing
7aae4540b42d: Waiting
unauthorized: authentication required

Log in, then repeat the push attempt.

Conclusion

There’s a whole lot more to Docker than has been given in this article, but this should be enough to getting you started working with it on Ubuntu 16.04. Like most open source projects, Docker is built from a fast-developing codebase, so make a habit of visiting the project’s blog page for the latest information.

Also check out the other Docker tutorials in the DO Community.

Docker web proxy

 

 

Ubuntu 14.04 LTS

For Ubuntu 14.04 LTS who uses SysVinit, you should modify /etc/default/docker file:

# cat /etc/default/docker
# Docker Upstart and SysVinit configuration file

#
# THIS FILE DOES NOT APPLY TO SYSTEMD
#
#   Please see the documentation for "systemd drop-ins":
#   https://docs.docker.com/engine/articles/systemd/
#

.......
# If you need Docker to use an HTTP proxy, it can also be specified here.
export http_proxy="http://web-proxy.corp.xxxxxx.com:8080/"
export https_proxy="https://web-proxy.corp.xxxxxx.com:8080/"
......

Then restart docker:

service docker restart

Ubuntu 16.04 LTS

For Ubuntu 16.04 LTS who uses Systemd, you can follow this post:

(1) Create a systemd drop-in directory:

mkdir /etc/systemd/system/docker.service.d

(2) Add proxy in /etc/systemd/system/docker.service.d/http-proxy.conf file:

# cat /etc/systemd/system/docker.service.d/http-proxy.conf
[Service]
Environment="HTTP_PROXY=https://web-proxy.corp.xxxxxx.com:8080/"
Environment="HTTPS_PROXY=https://web-proxy.corp.xxxxxx.com:8080/"
Environment="NO_PROXY=localhost,127.0.0.1,localaddress,.localdomain.com"

(3) Flush changes:

systemctl daemon-reload

(4) Restart Docker:

systemctl restart docker

Docker Fundamental (1)

笔记:

记录Docker的一些基本命令

  1. Docker pull – pull docker image from public docker hub
  2. Docker image – show local image
  3. Docker run – run once using specific dock
  4. Docker ps
  5. Docker search <containerName>

 

2017.10.17 重新启用

时隔五年,经历了种种之后,我又决定重写启用技术博客系统。在这五年,更多的是寻找,而今天我依然在寻找,不管如何吧,只用Evernote写自己的东西显然是不够用的,仍然还需要一片天地记录、分享一些心得给自己,也给大家。

Tinyboat