Python 非常奇怪的代码现象

  1. #!/usr/bin/python
    
    
    import os
    from subprocess import *
    import sys
    
    import yaml
    def local_run(cmd):
        if cmd:
            p = Popen(cmd, shell=True, stdout=PIPE,stderr=PIPE)
            out,err = p.communicate()
        return(p.returncode, out, err)
    
    
    if __name__ == '__main__':
        rst = local_run("salt 'dev*' state.apply test  --out=yaml")
        data=yaml.load(rst[1])
        if rst[0] == 0:
            print([ data[k][cmd]['result'] for cmd in data[k].keys() for k in data.keys() ])
            print([ [data[k][cmd]['result'] for cmd in data[k].keys() ] for k in data.keys() ])
            # method 1
            #for k in data.keys():
            #    for cmd in data[k].keys():
            #        print data[k][cmd]['result']
            # method 2
        else:
            print rst[2]
            [ data[k][cmd]['result'] for cmd in data[k].keys() for k in data.keys() ]
            sys.exit(rst[0])
    
    

    Traceback (most recent call last):

      File “test.py”, line 20, in <module>

        print([ data[k][cmd][‘result’] for cmd in data[k].keys() for k in data.keys() ])

    NameError: name ‘k’ is not defined

    2. 将两个Expression 对掉,却能生效

    #!/usr/bin/python
    
    
    import os
    from subprocess import *
    import sys
    
    import yaml
    def local_run(cmd):
        if cmd:
            p = Popen(cmd, shell=True, stdout=PIPE,stderr=PIPE)
            out,err = p.communicate()
        return(p.returncode, out, err)
    
    
    if __name__ == '__main__':
        rst = local_run("salt 'dev*' state.apply test  --out=yaml")
        data=yaml.load(rst[1])
        if rst[0] == 0:
            print([ [data[k][cmd]['result'] for cmd in data[k].keys() ] for k in data.keys() ])
            print([ data[k][cmd]['result'] for cmd in data[k].keys() for k in data.keys() ])
            # method 1
            #for k in data.keys():
            #    for cmd in data[k].keys():
            #        print data[k][cmd]['result']
            # method 2
        else:
            print rst[2]
            [ data[k][cmd]['result'] for cmd in data[k].keys() for k in data.keys() ]
            sys.exit(rst[0])

    [[True], [True]]

    [True, True]

    奇怪。

Saltstack Set Roles with Pillar

Saltstack Set Roles with Pillar

Sometimes, we would like to set roles for our servers. This is can be done to define  /srv/pillar/top.sls.

for example

we have:

web_prod01

web_prod02

web_prod02

PART 1 working with pillar

  1. then we can define like this:
base:
   'web_prod*'
       - prod_role

 

2. and in the /srv/pillar/prod_role.sls

role: webserver

3. refresh the pillar file to all matched web_prod*minions

salt “web_prod*” saltutil.refresh_pillar

4. then test it

salt -I ‘role:webserver’ test.ping

additional we can set matched in state file:

base:
 'role:webserver':
   - match: pillar
   - state
   - state2

Reference links:

PART 2 another workaround with external nodegroups

include files in /etc/salt/master

# Include config from several files and directories:

include:

   – /opt/test/saltmgt/nodegroups.yaml

2. cat /opt/test/saltmgt/nodegroups.yaml

nodegroups:

   test1:

     – ‘*prod*’

 

more useful:

Working with Django Model

  1. Sub-queries used for query pk dee in  main talbe

Create your models here.
class projects(models.Model):
    #env = models.ForeignKey(deploy_env, on_delete=models.CASCADE)
    project_name = models.CharField(max_length=200)
    create_date = models.DateTimeField(default=0)
    owner = models.CharField(max_length=200)

    def __str__(self):
        return self.project_name
class AppEnv(models.Model):

    name = models.CharField(max_length=200, unique=True)
    def __str__(self):
        return self.name

class MGDeployEnv(models.Model):
    deploy_env = models.OneToOneField(minion_groups, on_delete=models.CASCADE)
    project_name = models.ForeignKey(projects, on_delete=models.CASCADE)
    env_name = models.ForeignKey(AppEnv, on_delete=models.CASCADE)
    pillar = models.TextField()
    state = models.TextField()
    current_version = models.CharField(max_length=200, blank=True)
    status = models.CharField(max_length=200, blank=True)
    comments = models.CharField(max_length=200, blank=True)
    update_on = models.DateTimeField(default=timezone.now)

    def __str__(self):
        return str(self.deploy_env)
class tasks(models.Model): #question = models.ForeignKey(Question, on_delete=models.CASCADE) #project_name = models.ForeignKey(projects, on_delete=models.CASCADE) env = models.ForeignKey(deploy_env, on_delete=models.CASCADE) deploy_url = models.CharField(max_length=200) owner = models.CharField(max_length=200) date = models.DateTimeField(default=timezone.now) status = models.CharField(max_length=200, blank=True) result = models.TextField(blank=True) def __str__(self): return self.deploy_url

1.1 Command line tests:

>> env_id=deploy_env.objects.filter(project_name_id=5)
>>> qt=tasks.objects.filter(env_id__in=env_id)
>>> qt.values()

<QuerySet [{‘deploy_url’: ‘testurl’, ‘id’: 11, ‘env_id’: 12, ….. etc

class tasks(models.Model):
    #question = models.ForeignKey(Question, on_delete=models.CASCADE)
    #project_name = models.ForeignKey(projects, on_delete=models.CASCADE)
    #env = models.ForeignKey(deploy_env, on_delete=models.CASCADE)
    env = models.ForeignKey(MGDeployEnv, on_delete=models.CASCADE)
    deploy_url = models.CharField(max_length=200)
    owner = models.CharField(max_length=200)
    date = models.DateTimeField(default=timezone.now)
    status = models.CharField(max_length=200, blank=True)
    result = models.TextField(blank=True)

    def __str__(self):
        return self.deploy_url

More Model Query:

There two methods to get the searching result, for example.

1.2 Foward query (query by main set)

if we would like get the all deploy environment of PROD,  or deploy environment of Projects test, we can do following query:

by project

pj=projects.objects.get(project_name=‘abc’)

pj.mgdeployenv_set.all()

or shorter 

projects.objects.get(project_name=‘cpg’).mgdeployenv_set.all()

<QuerySet [<MGDeployEnv: cpg_cons_be>, <MGDeployEnv: cpg_cons_all>]>

by environments

env = AppEnv.objects.get(name=’cons’)

env.mgdeployenv_set.all()

QuerySet [<MGDeployEnv: abc_cons_be>, <MGDeployEnv: abc_cons_all>]>

1.3 BackForward query(query by sub set)

by project

MGDeployEnv.objects.filter(project_name__in=projects.objects.filter(project_name=‘abc’))

<QuerySet [<MGDeployEnv: abc_cons_be>, <MGDeployEnv: abc_cons_all>]>

by environments

MGDeployEnv.objects.filter(env_name__in=AppEnv.objects.filter(name=‘cons’))

<QuerySet [<MGDeployEnv: abc_cons_be>, <MGDeployEnv: abc_cons_all>]>

 

as you can see, this 4 queries are the same.

 

Reference Links:

http://scottlobdell.me/2015/01/sql-database-best-practices-django-orm/ 

 

2. Many to Many

https://docs.djangoproject.com/en/2.0/topics/db/examples/many_to_many/

Regular Expression to minimum(non-greedy) matching

If we would like to match multiple duplicate content in the same line, we would like to use minimum match by using RE.

for example:

filename: text

pillar[‘abc’]
pillar[‘abc’]
pillar[‘abc’]}pillar[‘wx’]||pillar[‘yz’]
pillar[‘abc’]

1. matched expression python

import re

f=open('./text','r').read()
# non-greddy result:

print(re.findall('(pillar\[.*?\])',f))

# ourput: ["pillar['abc']", 
"pillar['abc']", 
"pillar['abc']", 
"pillar['wx']", 
"pillar['yz']", 
"pillar['abc']"]

# greedy match result:

print(re.findall('(pillar\[.*\])',f))

#output: ["pillar['abc']", 
"pillar['abc']", 
"pillar['abc']}pillar['wx']||pillar['yz']", 
"pillar['abc']"]

 

2. matched expression using shell

grep -o -P "pillar\['.*?'\]" text

# output: 
pillar['abc']
pillar['abc']
pillar['abc']
pillar['wx']
pillar['yz']
pillar['abc']

How to use privileges port less than 1024 with non-root user

original url: https://blogs.oracle.com/sduloutr/binding-a-server-to-privileged-port-on-linux-wo-running-as-root

Using setcap command, for example, if you tomcat run with 80 with user tomcat

# setup the net bind program
setcap 'cap_net_bind_service=+epi' $JAVA_HOME/bin/java
# start tomcat
systemctl start tomcat
# check port
netstat -ant |grep 444
tcp        0      0 0.0.0.0:444             0.0.0.0:*               LISTEN

All done!

[转自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 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>

 

我所积累的20条编程经验

Referehce link: http://www.williamlong.info/archives/2405.html
前人的经验不得不借鉴.

编者按:原文作者乔纳森·丹尼可(Jonathan Danylko)是一位自由职业的web架构师和程序员,编程经验已超过20年,涉足领域有电子商务、生物技术、房地产、医疗、保险和公用事业。正如乔纳森在文中所言,本文适合刚毕业的大学生和刚入门的程序员。如果你已是高级开发人员,或许你能在本文中看到自己的身影。

  从11岁时,我就一直在编程,并且一直都很喜欢技术和编程。这些年来,我积累了一些艰难又容易的经验。作为一名程序员,你或许还没这些经验,但我会把它们献给那些想从中学到更多的朋友。

  我会持续更新这些经验,我可能还会有更多的感想,但就我这20年来看,我想下面这个列表中基本不需要增添额外的东西了。下面就是我至今最难忘的经验。

  1. 估算解决问题所需要的时间。不要怕,承认吧!我曾见过一些程序员为了解决一个特殊问题而坐在显示器前面8小时。为自己定一个时间限制吧,1小时、30分钟或甚至15分钟。如果在这期间你不能解决问题,那就去寻求帮助,或到网上找答案,而不是尝试去做“超级堆码员”。

  2. 编程语言是一种语言,只是一种语言。随着时光推移,只要你理解了一种语言的原理,你会发现各种语言之间的相似之处 。你所选择的语言,你应该觉得“舒服”,并且能够写出有效(而且简洁)的代码。最重要的,让语言去适应项目,反之亦然。

  3. 不要过于注重程序的“设计模式”。 有时候,写一个简单的算法,要比引入某种模式更容易。在多数情况下,程序代码应是简单易懂,甚至清洁工也能看懂。

  4. 经常备份代码。在我年轻时,我就有过因硬盘故障而丢了大量代码的经历,这经历很恐怖的。只要你一次没有备份,就应当像有着严格的期限,客户明天就需要。此时就该源码/版本控制软件大显身手了。

  5. 承认自己并不是最顶尖的程序员 – 知不足。我常想,我对编程了解已足够多,但是总有其他人比你优秀。正所谓,“一山总比一山高”。所以,向他们看齐吧!

  6、学习再学习。正如第5点所说,我经常会在手里拿一本计算机或编程相关的杂志或书(不信,可以问我的朋友)。诚然,总有很多你不知道的技术,你可以从中学习以保持不落后。如果你有一种灵巧的方式来获取你需要的新技术,那你每天都应该坚持学习。

  7. 永恒的变化。你对待技术/编程知识,就应像你对待股票一样:多样化。不要在某一特定技术上自我感觉良好。如果那种技术或语言已经没有足够支持,那你还不如现在就开始更新你的简历,并启动培训新计划。我能保持前行的主要原则是什么呢?至少了解两到三种语言,所以,如果某种语言过时了,你在学习新技术的时候还可以依靠另一种语言。

  8. 提携新人。协助并且培养初级/入门的开发人员学习优秀的编程方法和技巧。也许你还不知道,在帮助他们向更高一层前进时,你自己也在向更高一层提升,你会更加自信。

  9. 简化算法。代码如恶魔,在你完成编码后,应回头并且优化它。从长远来看,这里或那里一些的改进,会让后来的支持人员更加轻松。

  10. 编写文档。无论是Web服务的API,还是一个简单的类,你尽量编写相应文档。我曾经引以为豪的代码注释,因过度注释而有人指责。给三行代码加一行注释,只需要你几秒时间。如果那是一个比较难以理解的技术,千万别担心过多注释。如果你能很好做好自己的工作,大多数架构师、后备程序员、支持组都会感激你。

  11. 测试、测试再测试。我是一名黑盒测试粉丝。当你完成编码后,你“被认可”的时候就开始了。如果你们公司有QA部门,如果你的代码中有错误,那你得到的评论,会比项目经理还多。如果你不彻底测试自己的代码,那恐怕你开发的就不只是代码,可能还会声名狼藉。

  12. 庆祝每一次成功。我见过很多程序员在解决编程技术难题后,会和同伴握手、击掌或甚至手舞足蹈。每个人在生命中都会碰到“顿悟”。如果一个程序员高兴地跑来叫你去看他的非凡代码,也许你已经看过这样的代码100遍了,但你也应该为了这个家伙而庆祝第101次。(编者注:《庆祝成功的九种方式》。)

  13. 经常检查代码。 在公司,你的代码要经常检查(包括自查和其他同事检查)。不要把别人的检查,看成是对代码风格的苛求。应该把它们看作是有建设性的批评。对个人来说,经常检查你的代码并且自问,“我怎样才能写得更好呢?” 这会加速你的成长,让你成为一个更优秀的程序员。

  14. 回顾你的代码。在看到自己以前的代码时,通常会有两种方式:“难以至信,这代码是我写的”和“难以至信,这代码是我写的”。第一种往往是厌恶的语气,并在想如何改进它。你也许会惊叹,旧代码也能复活成为一种更好的程序,甚至是一个完整的产品。第二种通常带着惊奇和成就感。开发人员应该一到两个自己完成的项目成果,能让众人不禁而立并注目而观的项目。同样,基于你优越的编程能力,你可以把过去的程序或项目拿出来,把它们更新为更加优秀的产品或想法。

  15. 幽默是不可缺的。在我20年的开发生涯中,我还没有碰到哪位程序员是没有幽默感的。实际上,干我们这行,幽默是一项必备品。

  16. 谨防那些无所不知的程序员,不愿分享的程序员,还有经验不足的程序员。当你遇到这几种程序员时,你自己要谦虚。无所不知的程序员,更想当一个英雄而不是团队成员;保守的程序员则是在编写着他们独享的代码;而经验不足的程序员则会每十分钟就来问你一下,当代码完成后,代码已经是你的,而不是他们。

  17. 任何项目都不会那么简单。朋友、家人和同事曾请求我仓促做一些事情,仓促做一个程序或者网站。对于这样的事,应该从双方做计划,才能做出令两方都会满意的东西。如果某人起初只是需要一个使用Microsoft Access的、只有有3个页面的网站,但来就很可能变成一个有15个页面的网站,并使用SQL Server,有一个论坛,还有一个定制的CMS(内容管理系统)。

  18. 任何时候不要想当然。假如你承接一个简单的项目,你可能会认为某个部分可以轻松完成。千万别这样想!除非你有一个类、组件、或者一段已经写好的代码,并且在现有的项目已经测试通过。不要认为这将是很容易的。

  19. 没有已经完成的软件。曾经有一位程序员告诉我,没有软件是已经完成的,它只是“暂时完成了”。这是明智的忠告。如果客户还在使用你写的程序,并经受了时间的考验。如果有机会,你仍在更新它,这并不是什么坏事,这让你不断地前行。

  20. 耐心是一种美德。当客户、朋友或家庭成员用电脑的时候,他们也许会受挫,进而想砸电脑,或气冲冲地离开。我一直在告诉他们,“是你掌控电脑,不是电脑掌控你。”对于用作编程的电脑,你要有一定的耐心。一旦程序员知道问题所在后,他们就会站在电脑的角度看问题,并且说“哦,这就是为什么它是这样做。”