转到正文

浪淘沙

静观己心,厚积薄发

存档

分类: 网摘

原文地址:理解Javascript的闭包

前言:还是一篇入门文章。Javascript中有几个非常重要的语言特性——对象、原型继承、闭包。其中闭包对于那些使用传统静态语言C/C++的程序员来说是一个新的语言特性。本文将以例子入手来介绍Javascript闭包的语言特性,并结合一点ECMAScript语言规范来使读者可以更深入的理解闭包。

注:本文是入门文章,例子素材整理于网络,如果你是高手,欢迎针对文章提出技术性建议和意见。本文讨论的是Javascript,不想做语言对比,如果您对Javascript天生不适,请自行绕道。

什么是闭包

闭包是什么?闭包是Closure,这是静态语言所不具有的一个新特性。但是闭包也不是什么复杂到不可理解的东西,简而言之,闭包就是:

• 闭包就是函数的局部变量集合,只是这些局部变量在函数返回后会继续存在。

• 闭包就是就是函数的“堆栈”在函数返回后并不释放,我们也可以理解为这些函数堆栈并不在栈上分配而是在堆上分配

• 当在一个函数内定义另外一个函数就会产生闭包

上面的第二定义是第一个补充说明,抽取第一个定义的主谓宾——闭包是函数的‘局部变量’集合。只是这个局部变量是可以在函数返回后被访问。(这个不是官方定义,但是这个定义应该更有利于你理解闭包)

做为局部变量都可以被函数内的代码访问,这个和静态语言是没有差别。闭包的差别在于局部变变量可以在函数执行结束后仍然被函数外的代码访问。这意味着函数必须返回一个指向闭包的“引用”,或将这个”引用”赋值给某个外部变量,才能保证闭包中局部变量被外部代码访问。当然包含这个引用的实体应该是一个对象,因为在Javascript中除了基本类型剩下的就都是对象了。可惜的是,ECMAScript并没有提供相关的成员和方法来访问闭包中的局部变量。但是在ECMAScript中,函数对象中定义的内部函数() inner function是可以直接访问外部函数的局部变量,通过这种机制,我们就可以以如下的方式完成对闭包的访问了。

function greeting(name) {
    var text = 'Hello ' + name; // local variable
    return function() { alert(text); }  // 每次调用时,产生闭包,并返回内部函数对象给调用者
}
var sayHello=greeting("Closure");
sayHello()  // 通过闭包访问到了局部变量text

上述代码的执行结果是:Hello Closure,因为sayHello()函数在greeting函数执行完毕后,仍然可以访问到了定义在其之内的局部变量text。

好了,这个就是传说中闭包的效果,闭包在Javascript中有多种应用场景和模式,比如Singleton,Power Constructor等这些Javascript模式都离不开对闭包的使用。

ECMAScript闭包模型

ECMAScript到底是如何实现闭包的呢?想深入了解的亲们可以获取ECMAScript 规范进行研究,我这里也只做一个简单的讲解,内容也是来自于网络。

在ECMAscript的脚本的函数运行时,每个函数关联都有一个执行上下文场景(Execution Context) ,这个执行上下文场景中包含三个部分

  • 文法环境(The LexicalEnvironment)
  • 变量环境(The VariableEnvironment)
  • this绑定

其中第三点this绑定与闭包无关,不在本文中讨论。文法环境中用于解析函数执行过程使用到的变量标识符。我们可以将文法环境想象成一个对象,该对象包含了两个重要组件,环境记录(Enviroment Recode),和外部引用(指针)。环境记录包含包含了函数内部声明的局部变量和参数变量,外部引用指向了外部函数对象的上下文执行场景。全局的上下文场景中此引用值为NULL。这样的数据结构就构成了一个单向的链表,每个引用都指向外层的上下文场景。

例如上面我们例子的闭包模型应该是这样,sayHello函数在最下层,上层是函数greeting,最外层是全局场景。如下图:

因此当sayHello被调用的时候,sayHello会通过上下文场景找到局部变量text的值,因此在屏幕的对话框中显示出”Hello Closure”

变量环境(The VariableEnvironment)和文法环境的作用基本相似,具体的区别请参看ECMAScript的规范文档。

闭包的样列

前面的我大致了解了Javascript闭包是什么,闭包在Javascript是怎么实现的。下面我们通过针对一些例子来帮助大家更加深入的理解闭包,下面共有5个样例,例子来自于JavaScript Closures For Dummies(镜像)

例子1:闭包中局部变量是引用而非拷贝

function say667() {
    // Local variable that ends up within closure
    var num = 666;
    var sayAlert = function() { alert(num); }
    num++;
    return sayAlert;
}
var sayAlert = say667();
sayAlert()

因此执行结果应该弹出的667而非666。

例子2:多个函数绑定同一个闭包,因为他们定义在同一个函数内。

function setupSomeGlobals() {
    // Local variable that ends up within closure
    var num = 666;
    // Store some references to functions as global variables
    gAlertNumber = function() { alert(num); }
    gIncreaseNumber = function() { num++; }
    gSetNumber = function(x) { num = x; }
}
setupSomeGolbals(); // 为三个全局变量赋值
gAlertNumber(); //666
gIncreaseNumber();
gAlertNumber(); // 667
gSetNumber(12);//
gAlertNumber();//12

例子3:当在一个循环中赋值函数时,这些函数将绑定同样的闭包

function buildList(list) {
    var result = [];
    for (var i = 0; i < list.length; i++) {
        var item = 'item' + list[i];
        result.push( function() {alert(item + ' ' + list[i])} );
    }
    return result;
}
function testList() {
    var fnlist = buildList([1,2,3]);
    // using j only to help prevent confusion - could use i
    for (var j = 0; j < fnlist.length; j++) {
        fnlist[j]();
    }
}

testList的执行结果是弹出item3 undefined窗口三次,因为这三个函数绑定了同一个闭包,而且item的值为最后计算的结果,但是当i跳出循环时i值为4,所以list[4]的结果为undefined.

例子4:外部函数所有局部变量都在闭包内,即使这个变量声明在内部函数定义之后。

function sayAlice() {
    var sayAlert = function() { alert(alice); }
    // Local variable that ends up within closure
    var alice = 'Hello Alice';
    return sayAlert;
}
var helloAlice=sayAlice();
helloAlice();

执行结果是弹出”Hello Alice”的窗口。即使局部变量声明在函数sayAlert之后,局部变量仍然可以被访问到。

例子5:每次函数调用的时候创建一个新的闭包

function newClosure(someNum, someRef) {
    // Local variables that end up within closure
    var num = someNum;
    var anArray = [1,2,3];
    var ref = someRef;
    return function(x) {
        num += x;
        anArray.push(num);
        alert('num: ' + num +
        '\\nanArray ' + anArray.toString() +
        '\\nref.someVar ' + ref.someVar);
    }
}
closure1=newClosure(40,{someVar:'closure 1'});
closure2=newClosure(1000,{someVar:'closure 2'});
closure1(5); // num:45 anArray[1,2,3,45] ref:'someVar closure1'
closure2(-10);// num:990 anArray[1,2,3,990] ref:'someVar closure2'

闭包的应用

Singleton 单件:

var singleton = function () {
    var privateVariable;
    function privateFunction(x) {
        ...privateVariable...
    }
    return {
        firstMethod: function (a, b) {
            ...privateVariable...
        },
        secondMethod: function (c) {
            ...privateFunction()...
        }
    };
}();

这个单件通过闭包来实现。通过闭包完成了私有的成员和方法的封装。匿名主函数返回一个对象。对象包含了两个方法,方法1可以方法私有变量,方法2访问内部私有函数。需要注意的地方是匿名主函数结束的地方的’()’,如果没有这个’()’就不能产生单件。因为匿名函数只能返回了唯一的对象,而且不能被其他地方调用。这个就是利用闭包产生单件的方法。

参考:

JavaScript Closures For Dummies(镜像) 可惜都被墙了。

Advance Javascript (Douglas Crockford 大神的视频,一定要看啊)

原文地址:理解Javascript的闭包

另外一篇 Javascript中Closure及其相关概念  感觉也不错。

关于js闭包的问题 自己还是需要好好地研究研究

原文地址:JS实现拖动div层移动

JS实现拖动div层移动

      在谈到拖动div层之前,我们有必要来了解下 下面JS几个属性的区别—-  pageX,pageY,layerX,layerY,clientX,clientY,screenX,screenY,offsetX之间的区别!

     PageX: 鼠标在页面上的位置,从页面左上角开始,即是以页面为参考点,不随滑动条移动而变化.(只有firefox等标准游览器特有,IE没有)。
clientX: 鼠标在页面上可视区域的位置,从浏览器可视区域左上角开始,即是以浏览器滑动条此刻的滑动到的位置为参考点,随滑动条移动 而变化.

这两个最主要的区别是 在有滚动条的情况下,pageX是不随滚动条变化而变化,clientx是在可视区域内的距离,不包括滚动条的距离。

  screenX: 鼠标在屏幕上的位置,从屏幕左上角开始,这个没有任何争议.

     offsetX和layerX

      offsetX   IE特有,鼠标相比较于触发事件的元素的位置,以元素盒子模型的内容区域的左上角为参考点,如果有boder,可能出现负值。

      layerX:   firefox特有,鼠标相比较于当前坐标系的位置,即如果触发元素没有设置绝对定位或相对定位,以页面为参考点,如果有,将改变参考坐标系,从触发元素盒子模型的border区域的左上角为参考点 也就是当触发元素设置了相对或者绝对定位后,layerX和offsetX就幸福地生活在一起^-^,几乎相等,唯一不同就是一个从border为参考点,一个以内容为参考点,FF从border开始.

    pageX,pageY只有firefox特有,IE没有,所以要针对游览器兼容性写个函数,Jquery源码中 这样写的,

    所以我们也可以针对写个公用的函数,代码如下:

function pageXY(e) {
    var event = e || window.event;

    var doc = document.documentElement,
          body = document.body;

    // IE
    if (event.pageX == null && event.clientX !=  null ) {
        var doc = document.documentElement,
            body = document.body;
            event.pageX = event.clientX + ( doc && doc.scrollLeft || body && body.scrollLeft || 0 ) - ( doc && doc.clientLeft || body && body.clientLeft || 0 );

            event.pageY = event.clientY + ( doc && doc.scrollTop  || body && body.scrollTop  || 0 ) - ( doc && doc.clientTop  || body && body.clientTop  || 0 );

            return {
                x : event.pageX,
                y : event.pageY
            }
        }

        // firefox
        return {
            x : event.pageX,
            y : event.pageY
        }
    }

offsetX 是IE特有的 layerX是firefox特有的,所以针对这两个也可以写个公用的函数 代码如下:

 

function offsetXY(e) {
    var event = e || window.event;
    return {
         x:event.offsetX || event.layerX,
                 y:event.offsetY || event.layerY
    }
}

 

JSFiddle链接代码如下:

 想看div层拖动的话 请点击我!

拖动层的基本原理是:

首先先来理解下 我们要在页面上拖动某一块 到 页面上的另外一个位置 那么肯定这块元素是绝对定位的 并且 我们移动它时 是不断的改变他们的top值和left值!再者 我们拖动它时候肯定要触发事件!有 onmousedown事件!

  那么我们现在是要计算的是 我们这个元素被拖动到页面上的某个位置时的 左上标的位置X和Y。

      如下图所示:

      

 

要计算元素的左上的x和y坐标 如上图所示:就是指x = clientX-offsetX + “px”; y= clientY-offsetY + “px”;

HTML和CSS代码如下:

 

<div id="father" style="border:0px solid red;width:200px;">
    <div id="a" style="background:red;width:100px;height:100px">长,宽都是100px</div>
    <div id="b" style="border-top:0px solid red;background:yellow;width:100px;height:100px;margin-left:100px;"></div>
    </div>
<style>
    #oDiv{ width:200px; height:200px; color:#fff;background:#00C; position:absolute; top:200px; left:200px; z-index:100;overflow:hidden;}
 </style>

 

JS所有代码如下:

function pageXY(e) {
    var event = e || window.event;

    var doc = document.documentElement,
        body = document.body;

    // IE
    if (event.pageX == null && event.clientX !=  null ) {
        var doc = document.documentElement,
            body = document.body;

            event.pageX = event.clientX + ( doc && doc.scrollLeft || body && body.scrollLeft || 0 ) - ( doc && doc.clientLeft || body && body.clientLeft || 0 );

            event.pageY = event.clientY + ( doc && doc.scrollTop  || body && body.scrollTop  || 0 ) - ( doc && doc.clientTop  || body && body.clientTop  || 0 );

            return {
                x : event.pageX,
                y : event.pageY
            }
        }

        // firefox
        return {
            x : event.pageX,
            y : event.pageY
        }
    }

    function offsetXY(e) {
        var event = e || window.event;
        return {
             x:event.offsetX || event.layerX,
                         y:event.offsetY || event.layerY
        }
    }
    var $=function(id){
        return ("string"==typeof id) ? document.getElementById(id):id;
    };
    $('a').onmousemove = function(e){
        text(e);
    }
    $('b').onmousemove = function(e){
        text(e);
    }
    function text(e) {
        e = e || window.event;
        var offset = offsetXY(e),
            page = pageXY(e);

        var doc = document.documentElement,
            body = document.body;
                $("pageX").innerHTML= page.x;
        $("pageY").innerHTML= page.y;
        $("clientX").innerHTML=e.clientX;
        $("clientY").innerHTML=e.clientY;
        $("screenX").innerHTML=e.screenY;
        $("screenY").innerHTML=e.screenY;
        $("scrollTop").innerHTML=doc && doc.scrollTop;
        $("scrollLeft").innerHTML=doc && doc.scrollLeft;
        $("offsetX").innerHTML = offset.x;
        $("offsetY").innerHTML = offset.y;
    }

    window.onload = function () {
            var oDiv = document.getElementById("oDiv");//oDiv必须使用CSS定位
            oDiv.onmousedown = drag;
            function drag(evt) {
                evt = evt || window.event;
                this.onmouseup = drop;
                this.onmousemove = moveDiv;
                this.offset = {
                    x:evt.offsetX || evt.layerX, //layerX 和layerY是w3c标准的 offsetX 和 offsetY是IE标准的
                    y:evt.offsetY || evt.layerY
                };
            }
            function moveDiv(evt) {
                evt = evt || window.event;
                this.style.left = evt.clientX-this.offset.x+"px";
                this.style.top = evt.clientY-this.offset.y+"px";
            }
            function drop(evt) {
                this.onmouseup = null;
                this.onmousemove = null;
            }
        };

原文地址:JS实现拖动div层移动

另一个使用JQUERY的文章为:Jquery 实现层的拖动,支持回调函数

还有一个 “自己写了一个无缝滚动的插件(jQuery)”也很有意思

JSON的标准格式如下:
1.所有的键必须用双引号包裹
2.JSON不支持注释
3.JSON的值不得为函数不得未定义。值可以是用双引号包裹的字符串,或是数字,或true、false,或null,或一个对象、数组。允许嵌套结构。
4.JSON的最后一个值不使用逗号(,)分隔符

更相信的请点这里

 

原文地址:由蔡文胜骗股有感——技术人员,你除了技术,还有啥

近闻悉,中国著名天使投资人——蔡文胜,对其4399cto曹政股权被稀释一事,蔡文胜并未否认,他表示自己早已卸任4399董事长职务,股权的事 是4399公司内部的事情。其中来龙去脉,作为局外人也不好评论,但程序员们,你们除了技术外,是不是要有另外立足与世界的本领。

不错,程序员,本应是一个神圣职业,你们正是利用你们手中武器改变这世界。但是,世界终归是人的世界,终归是情感的世界,不是机器的世界。所以 了一般做技术的人,显得与这个世界显得格格不入。一般喜欢技术的人,就木讷,和机器相处多了,就显的更加的木讷。被具有中国特色的人情社会所抛弃,也很有 可能,呗坑蒙拐骗也是理所当然的。因此,技术人员,你除了技术,应该还有啥把。那请提高你的人文修养把!

作为一个技术人员,想成为管理者并不难,只要你坚持这个工作。在国内的氛围中,当技术人员,在经验、能力、年龄达到一定层面后,公司都会想办法提升 他的职位,进入管理岗位,如项目经理、研发主管、技术部经理、技术总监等等。很少会有公司能允许一个三十多岁的程序员存在,即便他做着技术工作,也会给他 安个什么大牌的头衔。

当进入管理岗位后,痛苦就开始了。专业技术人员与技术管理人员,虽然都是技术性工作,前者侧重于技术,后则侧重于管理,工作性质已经有了明显区别。 相较于技术,管理工作更复杂。管理工作是面对人,技术工作是面对电脑,人比电脑复杂得太多了。没有学不会的技术,管理则需要岁月历炼。管理的英语单词 “Manage”,就是男人与岁月的合成词。

国王的命运

管理性工作,不管你做的有多好,总会有人给你提意见,总会有人不满意。相比较而言,做技术性工作,真是太幸福了,不用操心,专心至致,不会有人打扰,做起来也顺手,工作成果总会受到大家的赞誉。

当我在做经理后,总是忍不住回过头来写代码,一方面是因为管理能力不足,任务分解不出去,一方面是对他们做的工作不满意,最主要的还是,写代码的感 觉实在太幸福了。虽然我现在也写代码,但目的已经不是为了体验幸福,而是觉得作为一个技术方面的管理者,不应该丢弃技术,工作重点已经不是程序编写。

在那个阶段,我非常迷茫,不知道怎么才能把工作做好,团队成员整天提意见,公司领导责备多于鼓励,我的自信心跌到了冰点,甚至有想过放弃管理工作。但说实话,又有些不甘心,也有些中国人官本位思想,毕竟是混到个小领导了,真是再下来了,多没有面子。

在这个过程中,我看了很多管理的书、管理的讲座,始终不得要领。有一次在书店闲逛,看到《沉思录》随手拿起来翻看,我知道这本书,之前中央领导向社会推荐读物,温家宝推荐了《沉思录》。也就是这一翻,看到了将会影响我终生的一句话(一点儿也不夸张)。

“国王的命运,就是行善事而遭恶誉”。

我毫不犹豫的买下这本书,如果一本书有一句话值得拥有,这几十块钱就花值了。

前一段,有个朋友刚当了项目经理,很痛苦,在QQ上向我诉苦。我说,我送你一句话,“国王的命运,就是行善事而遭恶誉”,管理者就要有王的胸怀,不 仅要敢于担当,还要有胸襟承受非议,相信自己是对的,做就是了。几秒钟后,他的QQ签名变成了这句话;几个月后,说他感觉自己已经可以胜任了。

在我的管理工作中,每次提拔主管时,我都会赠送这句话给他们。我不担心他们的技术能力,我担心他们的心理承受能力。其实这句话,有些类似于“走自己路,让别人去说吧”的意思,但是它更有气魄。

《梓人传》

当刚开始做管理工作时,任务分解是一个让我非常头痛的问题。

如何能够合理的把任务分配给团队成员,让他们轻松完成,而且又能保证质量,这对我来说,实在是个难以解决的问题。

往往是,任务分解不出去,自己埋头干活,团队进度没时间把控;要么就是团队成员做完工作,不合要求,自己伸手把任务又重做一遍。很显然,我做得更好,更快。看着程序员们崇拜的目光,也有点小小的成就感。可到头来,自己累得要死,并没有落好,还净落埋怨。

在这个过程中,我着重学习了项目管理,后来还考了一个信息系统的项目管理师。我很清楚,自己应该高屋建棱,我还自己总结了一句话,“低姿态工作,高视角审视”。事实上,我根本不知道该如何去“高视角”。虽然书上讲了很多方法,但操作起来总是不能令自己满意。

很偶然的,我在图书馆看杂书,看到柳宗元的《梓人传》,有些感触,后来上班时无事时,在网又搜这篇文章,仔细的阅读,还看了很多人的点评。虽然没有醍醐灌顶吧,但也受用良多。

例如文中所述:

“彼将舍其艺,而专其心智,能知体要欤”

“不炫能,不矜名,不亲小劳,不侵众宫,日与天下英才讨论其大经。如梓人之善运众工,而不伐艺。”

它说的这些原则,我全违背了,思路不正确,方法再正确也没有用。

法、术、势

为了规范开发行为,我制订了很多制度,因为从我自身管理思想上来说,我是崇尚制度化管理的。我学习了很多开发方法、开发模式,研习了很久,但任何一 种方法,应用到研发工作中,都是一堆问题。当有人质疑时,我总会引章据典的予以辩论,说得对方无可反驳,其实我也清楚,他是“口服心不服”。

我不知道自己哪里出了问题,我相信自己学习的东西都是正确的。为什么就实施不起来呢?

前几天和一个朋友还在聊这类事情,他也很迷茫,我告诉他,其实我也经历过这个阶段,我建议你有时间看看《韩非子》。我当时就是认真的看了《韩非子》(其实也没有看完了,至少比以前看得仔细了)之后,才有了较大改观。

《韩非子》是法家思想经典之作。我们总是以为,法家思想提倡“法”,就是制度化管理。事实上,法家的精髓不仅是“法”,而是包括:法、术、势。

法,是制度,是条例,也是规范,它有一定的约束性,但它不是为了约束,而是为了规范。

术,是手段,是技巧,例如,当发现别人做得不符合要求时,不要批评,而应该说:“你做得很好,但我认为,还有很大的提升空间。”

势,是权力,是职责,例如,韩非子中说,桀纣虽然很坏,但如果不是坐在王的位置上,也不能危害天下;尧舜虽然贤明,如果不是坐在王的位置上,也不能造福天下。

我们评论法家思想,总会说“法太苛”,并举秦朝失败的案例,事实上,至从秦朝之后,无论哪个朝代都在延用法家思想,也就是所谓的“儒表法里”(表面 是儒,其实是法)。到了唐朝,则大范围照搬秦制,为了不让别人说闲话,柳宗元说了句名言为唐朝开脱,“秦之失,失于政,非失于制”,就是说秦朝的制度是非 常好的,是他们管理上出了问题。

应用到我们管理中,制度化是必须的,其次还要考虑管理手段问题,不能完全依靠制度。最后,就是把合适的人放到合适的位置,明确其职责。

关于“法”,我们可以学习别人,甚至照搬。而“术”,则需要因地制异,需要管理艺术。而“势”,则需要因人而异、量才适用,它不仅需要高超的管理艺术,还要大胆授权、敢于放权。

注意沟通

学会倾听
·倾听的技巧
倾听是一种情感活动,在倾听时应该给客户充分的尊重、情感的关注和积极的回应。

1.倾听的定义

倾听是一种情感的活动,它不仅仅是耳朵能听到相应的声音。倾听还需要通过面部表情,肢体的语言,还有用语言来回应对方,传递给对方一种你很想听他说话的感觉,因此我们说倾听是一种情感活动,在倾听时应该给客户充分的尊重、情感的关注和积极的回应。

【案例】

倾听的“听”字在繁体中文是听字里有一个“耳”字,说明听字是表示用耳朵去听的;听字的下面还有一个“心”字,说明倾听时要用“心”去听;听字里还有一个“目”字,说明你听时应看着别人的眼睛地听;在“耳”的旁边还有一个“王”字,“王”字代表把说话的那个人当成是帝王来对待。

从听字的繁体结构中可以看出,倾听时不仅要用“耳朵”,还要用“心”,用“眼睛”,更重要的是要把你对面的那个人当成是帝王,充分地去尊重他。

2.听事实和情感

倾听不但要听清楚别人在讲什么,而且要给予别人好的感觉,那么听时服务代表都在听什么呢?对服务代表来说,需要听两点:

◆听事实

倾听事实意味着需要能听清楚对方说什么。要做到这一点,就要求服务代表必须有良好的听力。

◆听情感

与听事实相比,更重要的是听情感。服务代表在听清对方说事实时,还应该考虑客户的感受是什么,需不需要给予回应。

【案例】

A对B说:“我昨天看中一套房子,决定把它买下来。”B说:“哦,是吗?在哪儿呢?恭喜你呀。”A看中了房子,想买下来,这是一个事实,B问房子在那,这是对事实的关注,“恭喜你”就是对A的情感关注。

A把事实告诉B,是因为他渴望B与他共同分享他的喜悦和欢乐,而作为B,应对这种情感去加以肯定。对于服务代表而言,就是运用倾听的技巧,通过你的面部表情,肢体语言,给予客户恰当的及时回应。例如客服人员对客户说:“现在你就是这方面的专家,你真的是很内行。”这就是对客户的一种情感的关注。而在这种关注之前,服务代表在听到客户谈话时应该分辨出哪些是情感的部分,哪些是事实的部分。

3.提升倾听能力的技巧

◆永远都不要打断客户的谈话

可以这样说,在这个世界上就应该没有一个人说我喜欢或习惯打断过别人的谈话,很多时候一些人的倾听能力是很差的,他们都不是无意打断,而是有意识地打断对方的谈话。

无意识的打断是可以接受的,有意识的打断却是绝对不允许的。无意识地打断客户的谈话是可以理解的,但也应该尽量避免;有意识地打断别人的谈话,对于客户来讲是非常不礼貌的。当你有意识地打断一个人说话以后,你会发现,你就好像挑起来了一场战争,你的对手会以同样的方式来回应你,最后你们两个人谈话就可能变成了吵架。因此有意识的打断是绝对不允许的。

◆清楚地听出对方的谈话重点

当你与对方谈话时,如果对方正确地理解了你谈话中的意思,你一定会很高兴。至少他知道你成功地完成了我们上边所说的“听事实”的层面。

能清楚地听出对方的谈话重点,也是一种能力。因为并不是所有人都能清楚地表达自己的想法,特别是在不满,受情绪的影响的时候,经常会有类似于“语无伦次”的情况出现。而且,除了排除外界的干扰,专心致志地倾听以外,你还要排除对方的说话方式给你的干扰,不要只把注意力放在说话人的咬舌、口吃、地方口音、语法错误或“嗯”、“啊”等习惯用语上面。

◆适时地表达自己的意见

谈话必须有来有往,所以要在不打断对方谈话的原则下,也应适时地表达自己的意见,这是正确的谈话方式。这样做还可以让对方感受到,你始终都在注意地听,而且听明白了。还有一个效果就是可以避免你走神或疲惫。

◆肯定对方的谈话价值

在谈话时,即使是一个小小的价值,如果能得到肯定,讲话者的内心也会很高兴的,同时对肯定他的人必然产生好感。因此,在谈话中,一定要用心地去找对方的价值,并加以积极的肯定和赞美,这是获得对方好感的一大绝招。比如对方说:“我们现在确实比较忙”,你可以回答:“您坐在这样的领导位子上,肯定很辛苦。”

◆配合表情和恰当的肢体语言

当你与人交谈时,对对方活动的关心与否直接反映在你的脸上,所以,你无异于是他的一面镜子。

光用嘴说话还难以造成气势,所以必须配合恰当的表情,用嘴、手、眼、心灵等各个器官去说话。但要牢记切不可过度地卖弄,如过于丰富的面部表情、手舞足蹈、拍大腿、拍桌子等。

◆避免虚假的反应

在对方没有表达完自己的意见和观点之前,不要做出比如“好!我知道了”、“我明白了”、“我清楚了”等反应。这样空洞的答复只会阻止你去认真倾听客户的讲话或阻止了客户的进一步的解释。

在客户看来,这种反应等于在说“行了,别再罗嗦了”。如果你恰好在他要表达关键意思前打断了他,被惹恼了的客户可能会大声反抗:“你知道什么?”那就很不愉快了。

·倾听——团队沟通的艺术

在团队沟通中,言谈是最直接、最重要和最常见的一种途径,有效的言谈沟通很大程度上取决于倾听。

有一个古老的哲学问题:“森林中一棵树倒了下来,那儿不会有人听到,那么能说它发出声响了吗?”关于沟通,我们也可以问类似的问题:如果你说话时没人听,那么能说你进行沟通了吗?

团队沟通中,言谈是最直接、最重要和最常见的一种途径,有效的言谈沟通很大程度上取决于倾听。作为团体,成员的倾听能力是保持团队有效沟通和旺盛生命力的必要条件;作为个体,要想在团队中获得成功,倾听是基本要求。在对美国500家最大公司进行的一项调查表明,做出反应的公司中超过50%的公司为他们的员工提供听力培训。有研究表明:那些是很好的倾听者的学生比那些不是的学生更为成功。在工作中,倾听已被看作是获得初始职位、管理能力、工作成功、事业有成、工作出色的重要必备技能之一。
在倾听的过程中,如果人们不能集中自己的注意力,真实地接受信息,主动地进行理解,就会产生倾听障碍。在人际沟通中,造成信息失真。影响倾听效率障碍不外乎以下三点:

1.环境干扰

环境对人的听觉与心理活动有重要影响,环境中的声音、气味、光线以及色彩、布局,都会影响人的注意力与感知。布局杂乱、声音嘈杂的环境将会导致信息接收的缺损。

2.信息质量低下

双方在试图说服、影响对方时,并不一定总能发出有效信息,有时会有一些过激的言辞、过度的抱怨,甚至出现对抗性的态度。现实中我们经常遇到满怀抱怨的顾客,心怀不满的员工,剑拔弩张的争论者。在这种场合,信息发出者受自身情绪的影响,很难发出有效的信息,从而影响了倾听的效率。

信息低下的另一个原因是,信息发出者不善于表达或缺乏表达的愿望。例如,当人们面对比自己优越或地位高的人时,害怕“言多必失”以致留下坏印象,因此不愿意发表自己的意见,或尽量少说。

3.倾听者主观障碍

在沟通的过程中,造成沟通效率低下的最大原因就在于倾听者本身。研究表明,信息的失真主要是在理解和传播阶段,归根到底是在于倾听者的主观障碍。

(1)个人偏见 即使是思想最无偏见的人也不免心存偏见。在一次国际会议上,以色列代表团的成员们在阐述其观点时,用了非常激烈的方式,他们抱怨泰国代表对会议不表示任何兴趣或热情,因为他们“只是坐在那里”,而泰国代表则认为以色列教授非常愤怒,因为他们“用了那么大的嗓门”。所以,在团队中成员的背景多样化时,倾听者的最大障碍就在于自己对信息传播者偏见,而无法获得准确的信息。

(2)先入为主 在行为学中被称为“首因效应”,它是指在进行社会知觉的过程中,对象最先给人留下的印象,对以后的社会知觉发生重大影响。也就是我们常说的,第一印象往往决定了将来。人们在倾听过程中,对对方最先提出的观点印象最深刻,如果对方最先提出的观点与倾听者的观点大相径庭,倾听者可能会产生抵触的情绪,而不愿意继续认真倾听下去。

(3)自我中心 人们习惯于关注自我,总认为自己才是对的。在倾听过程中,过于注意自己的观点,喜欢听与自己观点一致的意见,对不同的意见往往是置若罔闻,这样往往错过了聆听他人观点的机会。

掌握倾听的艺术并非很难,只要克服心中的障碍,从小节作起,肯定能够成功。现列出一些提高倾听能力的技巧以便核对、参考:

1.创造有利的倾听环境,尽量选择安静、平和的环境,使传递者处于身心放松的状态。

2.在同一时间内既讲话又倾听,这是不可能的事情,要立即停止讲话,注意对方的讲述。

3.尽量把讲话时间缩到最短。你讲话时,便不能聆听别人的良言,可惜许多人都忽略了这一点。

4.摆出有兴趣的样子。这是让对方相信你在注意聆听的最好方式,是发问和要求阐明他正在讨论的一些论点。

5.观察对方。端详对方的脸、嘴和眼睛,尤其要注视眼睛,将注意力集中在传递者的外表。这能帮助你聆听,同时,能完全让传递者相信你在聆听。

6.关注中心问题,不要使你的思维迷乱

7.平和的心态,不要将其他的人或事牵扯进来。

8.注意自己的偏见,倾听中只针对信息而不是传递信息的人。诚实面对、承认自己的偏见,并能够容忍对方的偏见。

9.抑制争论的念头。注意你们只是在交流信息,而非辩论赛,争论对沟通没有好处,只会引起不必要的冲突。学习控制自己,抑制自己争论的冲动,放松心情。

10.保持耐性,让对方讲述完整,不要打断他的谈话,纵然只是内心有些念头,也会造成沟通的阴影。

11.不要臆测。臆测几乎总是会引导你远离你的真正目标,所以要尽可能避免对对方做臆测。

12.不宜过早做出结论或判断。人往往立即下结论,当你心中对某事已做了判断时,就不会再倾听他人的意见,沟通就被迫停止。保留对他人的判断,直到事情清楚,证据确凿。

13.做笔记。做笔记不但有助于聆听,而且有集中话题和取悦对方的优点。如果有人重视你所说的话并做笔记,你不会受宠若惊吗?

14.不要自我中心,在沟通中,只要把注意力集中在对方身上,才能够进行倾听。但很多人习惯把注意力集中在自己身上,不太注意别人,这容易造成倾听过程的混乱和矛盾。

15.鼓励交流双方互为倾听者。用眼神、点头或摇头等身体语言鼓励信息传递者传递信息和要求别人倾听你的发言。

·积极倾听

这个世界的图像并不是自动进入我们大脑的,而是有选择的。我们不是在看,而是在寻觅着什么。我们不是听见世界上所有的声音,只是在听。

积极倾听是一种非常好的回应方式,既能鼓励对方继续说下去,又能保证你理解对方所说的内容。要熟练地使用这种技巧,首先要知道,当别人和你说话时,发生着什么样的事情。

人际交往首先源于个人内心。对方先是有一些感受或者想法想告诉你。为了传递这个信息,他首先必须将其转换成语言以及非语言代码,以便你能够理解。至于他选择什么样的代

码,什么样的语言和动作,以及说话时的音调,会由他的目的、所处环境、和你的关系亲密程度,以及他的年龄、教育背景、社会地位、文化背景和感情状况所决定。这个把内心的想法和感受转换成信息的过程被称为编码。

例如,假设你在给一个朋友播放音乐。他很喜欢,却希望能柔和一些。你无法知道他头脑中的想法,于是为了让你知道,他把自己的感受编码,用盖过音乐的声音对你说:“声音关小点儿!”
这样,你有了技术,还有更多。

原文地址:由蔡文胜骗股有感——技术人员,你除了技术,还有啥

PS:感觉这篇文章 博主写的很好。在“景德镇”咱不能一辈子coding,如果咱想在IT行业一直有优势、可以站得住脚的话,咱就要往上爬,需要学点管理;管理和咱们coding不那么一样,需要学的东西还有很多很多,各种为人处世的本事。。。

看了一篇文章深有感触。再次转载。

原文地址:http://www.cnblogs.com/naturesex/p/3594955.html

有时候想想程序员何苦为难程序员呢?

扳扳手指走上码农这个行业也有几年了,但是越来越觉得这个行业很累,有人说程序员就是二代农民工,我个人还是比较赞同的,对于刚入道的同仁们来 说确实就是个体力(脑力,眼力<你懂的,眼力比较>)活,真就迁扯不到什么高深的算法,基本上你要用的微软都帮你想到了。公司方面也充斥着各 种各样的复合型(什么都搞),一不小心就掉坑里了,好不容易爬出来,又被社会XXOO了。只能说人生在世几多愁,愁来愁去未到头。那既然跳进了这个火坑, 生活还得继续呀。在这几年中,也帮经理面试过不少人,但是有时候静下来想想很多情况下程序员经常有为难程序员的时候?又给苦逼添加了一份色彩,那就说说我 自己认为的程序员何苦为难程序员把(突然想起好像有首歌叫女人何苦为难女人#_#)!

 

一:对于面试

作为被面试的人:面试中有笔试我个人是很不喜欢的,既浪费纸张又浪费时间,我又不是来考试的,一来就给3页 纸以上的题目做,而且好多问答题。好吧笔试固然是一个测试手段,但是有些笔试题目也太不行了,都是网上复制下来的那种,而且还是最基本的概念题。相信大家 面试中有90%几率都会出现【什么是面向对象】吧,这样的测试题我只能呵呵。我比较喜欢文艺的公司,那就是上机解决1-3个在实际项目中出现的问题,如果 没时间完成的可以写伪代码,提供思路也是不错的,最后谈谈一些项目,和处理问题的方法,基本上就大概了解适不适合了。去面试程序员又不是考公务员,怎么那 么多笔试呢?不过有时候也碰到过面试题,后面写了要用自己理解是方式去写答案,而不是一味的名词解释。

作为面试的人:面试别人不管对方技术好与坏,长相是否很凶残,年龄大小,都要平等的去对待,有时候长得像小 孩子的比那些大叔级别的技术和口才好多了。个人觉得什么样的技术职位就应该放什么样技术的人,而不是放一个薪水开的比其他较低的人就可以了。要想想自己也 是这么过来的,平等对待对方,都是程序员何必为难自己人呢,特别是遇到那种容易紧张的面试者,其实本身技术可以的,紧张后什么都忘记了,这个时候面试官就 不要在制造紧张的气氛了,有时候讲个笑话调解下多好。这样良性循环下去,你给别人机会以后别人做了面试官也会给你机会。但是有一个事情我就不得不提起。有 些面试官当发现来面试的人开的工资比自己还高,就会出现应聘失败的情况(奶奶的开的比我还高,玩个毛啊)。我觉得正常的情况就是和经理以及HR谈谈,然后 给个综合的工资额度,然后HR去谈,而不是面试完回来后和经理说这个人技术不行。

  我想说的:

笔试题是怎么来的了,大部分情况不是经理网上复制,就是程序员自己down下来的,自己写代码都没时间,哪有时间出题目。有时候仔细想想其实这 个就是为难以后的自己。大家都学上一辈的人,都这样弄题目,导致大部分的面试提基本都一样的,完全失去了笔试的意义。虽然在面试的时候有些人会莫名的给你 一些算法的问题,什么是冒泡呀?排序有哪些方法呀,什么是树呀,怎么创建一个队列呀?等等等等,这样作为难道面试官的你就可以装一下。这些东西网上一抓一 大把,问问大概的原理就行了,有时候一个地方没说清就排斥这个人,程序员自己何苦为难以后的自己,都文艺一点多好,整一些名词解释有意思吗?还有就是对于 作为面试官的程序员自己压自己人工资的最鄙视,你老和HR报价压那么低干嘛,这样自己去别的公司工资能起来吗?HR理所当然的觉得程序员就值这么多,这样 以后自己出去能找到工资比现在工资高些的吗,一味的压低工资只是埋没以后的自己。

我最记得2年多前的一次面试,技术没问题,到了人事那里挂了,原因就是工资开高了,然后那个人事竟然说【她】自己做了6-7年的人事都才 12K,你开8k而且你还是专科,你觉得不是要求太高了吗?当时我脑袋一充血心里已经放弃这家公司,然后和她理论起来说:你做人事的和做技术的好像不能这 样对比吧,我们苦逼的加班你们加班吗,我们经常要学习新的技术你们要吗?程序有问题找的是我们程序员而不是测试人员吧,再说我们每天敲的字也比你们多吧? 反正说了霹雳扒拉说了很多,那个女的人事中途没说一句话,最后走的时候来了一句你工作才3年多点,你确实开高了。我当时笑了一下就走了。这件事情告诉我现 在的普通的行业已经追上IT所谓的高薪行业了。一些公司的HR只是当我们是傻乎乎的农民工,特别是女的HR。我的意思不是鼓励大家一味的乱开高工资,管他 三七二十一开了再说,而是要评估自己的技术、能力、工作年限来。我说的别大家不承认,举个例子把,大家都会面对一个事情就是很多同样3年和5年以上的,技 术能力等同的情况下工资很多是一样的,因为HR已经给程序员定了所谓的最高薪水。对于那种工作长的、经验丰富其实是一记猛棒,导致很多技术很好的都转到项 目经理和产品经理,埋没了很多写代码很好而且很牛逼的高级程序员。

我还想说:程序员面试官何苦为难程序员,更没必要和HR联合起来为难。

二:对于上班

正常上班:这个没什么好说的,完成自己本职工作后,如果有时间可以帮助同事分担一点,都是程序员相互帮助 才是王道啊,这样不至于一个人的失误导致整个小组加班或者挨骂,大家都认为程序员是最不会说话的人群,但是这个是极端的,业界那么多老板还不是程序员出生 的。多交流技术才能让这个行业进步,一个技术藏着掖着没什么意思,和人分享才是最大的乐趣,就好比你做了个软件没有人用,有意义吗?所有程序员不要自己憋 着自己,这样其实就是自己为难自己,也就是程序员为难程序员,要学会分享。

非正常上班(加班):让我先长叹一声,o(︶︿︶)o 唉!天天加班何时才能到头啊。。。。…………………………………………….

回归正题,我有时候问自己加班加班加你妹的班啊,什么都没有,加毛啊。其实大家心里都是排斥加班的,而且加班的效率是很低的,基本上写不了几行 代码,因为白天的能量都用完了,晚上根本就不想动了。为什么会加班,大家肯定经常会问到这个问题,最大原因就是资本主义要榨取最大的利益。回归现实就是经 理所谓的答应客户的时间,要快点啊,本来一个3个月的项目,硬逼着1个月完成了,这样的项目质量能有多好,可想而知。所以经常就会出现有用户骂,什么破系 统,真他妈的好慢好烂,特别是游戏开发。然后整个行业都变成这样了,然后大家理所当然的觉得程序员就要加班了。还一种加班的情况就是,所谓的绩效,我看是 HR来“讥笑”我们的吧,麻痹的这个是逼人加班的条款,不加班就面有可能面临扣工资,还一种就是同事都在加班,我不好意思走啊,就算我做完了自己的事情都 不好意思走,我想说那些加班的同事你把这个行业带坏了(这个过于极端了哈),但是这个确实是一个因素啊。

其实一般正常情况下,项目完成是不用怎么加班的,特别是经验丰富的程序员,基本上累积到一定程度后都是复制粘贴,但是想归想,现实却不是这样的,你不加班经理和同事会给你带上工作不积极的大帽子,这样一来不加都没办法了。

过去与未来大家都是程序员,何必用未来的自己来为难现在的自己,我好想说我们要学会拒绝加班,我的意思不是不加班,而是偶尔还是能接受的,天天这样是个人都要崩溃。

三:题外话

在中国正常的公司都会是以利益驱动为第一驱动力,毕竟公司要生存要发展嘛,这是一个不可回避的问题。其次才是需求驱动,最后甚至没有技术驱动这 一说。试想一下,利益驱动产生一种方案,之后的事情就可以用脚趾头去想了,肯定就是一个接着一个想法产生了,为了利润而去重复的生产,难道不是一件非常可 怕的事情嘛。苦了写代码的程序员们,本来可以去学去看新的知识,但却只能去造这些外表不同的轮子,这是一个恶性的循环。是不是应该跳出这个圈,有人说过不 要重复的去造轮子。也有人说过技术不是问题,这话也有道理,但如果你用脑去想想这话的意思就是没有什么问题解决不了,这就相当可笑了,这就是利益驱动造成 的可怕思想,之所以说出这种话,是因为你的出发点就是在想怎样通过现有的技术来搛取利益,而不是我现在有什么问题,现有技术解决不了,我怎样去解决它。

原文地址:http://www.cnblogs.com/naturesex/p/3594955.html

原文地址:http://xenojoshua.com/2011/05/php-why-include-not-require/

为什么不用require而用include呢?PHPer都应该知道,include是动态执行的,也就是说执行到include这个语句时才把文件包 含进来,而require是预先执行的,也就是说,在php文件在执行前就已经把相关的文件包含进来,组成一个大文件,如果include改成 require,当然也可以执行,但是这样并不会达到好的性能。

原文地址:http://xenojoshua.com/2011/05/php-why-include-not-require/

 

PS:以前我只知道 include 的文件不存在的时候 会产生一个 warning的信息,require 的文件不存在的时候 会产生一个fatal error。 今天见戴神文章,又长见识了。

今天发现 PHP中include和require的区别详解 这篇文章介绍的比较清楚了,如果有兴趣可以前往拜读

原文地址:http://www.biaodianfu.com/hacker-howto.html

看了《黑客与画家》,于是在网上找到了这篇如何成为黑客的教材。记录下来于大家一起学习。本文由:The Duck Typist 翻译。英文原文在这里:http://catb.org/~esr/faqs/hacker-howto.html

如何成为一名 Hacker

Eric Steven Raymond

Thyrsus Enterprises

Copyright © 2001 Eric S. Raymond <esr@thyrsus.com>

Wang Dingwei <gastlygem(at)gmail.com> 基于 Barret 的翻译更正而成。转载请注明出处。

版本更新历史
版本 1.43 2011-02-07 esr
2011 年以后 Python 比 Perl 更流行了
版本 1.42 2010-10-22 esr
添加了“历史回顾”
版本 1.40 2008-11-03 esr
链接修正
版本 1.39 2008-08-14 esr
链接修正
版本 1.38 2008-01-08 esr
取消将 Java 推荐为首学语言
版本 1.37 2008-01-08 esr
推荐 Ubuntu 作为新手首选 Unix 发行版

目录

为什么会有这份文档?什么是黑客?黑客精神

  1. 这个世界充满了令人着迷的问题等着我们解决。
  2. 一个问题不应该被解决两次。
  3. 无聊和乏味的工作是罪恶。
  4. 崇尚自由。
  5. 态度不能替代能力。

黑客基本技能

  1. 学习编程。
  2. 学习使用开源 Unix 系统。
  3. 学会使用万维网以及编写 HTML。
  4. 学习英语,如果你的水平不够用的话。

黑客文化中的地位

  1. 撰写开源软件
  2. 帮助测试和调试开源软件
  3. 发布有用的信息
  4. 协助维护基础设施运行
  5. 为黑客文化本身服务

黑客和书呆子(Nerd)的联系向黑客的格调靠拢历史:Hacking、开源。以及自由软件其他资源 FAQ(常见问题解答)

为什么会有这份文档?

作为 Jargon File 的编辑和几份其他类似性质知名文章的作者,我经常收到充满热情的网络新手的电子邮件询问:“我如何才能成为一名出色的黑客?” 早在 1996 年,我注意到网上似乎没有任何的 FAQ 或者 Web 形式的文档提到过这个至关重要的问题,因此我写了这份文档。现在,很多黑客都认为这是一篇权威性文档,那我也姑且这么认为吧。不过,我不认为我是这个话题的绝对权威;如果你不喜欢这篇文档,你也可以自己写一份。

如果你读到的是这份文档的离线拷贝,你可以在 http://catb.org/~esr/faqs/hacker-howto.html 读到最新版本。

注意:文档的结尾有一份 FAQ(常见问题解答) 。如果你想通过邮件询问我关于这份文档的问题,请先读这份 FAQ 看看能否找到答案——一遍不行就读两遍。

目前这份文档有很多翻译版本: 阿拉伯语白俄罗斯语丹麦语荷兰语爱沙尼亚语德语希腊语意大利语希伯来语挪威语葡萄牙语(巴西)罗马尼亚语西班牙语土耳其语瑞典语 。注意由于这份文档时有修正,所以以上翻译版本可能有不同程度的过时。

装饰本文的“五点九宫格”图像被称作的“glider”,在一种被叫做 Life 的数学模型中,这个简单的样本有一些异乎寻常的属性;多年以来,黑客们都为此着迷。我认为这个图像是一个很好的黑客的徽标:它显得抽象而且神秘,而且像是一扇通向一个截然不同的以有其内在逻辑的世界的大门。你可以阅读更多关于 Glider 徽标 的内容。

什么是黑客?

Jargon File 包含了一堆关于“hacker”这个词的定义,大部分是关于“技术高超”、 “热衷解决问题”、以及“超越极限”的内容。但如果你只想知道如何_成为_一名黑客的话,真正重要的只有两条。

这可以追溯到几十年前,那时候第一代分时微型计算机才刚刚诞生, 而 ARPAnet 的实验也才刚展开。那时的编程专家和组网高手建立了一个具有共享性质的文化社群, “hacker” 这个名词就是其中的成员创造的。黑客们建立了互联网,黑客们让 Unix 操作系统演化到现在的模样,黑客们经营着 Usenet,黑客们让万维网运转起来。如果你是这个文化的一部分,如果你对这种文化有所贡献,而且 这个社群的其它成员也认识你并称你为 hacker, 那么你就是一名黑客。

黑客的思维方式并不仅仅局限在软件黑客的文化圈内。也有人用黑客态度对待其它事情,如电子和音乐方面——其实你可以在任何最高级别的科学和艺术活动中发现它。软件黑客对这些领域的践行者尊重有加,并把他们也称作黑客——有人宣称黑客天性是绝对独立于他们工作的特定领域的。但在这份文档中,我们将集中书写在软件黑客的技术和态度,以及发明了“黑客”一词的、以共享为特征的文化传统。

有另外一群人大声嚷嚷着自己是黑客,但他们不是。他们主要由青少年男性构成,是一些蓄意破坏计算机和电话系统的人。真正的黑客把这些人叫做“骇客”(cracker),并不屑与之为伍。黑客们通常认为他们是一群懒散、没有责任心、而且不是很聪明的人。 会通过热接线发动汽车并不意味着你是一个汽车工程师。一样的道理,会破坏安全也不意味着你是一名黑客,不幸的是,很多记者和作家往往错把“骇客” 当成黑客;这种做法一直使真正的黑客感到恼火。

根本的区别是:黑客搞建设,骇客搞破坏。

如果你想成为一名黑客,请接着读下去。如果你想做一个骇客,就去读 alt.2600 新闻组吧,顺便准备好去蹲个五到十年的监狱,而且最终你会意识到你并不像自己想象的那么聪明。

关于骇客,我能说的只有这些。

黑客的态度

黑客们解决问题,建设事物,同时他们信仰自由和无私的双向帮助。要想作为一名黑客被社群认同,你需要体现出自己已经具备了这种态度。而要体现出这种态度,你就得真正相信和赞同这种态度。

但是,如果你认为培养黑客态度只是进入黑客文化圈的敲门砖,那就大错特错了。这种态度将有助于有助于你的学习,并且能为你提供源源不断的动力,所以它对你而言是至关重要的。和所有创造性的艺术一样,成为大师的最有效方法,就是模仿大师的精神——智力上的模仿还不够,还要从感情上进行模仿。

或者正如下面这首现代的禅诗讲的:

修行之道:关注大师的言行,跟随大师的举动,和大师一并修行,领会大师的意境,成为真正的大师。

所以,如果你想成为一名黑客,反复读下面的事情直至你相信它们为止:

  1. 这个世界充满了令人着迷的问题等着我们解决。做一名黑客会有很多乐趣,但是这些乐趣需要付出很多努力才能获得。 这些努力需要动力。成功的运动员在表演和超越自我极限的时候获得身体上的愉悦,并把这种愉悦作为自己的动力。同样,为了成为一名黑客,你要从解决问题、磨练技术,以及锻炼智力中得到基本的快感。如果你不是天性如此,而你又想成为一名黑客,你就要设法成为这样的人。否则你会发现,你的黑客热情会被其他分心的事物吞噬掉——如金钱、性、以及社交圈的认同。(你必须建立对于自己学习能力的信念——就算你掌握的知识不足以解决当前的问题,如果你从问题的一小部分下手并从中学习,你将学到足够的知识用来解决下一部分 ——以此类推,直到整个问题都被你解决为止。)
  2. 一个问题不应该被解决两次。有创新能力的大脑是一种宝贵的有限资源。当世界还充满非常多有待解决的有趣的新问题时,它们不应该被浪费在重新发明轮子的事情上。作为一名黑客,你必须相信其他黑客的思考时间是宝贵的——因此共享信息、解决问题、并发布结果给其他黑客几乎是一种道义,这样其他人就可以去解决新问题,而不用在旧问题上面浪费精力了。(你不必认为你有义务把自己_所有_的作品都免费发布出来,但这样做的黑客能获得大家最大的尊敬。使用黑客技能养家糊口甚至发财致富都没关系,只要你别忘记自己作为一个黑客的责任,不背离黑客群体即可。)
  3. 无聊和乏味的工作是罪恶。黑客(以及所有创造力的人们)应该从来不会被愚蠢的重复性劳动所困扰,因为当这种事情发生时就意味着他们没有在做只有他们才能做的事情—— 解决新问题。这样的浪费伤害每一个人。因此无聊和乏味的工作不仅仅是令人不舒服而已,而且本身就是一种罪恶。作为一个黑客,你必须坚信这点并尽可能多地将乏味的工作自动化,不仅为你自己,也为了其他人(尤其是其他黑客们)。(对此有一个明显的例外。黑客有时也做一些在他人看来是重复性或枯燥的工作以进行“脑力休息”,或是为了获得某种技能,或是获得一些除此以外无法获得的特别经验。但这是自愿的——只要是有思维能力的人,就不应该被迫做无聊的活儿。)
  4. 崇尚自由。黑客们是天生的反权威主义者。任何能向你发号施令的人都可以让你停止解决令你着迷的问题,同时,按照权威主义者的一般思路,他通常会给出一些极端愚昧的理由。因此,不论何处,任何权威主义的作法,只要它影响到了你和其他的黑客,你就要和它斗到底。(这并非向所有权威挑战。儿童需要监护,罪犯要被看管起来。如果服从命令得到某种东西比起用其他方式得到它更节约时间,黑客可以同意接受某种形式的权威。但这是一个有限度的,斟酌过的的交易;那种权威主义者想要的个人服从是不在考虑范围内的。)权威主义者喜欢审查和保密。他们不信任自愿的合作和信息的共享——他们只喜欢由他们控制的所谓“合作”。因此,作为一个黑客,你应该对审查、保密,以及使用武力或欺骗去压迫有行为能力的人们的做法有一种本能的敌意。同时你要有为此信念付出的意愿。
  5. 态度不能替代能力。作为一名黑客,你必须培养起这些态度。但只具备这些态度并不能使你成为一名黑客,也不能使你成为一个运动健将和摇滚明星。成为一名黑客需要智力、实践、奉献精神、以及辛苦的工作。因此,你必须学着忽略态度问题,并尊重各种各样的能力。黑客们不会为那些装模做样的人浪费时间,但他们却非常尊重能力——尤其是从事黑客工作的能力(虽然有能力总归是好事)。如果能具备少有人能掌握的技能就更好了,当然如果你具备一些急需的技能,而这些技能又需要敏锐的思维、高超的技巧、和专注的精神,那就是再好不过了。如果你尊重能力,你就会享受到提高自己能力的乐趣——辛苦的工作和奉献将不会是一件苦差事,而是一种紧张的娱乐,这是成为黑客至关重要重要的一点。

黑客的基本技能

黑客态度重要,但技术更加重要。态度无法替代技术,在你被别的黑客称为黑客之前,你必须掌握一些基本的技术作为你随身携带的工具。

随着新技术的出现和老技术的过时,这个工具包的内容也在不断改变。比如以前机器语言编程也被列在里边,而 HTML 是直到最近才包括进去的。不过现在可以清楚地告诉你包含以下内容:

  1. 学习如何编程。这一条无须多说,当然是最基本的黑客技能。如果你还不会任何编程语言,我建议你从 Python 开始学起。它设计清晰,文档齐全,而且对初学者比较友好。虽然它很适合作为一种入门语言,但它不仅仅只是个玩具;它非常强大、灵活,也适合做大型项目。我在一篇更详细的 Evaluation of Python (译注:Python 试用体验)中有更详细的论述。 Python 网站 有很好的 入门教程 。我曾经推荐过将 Java 作为初学的语言,但 这则批评 改变了我的想法(在里边搜索 “The Pitfalls of Java as a First Programming Language” 就知道我的意思了)。作为一名黑客,你不能像人们挖苦的一样,“像水管工人一样装电脑”,你必须知道各个部件的工作原理。现在我觉得可能还是学过 C 和 Lisp 后再学 Java 比较好。有一个大体的规律,就是如果你过于偏重使用一种语言,这种语言一方面会成为你得心应手的工具,另一方面也会阻碍你的学习。有这个问题的不只是编程语言,类似 RubyOnRails、CakePHP、以及 Django 的 web 应用框架也有这个问题,它们只会让你肤浅地懂得一些东西,当你碰到难以解决的问题或者需要调试时,你就可能不知所措了。如果你想进入正式的编程领域,你将不得不学习 C 语言,它是 Unix 的核心语言。 C++ 与 C 非常其他类似;如果你了解其中一种,学习另一种应该不难。但这两种都不适合编程入门者学习。而且事实上,你越避免用C编程,你的工作效率会越高。C 语言效率极高,而且占用很少的系统资源。不幸的是,C 的高效是通过你手动做很多底层的管理(如内存管理)来达到的。底层代码都很复杂,而且极易出现 bug,你要花很多的时间调试。而现今的计算机速度如此之快,花时间调试程序通常是得不偿失——比较明智的做法是使用一种运行较慢、效率较低,但能大幅节省你的开发时间的语言。因此,还是选择 Python 吧。其他对黑客而言比较重要的语言包括 PerlLISP 。从实用的角度来说, Perl 是值得一学的;它被广泛用于动态网页和系统管理中,因此,即便你从不用 Perl 写程序,至少也应该学会读懂 Perl。许多人使用 Perl 的理由和 我建议你使用 Python 的理由一样,都是为了避免用 C 完成那些不需要 C 高效率的工作。你会需要理解那些工作的代码的。

    LISP 值得学习的理由不同——最终掌握了它时你会得到丰富的启迪和经验。虽然你实际上很少会用到 LISP,但这些经验会使你在以后的日子里成为一个更好的程序员。

    当然,实际上你最好五种都会(Python,Java,C/C++,Perl 和 LISP)。除了是最重要的黑客语言外,它们还代表了截然不同的编程思路和方法,每种都会让你受益非浅。(你可以通过修改 Emacs 编辑器的模式)

    单单学习编程语言并不会让你达到黑客的程度,甚至连程序员的程度都难企及—— 你需要脱离某种编程语言的素服,学习通过编程解决问题的思路。要成为一个真正的黑客,你需要达到几天就能学会一门编程语言的水平,你可以将文档里的信息和你已经掌握的知识结合起来,很快就学会一门编程语言。这意味着你需要先学会机种思路截然不同的语言才行。

    编程是一个复杂的技能,我无法给你完整的指南来教会你如何编程,不过我可以告诉你,书本和课程也无法教会你如何编程——很多黑客,或者也许几乎所有的黑客,都是靠自学的。你从书本上学到语言的特点——只是一些皮毛,但要使书面知识成为自身技能,你只能通过实践和虚心向他人学习。因此你要做的就是 (a) 读代码, (b) 写代码。

    Peter Novig 是 Google 公司的顶尖黑客之一,而且是最受欢迎的 AI 课本的一名作者。他写了一篇好文章名叫 Teach Yourself Programming in Ten Years (译注:十年教会自己编程),其中的“recipe for programming success” (译注:编程的成功之道)尤其值得一读。

    学习编程就象学习自然语言写作一样。最好的做法是读一些大师的名著,试着自己写点东西,再读些,再写点,再读些,再写点……如此往复,直到你的文章具备范文的力量和感觉为止。

    以前要找适合阅读的好代码并不容易,因为几乎没有大型程序的源代码能让新手练手。这种状况已经戏剧性地发生变化;开源软件、编程工具、和操作系统(全都由黑客写成)现在已经随处可见。让我们在下一个话题中继续讨论……

  2. 学习使用开源 Unix 系统。我将假设你已经有一台个人计算机供自己使用了(你可以体会一下这意味着多少东西。早些时候,计算机是如此的昂贵,没有人能买得起。而黑客文化就是在那样的环境下演化来的)。新手们能够朝学习黑客技能迈出的最基本的一步,就是找一版 Linux 或 BSD-Unix,安装在个人电脑上,并且把它跑起来。没错,这世界上除了Unix还有其他操作系统。但它们都是以二进制形式发布的 ——你无法读到它的源代码,也不可能修改它。尝试在运行 DOS 或 Windows 或 MacOS 的机器上学习黑客技术,就象是穿着骑士铠甲学跳舞。除此之外,Unix 还是 Internet 的操作系统。你可以学会上网却不知道 Unix,但你不了解 Unix 就无法成为一名 Internet 黑客。因此,今天的黑客文化在很大程度上是以Unix为核心的。(这点并不总是真的,一些很早的黑客对此一直很不满,但 Unix 和 Internet 之间的联系已是如此之强,就连 Microsoft 这样的“肌肉男”也对此也无可奈何。)所以, 安装一套 Unix 吧——我个人偏爱 Linux,但还有其他种类共你选择(是的,你可以在同一电脑上同时安装 Linux 和 DOS/Windows)。学习它,运行它,鼓捣它。用它上 Internet。阅读它的源代码。修改它的源代码。你会用到很多优秀的编程工具(包括 C,LISP,Python 及 Perl),这些工具在 Windows 下是做梦都没法得到的。你会觉得乐趣无穷。当你有一天成为大师再回顾初学的日子,你会觉得那时学到的东西可真多。如果你想了解更多关于学习 Unix 的信息,读一下 The Loginataka (译注: ESR 的另一著作,可以称为黑客大藏经)吧。也许你还想看看 The Art of Unix Programming (译注:Unix 编程艺术,经典著作)。你可以访问 Linux Online! 网站,这个网站可以帮你起步。你可以从那里下载到 Linux,或者更好的办法是找一个本地的 Linux 用户组,让他们帮你安装 Linux。

    在这份 HOWTO 文档生命的前十年里,关于 Linux 我写的是,从新人的观点来看,所有的Linux 发行版都差不多,但在 2006-2007 之间,我们终于有了一个最佳选择: Ubuntu 。我们可以说各种 Linux 发行版各有千秋,但 Ubuntu 是新人最容易上手的一个发行版。

    你可以在 www.bsd.org 找到 BSD Unix 的求助及其他资源。

    Linux 有一种被称为 Live CD 的发行方式,这种发行版会从 CD 运行起来,而且不会动到你硬盘里的东西,Live CD 是尝试 Linux 的一个不错的方法,速度有些慢,但 CD 本身就慢。慢归慢,Live CD 总归是一个能尝试各种可能性而又不过激的方法。

    我有写一篇关于 Unix 和 Internet 基础 的入门文章。

    对于新手,我以前不鼓励你自己独立安装 Linux 或者 BSD,现在这些系统的安装工具已经足够好了,就算对新手来说,独立安装操作系统也不是不可能的事。无论如何,我还是推荐你联系本地的 Linux 用户组,向他们寻求帮助,这会进程更加顺利。

  3. 学会使用万维网以及编写 HTML黑客文化建造的大多东西都在你看不见的地方发挥着作用。浙西东西可以帮助工厂、办公室、以及大学正常运转起来,但从表面上很难看到它们对非黑客的普通人的生活的影响。而 Web 是一个大大的例外。就连政客也同意,这个庞大耀眼的黑客玩具正在改变整个世界。就算只是因为这个(还有许多其它的原因),Web 也值得你一学。这并不是仅仅意味着如何使用浏览器(谁都会),而是要学会如何写 HTML,也就是 Web 的标记语言。如果你不会编程,写HTML会教你一些有助于学习的思考习惯。因此,先完成一个主页。(网上有很多不错的资源,比如 这个 HTML 入门教程 。)但仅仅拥有一个主页不能使你成为一名黑客。 Web里充满了各种网页。大多数是毫无意义的、毫无信息量的垃圾——界面时髦的垃圾,不过还是垃圾(更多相关信息访问 The HTML Hell Page )。要想有价值,你的网页必须有内容——它必须有趣或对其它黑客有帮助。这是下一个话题所涉及的……
  4. 学习英语,如果你的水平不够用的话。作为一个美国人和一个以英语为母语的人,我以前很不情愿提到这点,免得被当做一种文化上的帝国主义。但相当多以其他语言为母语的人一直劝我指出这一点,那就是:英语是黑客文化和 Internet 的工作语言,只有懂英语,你才能在黑客社区顺利做事。大概1991年的时候,我就了解到许多黑客在技术讨论中使用英语,甚至有时他们来自同一种母语也在用英文讨论。在现阶段,英语有着比其他语言丰富得多的技术词汇,因此是一个对于工作来说相当好的工具。基于类似的原因,英文技术书籍的翻译通常都不怎么令人满意。(如果有翻译的话)。Linus Torvalds 是芬兰人,但他的代码注解是用英语写的(很明显他从没想过其他的可能性)。他流利的英语。是他能够管理全球范围的 Linux 开发人员社区的重要因素。 这是一个值得学习的例子。就算你的母语是英语,这也无法保证你的语言技能足够达到黑客的标准。如果你的写作文字不通、语法混乱、错字连篇,包括我在内的大部分的黑客都会忽略你的存在。虽然写作马虎不一定意味着思考也马虎,但我们发现两者的关联性还是挺强的——马虎的头脑对我们来说毫无价值,如果你写作能力不够,就好好学习写作吧。

黑客文化中的地位

和大部分不涉及金钱的文化一样,黑客王国靠声誉运转。你设法解决有趣的问题,但它们到底多有趣,你的解法有多好,是要由那些和你具有同样技术水平,或比你更厉害的人去评判的。

相应地你需要认识到,当你在玩黑客游戏时,你的分数主要是靠其他黑客对你的技术的评价得到的(这就是为什么只有在其它黑客称你为黑客时,你才算得上是一名黑客)。常人的印象里,黑客是一项独来独往的工作,所以上述评价方式并不为众人所知。另一个黑客文化误区是拒绝承认自我或外部评价是一个人的动力,这种想法在 1990 年代末以后就逐渐衰退了,但现在还有人这么认为。这也是让上述评价方式鲜为人知的原因之一。

明确地讲,黑客行为就是人类学家所称的“奉献文化”。在这里你不是凭借你对别人的统治来建立地位和名望,也不是靠美貌,或拥有其他人想要的东西,而是靠你的贡献。尤其是贡献你的时间、你的创造、以及你的技术成果。

要获得其他黑客的尊敬,你可以从下面五种事情着手:

  1. 撰写开源软件第一个方法(也是最重要,最传统的方法)是写些被其他黑客认为有趣或有用的程序,并把程序源代码提供给整个黑客文化圈使用。(过去我们称之为“free software (自由软件)”, 但这却使很多不知 free 的精确含义的人感到困惑。现在我们很多人,根据搜索引擎网页内容分析,至少有 2:1的比率,使用”open-source software,即“开源软件”这个词)。黑客领域里最受尊敬的偶像,是那些写了大型的、好用的、用途广泛的软件,并把它们发布出来,使得每人都在使用他软件的人。但是从历史方面来讲有一点值得一提。虽然黑客们一直认为开源软件的开发者是真正的黑客,但在 1990 年代中期以前,大部分黑客会把自己的主要时间用来撰写闭源软件,直到我 1996 年开始写这篇 HOWTO 时也是如此。但从 1997 年后开源软件进入了主流,而且改变了这一切。以现在的观点来看,“黑客社群”和“开源开发者”是对这一个社群的两种称呼,但值得记住的是,以前这两者的概念并不完全一样。要了解更多信息,你可以看看 关于黑客、开源、以及自由软件的历史 这一节的内容。
  2. 帮助测试并调试开源软件黑客也尊敬那些使用和测试开源软件的人。这个世界并不完美,我们不可避免地要把大多数的开发时间放在调试阶段。这就是为什么任何有头脑的开源代码的作者都会告诉你好的beta测试员象红宝石一样珍贵。好的测试者知道如何清楚描述出错症状,很好地定位错误,能忍受快速发布中的 bug,并且乐意配合做一些例行的诊断性工作。一个优秀的测试者可以让一场旷日持久辛苦不堪的调试大战变成一场有益身心的小打小闹。如果你是个新手,试着找一个你感兴趣的正在开发中的程序,做一个好的 beta 测试员。你会自然地从帮着测试,进步到帮着抓臭虫,到最后帮着改程序。你会从中学到很多,而且善因种善果,以后别人也会很乐意帮助你。
  3. 公布有用的信息另一件好事是收集整理有用有趣的信息,做成网页或类似 FAQ 的文档,并且让大家都能看到。技术性 FAQ 的维护者会受到和开源代码的作者一样多的尊敬。
  4. 帮助维护基础设施的运转黑客文化(还有互联网工程方面的发展)是靠志愿者推动的。要使Internet能正常工作,就要有大量枯燥的工作不得不去完成——管理邮件列表和新闻组,维护大型软件库,开发 RFC 和其它技术标准等等。做这类事情的人会得到很多尊敬,因为每人都知道这些事情费时颇多,而又不象编程那样有趣。做这些事情需要奉献精神。
  5. 为黑客文化本身服务最后,你可以为这个文化本身做宣传(例如像我这样,写一个“如何成为黑客”的教程 )这并不要求在你已经在这个圈子呆了很久,因以上四点中的某点而出名,有一定声誉后才能去做。黑客文化没有领袖,这点是确认无疑的。但黑客圈里确实有些文化英雄、部落长者、历史学家、以及代言人。如果你在这圈里呆足够长时间,你也许也能成为其中之一。 记住:黑客们不相信他们的部落长者的自夸,因此过分追求这种名誉是危险的。与其奋力追求,不如先摆正自己的位置,等它自己落到你的手中——那时则要做到谦虚和优雅。

黑客和书呆子(Nerd)的联系

和大家普遍认为的相反,并不是只有书呆子才能成为一名黑客。但它确实有帮助,而且许多黑客事实上是书呆子。做一个深居简出的人有助于你集中精力进行十分重要的事情,如思考和编程。

因此,很多黑客都接受了“geek(奇客)”这个标签,并把它作为骄傲的奖章——这是宣布他们独立于主流社会期望的一种方式(这个标签也是他们喜欢科幻小说和策略型游戏的标记,而这些也是很多黑客喜欢的东西)。1990 年代更多用的称呼是“nerd(书呆子)”,那时“nerd”只带点轻微的贬义,而“geek”则是地地道道的蔑称,而在 2000 年以后,这两者逐渐调转过来了,至少再美国的大众文化中是这样。而到了现在,甚至在非技术人群里,也有不少以奇客精神为傲的文化团体。

如果你能集中足够的精力做好黑客工作同时还能有正常的生活,这是件好事。现在要做到这一点比我在 1970 年代还是新手的时候要容易的多;如今主流文化对技术怪人要友善得多。甚至有越来越多的人意识到黑客通常是很好的恋人和配偶的材料。

如果你因为生活上不如意而迷上做黑客,那也没什么——至少你不会分神了。也许你以后还能找到自己的生活。

向黑客的格调靠拢

重申一下,要做一名黑客,你必须深入体验黑客精神。计算你不在计算机边上,你仍然有很多对黑客工作有帮助的事情可做。它们并不能替代真正的编程(没有什么能替代编程),但很多黑客都那么做,并感到它们与黑客的本质存在某些基本的连系。

  • 学会用母语流畅地写作。尽管很多人认为程序员写不出好文章,但是有相当数量的黑客(包括所有我知道的最棒的)都是很有能力的写手。
  • 阅读科幻小说。参加科幻小说讨论会。(这是一个认识黑客和准黑客的好方法)
  • 学习一种武术。武术中需要的精神自律能力和黑客在这方面的需求非常相似。黑中最受欢迎的武术是来自亚洲的空手格斗类武术,例如跆拳道、空手道、武术、合气道、柔术等。西式击剑和亚洲剑术也有不少的跟随者。1990 年后期以来,在可以合法使用枪支的地方,射击受欢迎的程度也越来越高了。大部分黑客喜欢的武术类型都是那些强调精神的自律,放松的意识,以及意念的控制,而不仅仅是单纯的力量、运动精神、以及身体的强健。
  • 实实在在学习一种冥想修炼。多年以来黑客中最受欢迎的形式是参禅。(很重要的一点是,参禅和宗教可以说是独立的,你不需要接受一种新宗教,或者放弃现有的宗教信仰,就能做参禅的修炼。其他的形式也许也管用,但注意一定要挑那些靠谱的,不需要你相信不着边际的事物的冥想方式来演练。
  • 提高自己对双关语和文字游戏的鉴赏能力。

如果这些事情有很多你已经在做了,那你可能是天生做黑客的材料。至于为什么偏偏是这些事情,原因并不完全清楚,但它们都涉及用到左-右脑能力的综合,这似乎是关键所在(黑客们既需要清晰的逻辑思维,有时又需要偏离逻辑跳出问题的表象)。

最后,还有一些不要去做的事情。

  • 不要使用愚蠢的,哗众取宠的ID或昵称。
  • 不要卷入 Usenet(或任何其他地方)的骂战。
  • 不要自称为“cyberpunk(网络朋克)”,也不要浪费时间和那些人打交道。
  • 不要让你的 email 或者帖子中充满错误的拼写和语法。

以上的事情只会为你招来嘲笑。黑客们个个记忆超群——你将需要数年的时间让他们忘记你犯下的错误。

网名的问题值得深思。将身份隐藏在虚假的名字后是骇客、软件破解者、及其他低等生物幼稚愚蠢的行为。黑客不会做这些事;他们对他们所作的感到骄傲,而且乐于人们将作品与他们的真名相联系。因此, 如果你现在还在使用假名,那就放弃它吧。在黑客文化里假名是失败者的标记。

关于黑客、开源、以及自由软件的历史

1996 年我开始写这篇 HOWTO,那时候的大环境和现在很不一样。这里会给你简单介绍一下相关的历史变迁,这样大致可以澄清一下开源软件、自由软件、以及 Linux 和黑客圈的关系。如果你对这些不感兴趣,你可以直接跳过这一节,继续读下面的 FAQ。

我在这里所描述黑客精神和社会远远早于1990 Linux 出现的时候,我第一次涉足黑客圈是 1976 年,而究其根源则可追溯到20世纪60年代初。但在 Linux 出现之前,大多数黑客使用的操作系统要么是私有的商业版本,要么是自己开发的未得到广泛使用的系统(例如麻省理工学院的 ITS 系统)。虽然那时也有人想要改变这种状况,但他们的努力影响范围相当有限,充其量仅在某个黑客社区有少数忠实用户而已。

现在所谓“开源”历史和黑客社区的历史几乎一样长,但直到 1985 年前,它只是一种没有固定称谓的习惯做法,而不是一套有理论做后盾,有宣言做前锋的自觉运动。这种状态在 1985年结束了,长老级黑客Richard Stallman(“RMS”)将其命名为“自由软件 (Free Software)”。这种命名也是一种宣言的方式,不过大多数黑客社区都不接收这种包含明显思想烙印的标签。因此而大多数现有的黑客社区从来没有接受。结果,“自由软件”这一标签被黑客社群中声音较大的少数派(尤其是 BSD Unix 的相关人士)拒绝掉了,而剩下的大部分人(包括我)虽然也有保留意见,可也还是沿用了这一称谓。

尽管很多人存在保留意见,RMS 的“自由软件”的大旗也一直举到了 1990 年代中期。直到 Liunx 崛起的时候,它才受到了重大挑战。Linux 给了的开源开发者一个新的自然归宿,很多项目都已我们现称的开源的方式由 Unix 移植到了 Linux 系统中。Linux 的社区也得到了爆炸性增长,成为了一个比以前黑客文化更为庞大,并且异质化的新的群体。RMS 曾今尝试将这一社群也归并到他的“自由软件运动”大旗下,但终究没有成功,原因可以归于 Linux 社区的样性,以及 Linus Torvalds 本人的质疑。Torvalds 公开拒绝了 RMS 的自由软件思想,但还是沿用了“自由软件”这一术语,这也引来了很多年轻黑客的效仿。

1996年,当我第一次发表这篇 HOWTO 的时候,黑客社团正在围绕着 Linux 和其它几个开源操作系统(尤其是 BSD Unix 的衍生系统)进行着快速的重组。几十年来围绕着闭源系统进行闭源开发的方式还没有开始淡出集体记忆,但在大家看来,这似乎已经是死去的历史了。越来越多的黑客都已经开始注重自己在开源项目(例如 Linux、Apache 等)上的贡献,并将这些贡献当做自己的成就。

然而在那个时候“开源”这一名词还没有出现。这个名词是 1998 年初才开始出现的,而在出现的半年内,大部分的黑客社区就接受了这一名词,只有少数不接受这一概念的人还在坚持使用“自由软件”这一名词。1998 年以后,或者更准确地说是 2003 年以后,所谓的 “hacking” 和 “开源(自由)软件开发”的含义已经非常接近了。从今天的眼光来看,这种区分已经没有意义了,看趋势,这个现状将来也不大可能改变了。

话虽如此,这段变更的历史还是值得记住的。

其它资源

Paul Graham 写了一篇 Great Hackers ,还有 Undergraduation 一篇,里边有充满智慧的言论。

还有一篇叫 How To Be A Programmer 的文章,是这篇文章很好的补充。里边的建议不但包括如何提高编程和其它技术,还包含团队合作的窍门。

我还写过一篇 A Brief History Of Hackerdom (译注:黑客文化简史)。

我写了一本 The Cathedral and the Bazaar (译注:大教堂与市集),对于 Linux 及开放源代码文化现象有详细的解释。这种现象在我的另一篇 Homesteading the Noosphere (译注:开拓智域)中还有更直接的阐述。

Rick Moen 写了一份很好的关于 how to run a Linux user group (译注:如何运营 Linux 用户组)的文档。

我和Rick Moen合作完成了另一份关于 How To Ask Smart Questions (译注:提问的智慧)的文章,可以让在寻求帮助时得到事半功倍的效果。

如果你想知道 PC、UNIX 及 Internet 基本概念和工作原理,参考 The Unix and Internet Fundamentals HOWTO

当你发布软件或者补丁的时候,请遵照 Software Release Practice HOWTO 去做。

如果你对禅诗感兴趣,也许你还喜欢看这篇 Rootless Root: The Unix Koans of Master Foo

FAQ(常见问题解答)

问:怎样才能知道自己已经是一名够格的黑客?问:你能教我做黑客吗?问:那么我要如何开始?问:我得什么时候开始学?现在会不会太迟了?问:要学多久才能学会黑客道?问:Visual Basic 是好的入门语言吗?问:你能帮我“黑”掉一个站点吗?或者教我怎么黑它?问:我怎么样才能得到别人帐号的密码?问:我如何入侵/查看/监视别人的Email?问:我如何才能在IRC聊天室里偷到频道op的特权?问:我被黑了。你能帮我避免以后再被攻击吗?问:我的Windows软件出现问题了。你能帮我吗?问:我在哪里能找到可以与之交流的真正的黑客?问:你能推荐一些有关黑客的好书吗?问:成为一名黑客我需要擅长数学吗?问:我该从那种语言学起?问:我需要什么样的机器配置?问:我想贡献社区。你可以帮我选一个问题让我下手吗?问:我得因此憎恨和反对Microsoft吗?问:但开放源代码软件不会使程序员丢饭碗吗?问:我要如何开始?哪里有免费的 Unix?

问:怎样才能知道自己已经是一名够格的黑客?

答:问自己下面三个问题:

  • 你能流利地读写代码吗?
  • 你认同黑客社群的目的和价值吗?
  • 黑客社群里有没有资深成员称呼你为黑客呢?

如果你对这三个问题的答案都是“是”的话,你已经是一名黑客了。如果你只满足其中两项,那就说明你还不够格。

第一个问题是关于技能的。如果你已经符合本文前面提到的最低需求的话,你也算过关,不过如果你发布过为数不少的开源代码并被社群接受,那你就算满分过关了。

第二个问题是关于态度的。如果 黑客精神的五项基本原则 对你来说能有共鸣,而且已经是你处事的方式,你就算过关一半了。这算靠里的一半,靠外的一半和你在黑客社区长期项目上的投入和关联程度有关。

这里列出了一些项目的不完全列表供你参考:Linux 的改进和用户群扩大对你来说是否重要?你对于自由软件精神是否充满激情?你对于垄断是否有敌意?你是否相信计算机这种工具会让增加世界财富,让这个世界更富有人道主义?

不过值得注意的一点是,黑客社群有一些特有的政治倾向,其中两条,一条是保卫言论自由权,一种是抵御所谓“知识产权”对于开源社区的侵害。实践这两条的是一些民间组织,例如电子前沿基金会 (Electronic Frontier Foundation) 就是其中之一。不过虽然如此,黑客们对于有任何明确政治目的的团体都是心怀戒备的,因为我们已经从各种经验教训中学到一点:这些活动只会分裂黑客社团,并让黑客们分心。如果有人以黑客精神为名组织一场首都大游行,那他就完全没有弄明白这点。真正的应对方式也许应该是“闭上嘴巴,给他们看代码”。

第三个问题有点循环递归的味道。在“什么是黑客”一节我已经讲过,作为一名黑客的意义在于参与某个黑客社群,也就是社交网络的一个亚文化团体,作为内部的贡献成员以及外部的宣传者积极活动。和很久以前相比,黑客群体现在的团结意识和自我意识已经增强了很多。过去三十年来,随着互联网的发展,社交网络逐渐开始发挥举足轻重的作用,而黑客的亚文化团体也更加容易发展和维护了。这种变革的明显一个有代表性的现象是:黑客群体现在都有自己的T恤了。

研究社交网络的社会学家把黑客文化归为“看不见的大学”,而且注意到这些网络社交圈还有所谓的“看门人”——其中的一些核心成员,他们有一定的权威,可以准新成员的进入。所谓的“看不见的大学”本来就是一个松散的非正式组织,所以这些“看门人”也只是这门称呼而已。但不是每个黑客都是“看门人”,这是每个黑客都深刻明白的一点。“看门人”需要有一定的资历和成就,究竟要到什么程度很难讲,但一旦有这样的人出现,每一个黑客都能辨识出来。

问:你能教我做黑客吗?

答:自从第一次发布这份文档,我每周都会收到一些请求,(频繁的话一天几封)要我“教会他们做黑客”。遗憾的是,我 没有时间和精力来做这个;我自己的黑客项目,及我作为一个开放源代码倡导者 的四处奔波已经占用了我110%的时间。即便我想教你,黑客也依然基本上是一项自行修炼的的态度和技术。 当真正的黑客想帮助你的时候,如果你乞求他们一汤匙一汤匙“喂”你的话,你会发现他们不会尊重你。先去学一些东西。显示你在尝试,你能靠自己去学习。然后再去向你遇到的黑客请教特殊的问题。如果你发E-mail给一位黑客寻求他的帮助,这是两件首要记住的事情。 第一,写出来的文字显得懒且粗心的人通常非常懒于思考且非常马大哈,不能成为好黑客 ——因此注意拼写正确,使用正确的语法及发音,否则你可能会无人理睬。 第二,不要试图要求回复到一个ISP帐号,而那个帐号与你 的发信地址不同。这样做的人一般是使用盗用帐号,我们对于回报或者帮助窃贼不感兴趣。

问:那么,我要如何开始?

答:对你而言最佳的入门方式也许是去参加 LUG(Linux用户组)的聚会。 你可以找到在 LDP 的综合 Linux 信息页面上找到类似的组织;也许有一个在你家附近的,而且非常有可能与一所大学或学校挂钩。如果你提出要求,LUG 成员兴许会给你一套 Linux,当然此后会帮你安装并带你入门。

问:我得什么时候开始学?现在会不会太迟了?

答:你有动力学习的时候就是好时候。大多数人看来都是在15-20岁之间开始感兴趣的,但据我所知,在此年龄段之外的例外也是有的。

问:要学多久才能学会黑客道?

答:这取决于你的聪明程度和努力程度。大多数人只要他们专注, 就能在 18 个月到2 年之间学会一套令人尊敬的技能。但是,不要以为就此结束了; 如果你是一个真正的黑客,你要用你的余生来学习和完善你的技术。

问:Visual Basic 是好的入门语言吗?

答:既然你问了这个问题,那你肯定是想在 Microsoft Windows 操作系统下学习黑客技能。这本身就不是一个好主意。我前面讲过在 Windows 下 hack 就跟穿着骑士铠甲跳舞一样,我不是在开玩笑。别试图做这个,Windows 是一个很低劣的 hack 环境,而且一直如此。Visual Basic 有一个特征性问题,就是它不可以被移植到其他平台。虽然也有些 Visual Basic 开源实现的雏形,但实现的只是 ECMA 标准的一个很小的子集。在 Windows 下大部分类库的知识产权都是 Microsoft 独家所有,如果你不是及其小心的话,你的代码将只能在 Microsoft 支持的平台上使用。如果你不打算从 Unix 起步,那你也有更好的语言可选,而且类库质量还更高,例如 Python 就是其中之一和其他的 Basic 类语言一样,Visual Basic 这门编程语言的设计也很糟糕,它会教你一些坏的变成习惯。你就别问我细节了,这可是罄竹难书。还是去学一门设计优良的语言吧。其中一个坏习惯是让你依赖于单一厂商的函数库、控件及开发工具。一般而言,任何不能够支持至少 Linux 或者某一种 BSD,或其不能支持至少三种以上操作系统的语言,都是一种不适合应付黑客工作的语言。

问:你能帮我“黑”掉一个站点吗?或者教我怎么黑它?

答:No。任何读完这份 FAQ 后还问这个问题的人,都是无可救药的蠢材,即使有时间指教我也不会理睬。任何发给我的此类电子邮件都会被忽略或被痛骂一顿。

问:我怎么样才能得到别人帐号的密码?

答:这是骇客行为。滚得远远的,白痴。

问:我如何入侵/查看/监视别人的Email?

答:这是骇客行为。在我面前消失,智障。

问:我如何才能在IRC聊天室里偷到频道 op 的特权?

答:这是骇客行为。滚蛋吧,笨蛋。

问:我被黑了。你能帮我避免以后再被攻击吗?

答:不行。目前为止,每次问我这个问题的,都是一些运行 Microsoft Windows 的菜鸟。不可能有效的保护Windows系统免受骇客攻击;太多缺陷的代码和架构使保护 Windows 的努力有如隔靴搔痒。唯一可靠的预防来自转移到Linux或其他设计得至少足够安全的系统。

问:我的 Windows 软件出现问题了。你能帮我吗?

答:当然。打开 DOS 命令行输入“format c:”。你遇到的任何问题将会在几分钟之内消失。

问:我在哪里能找到可以与之交流的真正的黑客?

答:最佳办法是在你附近找一个Unix或Linux的用户组,参加他们的聚会。(你可以在ibiblio 的 LDP 站点 找到一些用户组的链接。)(我过去曾说过不能在IRC上找到真正的黑客,但我发觉现在情况有所改变。显然一些真正的黑客的社区像 GIMP 及 Perl,也有IRC频道了。)

问:你能推荐一些有关黑客的好书吗?

答:我维护着一份 Linux Reading List HOWTO ,也许你会觉得有用。The Loginataka 也大致值得一读。关于Python的介绍,请访问在Python站点上的 入门教程

问:成为一名黑客我需要擅长数学吗?

答:不用。黑客道很少使用常规的数学或算术,不过你绝对需要能逻辑性地思考和进行精密的推理。尤其是你不会用到微积分或电路分析(我们把这些留给电子工程师们 :-) )。有限数学中的一些可提(包括布尔代数,集合论,组合数学,图论)的背景知识会对你有所帮助。更重要的一点:你要有逻辑思维能力,能够以数学家的方式追溯因果。虽然大部分的数学知识对你可能没什么用处,但数学思维的能力对你来说是极其重要的。如果你缺乏这方面的智慧,要做一名黑客恐怕是无望了。如果你缺乏这方面的训练,还是尽早开始吧。

问:我该从那种语言学起?

答:如果你还没学过XHTML(HTML最新的表现形式)的话,就从它开始吧。市面上有一大堆的封面精美,宣传得天花乱坠的 HTML 书籍,不幸的是质量优秀的几近于无。我最喜欢的是 HTML: The Definitive Guide 。但 HTML 不是一种完整的编程语言。当你准备开始编程时,我推荐从 Python 起步。 你会听到一大群人推荐 Perl,但是 Perl 要难学得多,而且(以我之见)设计得不是很好。C 确实重要,但它也比 Python 或 Perl 难多了。不要尝试先学 C。Windows用户注意:不要满足于 Visual Basic。它会教给你坏习惯,而且它不可以跨平台移植,只能在Windows下运行。因此还是敬而远之为好。

问:我需要什么样的机器配置?

答:过去个人电脑能力相当不足并且内存很小,这给黑客的学习过程设置了人为的障碍。不过 1990 中期以后就不是这样了;任何一台 Intel 486DX50 以上配置的机器都有足够的能力进行开发工作、运行 X 系统、以及进行 Internet 通讯。而且你买到的市面上最小的硬盘都大得足够你使用了。选择用来学习的机器时重要的一点是注意配件是否是Linux兼容的(或BSD兼容,如果你选择 BSD 的话)。和刚才提到的一样,大多数现在的机器都是符合的;唯一值得注意的区域在于 modem 和打印机;有些具备为Windows设计的配件的机器不会在Linux下工作。你可以查看这份 Linux Hardware Compatibility FAQ

问:我想贡献社区。你可以帮我选一个问题让我下手吗?

答:不行,因为我不知道你的兴趣和擅长领域在哪里。如果你没有内在动力,你就很难坚持下去,所以说,别人只给你的路是行不通的。试试这么做吧。在 Freshmeat 网站观察几天,看看里边的项目更新,如果你看到一个看上去很酷而且你也很感兴趣的项目,就加入吧。

问:我得因此憎恨和反对Microsoft吗?

答:不,你不必如此。不是因为Microsoft不令人讨厌,而是因为黑客文化早在Microsoft 出现之前就存在了,且将在 Microsoft 成为历史后依然存在。 你耗费在憎恨 Microsoft 的任何力气不如花在爱你的技术上。写好的代码——那会相当有效地打击 Microsoft 又不会让你得到恶报应。

问:但开放源代码软件不会使程序员丢饭碗吗?

答:目前看起来不太可能,开放源代码软件产业似乎创造了更多的就业机会而不是减少就业机会。如果写一个程序比起不写来是纯经济收益的话,那么在写完后,程序员应该得到报酬不管程序是否是开放源代码。并且,无论写出多么“免费自由”的软件,都存在更多对新的,定制的软件的需求。我有这方面更多的论述,放在放源代码网站资料中。

问:我要如何开始?哪里有免费的Unix?

答:在本份文档的某个地方我已经提到过何处可以得到最常用的免费 Unix。要做一名黑客,你需要自立自强,以及自学能力。现在开始吧……

原文地址:http://www.biaodianfu.com/hacker-howto.html

原文地址:http://www.biaodianfu.com/yaml.html
YAML,是一个可读性高,用来表达资料序列的编程语言。YAML参考了其他多种语言,包括:XML、C语言、Python、Perl以及电子邮件格式。目YAML是”YAML Ain’t a Markup Language”(YAML不是一种置标语言)的递归缩写。在开发的这种语言时,YAML 的意思其实是:”Yet Another Markup Language”(仍是一种置标语言),但为了强调这种语言以数据做为中心,而不是以置标语言为重点,而用返璞词重新命名。

YAML的功能

YAML的语法和其他高阶语言类似,并且可以简单表达清单、杂凑表,标量等资料形态。它使用空白符号缩排和大量依赖外观的特色,特别适合用来表达或编辑数据结构、各种设定档、倾印除错内容、文件大纲(例如:许多电子邮件标题格式和YAML非常接近)。尽管它比较适合用来表达阶层式(hierarchical model)的数据结构,不过也有精致的语法可以表示关联性(relational model)的资料。由于YAML使用空白字符和分行来分隔资料,使的他特别适合用grep/Python/Perl/Ruby操作。其让人最容易上手的特色是巧妙避开各种封闭符号,如:引号、各种括号等,这些符号在巢状结构时会变得复杂而难以辨认。

为什么不使用XML?

YAML的可读性好。
YAML和脚本语言的交互性好。
YAML使用实现语言的数据类型。
YAML有一个一致的信息模型。
YAML易于实现。
上面5条也就是XML不足的地方。同时,YAML也有XML的下列优点:

YAML可以基于流来处理;
YAML表达能力强,扩展性好。
总之,YAML试图用一种比XML更敏捷的方式,来完成XML所完成的任务。

为什么不使用JSON ?

JSON的语法是YAML1.2版的子集,,同时非常接近YAML1.0与1.1版的子集,因此大部分的JSON文件都可以被YAML的剖析器剖析。这是因为JSON的语法结构和YAML的内置格式相同。虽然大范围的分层也可以使用类似JSON的内置格式,不过这并YAML标准并不建议这样使用,除非这样编写能让文件可读性增加。YAML的许多扩展在JSON是找不到的,如:进阶资料形态、关系锚点、字串不需要双引号、映射资料形态会储存键值的顺序。

YAML的语法要求

在yaml.org(英文)可以找到轻巧而好用的小抄(亦是用YAML表示)及格式说明。下面的内容,是关于基本元件的摘要。

YAML使用可打印的Unicode字符,可使用UTF-8或UTF-16。
使用空白字符为文件缩排来表示结构;不过不能使用跳格字符(TAB)。
注解由井字号( # )开始,可以出现在一行中的任何位置,而且范围只有一行(也就是一般所谓的单行注解)
每个清单成员以单行表示,并用短杠+空白( – )起始。或使用方括号( [ ] ),并用逗号+空白( , )分开成员。
每个杂凑表的成员用冒号+空白( : )分开键值和内容。或使用大括号( { } ),并用逗号+空白( , )分开。
杂凑表的键值可以用问号 ( ? )起始,用来明确的表示多个词汇组成的键值。
字串平常并不使用引号,但必要的时候可以用双引号 ( “ )或单引号 ( ‘ )框住。
使用双引号表示字串时,可用倒斜线( \ )开始的跳脱字符(这跟C语言类似)表示特殊字符。
区块的字串用缩排和修饰词(非必要)来和其他资料分隔,有新行保留(preserve)(使用符号 | )或新行折叠(flod)(使用符号 > )两种方式。
在单一档案中,可用连续三个连字号(——)区分多个档案。
另外,还有选择性的连续三个点号( … )用来表示档案结尾。
重复的内容可使从参考标记星号 ( * )复制到锚点标记( & )。
指定格式可以使用两个惊叹号 ( !! ),后面接上名称。
档案中的单一文件可以使用指导指令,使用方法是百分比符号( % )。有两个指导指令在YAML1.1版中被定义:
%YAML 指导指令,用来识别文件的YAML版本。
%TAG 指导指令,被用在URI的字首标记。这个方法在标记节点的型态时相当有用。
YAML再使用逗号及冒号时,后面都必须接一个空白字符,所以可以再字串或数值中自由加入分隔符号(例如:5,280或http://www.wikipedia.org)而不需要使用引号。

另外还有两个特殊符号在YAML中被保留,有可能在未来的版本被使用–( @ )和( ` )。

YAML的适用范围

由于实现简单,解析成本很低,YAML特别适合在脚本语言中使用。列一下现有的语言实现:Ruby,Java,Perl,Python,PHP,OCaml,JavaScript。除了Java,其他都是脚本语言.

YAML比较适合做序列化。因为它是宿主语言数据类型直转的。

YAML做配置文件也不错。比如Ruby on Rails的配置就选用的YAML。对ROR而言,这很自然,也很省事.

由于兼容性问题,不同语言间的数据流转建议现在不要用YAML.

YAML存在的意义

无论多么完美的事物,都需要有对立面,有说“NO”的声音。XML也不例外。当然,站在主流的对立面,需要勇气和智慧。

YAML和XML不同,没有自己的数据类型的定义,而是使用实现语言的数据类型。这一点,有可能是出奇制胜的地方,也可能是一个败笔。如果兼容性保证的不好的话,YAML数据在不同语言间流转会有问题。如果兼容性好的话,YAML就会成为不同语言间数据流通的桥梁。建议yaml.org设立兼容认证机制,每个语言的实现必须通过认证。

假如兼容性没问题的话,YAML就太完美了。轻巧,敏捷,高效,简便,通用。这才是理想中的数据模型。当然就现在而言,这还只是个理想。

常用YAML函式库

PHP
Spyc 纯PHP的实现。
PHP-Syck(与SYCK函式库绑定)
sfYaml 为symfony项目重写的Spyc, 可独立使用, 可以产生和剖析YAML文件。
Python
PyYaml 纯Python,或可选用LibYAML的函式库。
PySyck 与SYCK绑定。
参考链接:http://zh.wikipedia.org/wiki/YAML

原文地址:http://www.biaodianfu.com/yaml.html

原文地址:http://blogread.cn/it/article/6649

PHP的性能一直在提高。然而,若是用的不恰当,或是一个不留神,还是可能会踩到PHP内部实现方面的坑的。我在前几天的一个性能问题上就碰到了。

事情是这样子的,一位同事反馈我们的一个接口每次返回需要5秒之久,我们一起review了代码,“惊喜”的发现居然在循环(大约900次)中调用了一个读缓存的操作,而这个缓存的key并没有改变,因此我们把这段代码移到了循环外面,再测,接口返回时间降到了2秒,呜呼!虽然提升了1倍,但明显不是我们能接受的结果!

出现性能问题的代码量并不大,我们排除了IO问题以后,写了一段测试代码,果然问题很快重现。

<?php
$y="1800";
$x = array();
for($j=0;$j<2000;$j++){
        $x[]= "{$j}";
}

for($i=0;$i<3000;$i++){
        if(in_array($y,$x)){
                continue;
        }
}
?>
shell$ time /usr/local/php/bin/php test.php
real0m1.132s
user0m1.118s
sys0m0.015s

对的,我们用的就是字符串型的数字,从缓存拿出来就是这样子的啦!所以这里是特意转成字符串的(如果直接是数字,并不会出现这个问题 ,各位可以自行验证)。可以看出时间耗掉了1秒,才3000次循环,后面的sys用时也注定我们用strace不会拿到什么有效信息。

shell$ strace -ttt -o xxx /usr/local/php/bin/php test.php
shell$ less xxx

1

我们只看到这两次系统调用之间的延时非常大,却并不知道干了什么?一筹莫展了,幸好,Linux下的调试利器除了strace还有ltrace(当然还有dtrace,ptrace,不在本文讨论范围了,略去)。

引用:strace用来 跟踪一个进程的系统调用或信号产生的情况,而 ltrace用来 跟踪进程调用库函数的情况(via IBM developerworks)。

为了排除干扰因素,我们将$x直接赋值为array(“0″,”1″,”2″,……)的形式,避免过多的malloc调用影响结果。执行

shell$ ltrace -c /usr/local/php/bin/php  test.php

如图2

2

我们看到库函数__strtol_internal的调用非常之频繁,达到了94%,太夸张了,然后我又查了一下这个库函数__strtol_internal是干嘛的,原来是strtol的别名,简单的说就是把字符串转换成长整形,可以猜测PHP引擎已经检测到这是一个字符串型的数字,所以期望将他们转换成长整型来比较,这个转换过程中消耗了太多时间,我们再次执行:

shell$ ltrace -e "__strtol_internal" /usr/local/php/bin/php test.php

可以轻松抓到大量下图这样的调用,到此,问题找到了,in_array这种松比较,会将两个字符型数字串先转换为长整型再进行比较,却不知性能就耗在这上面了。

3

知道了症结所在,我们解决的办法就很多了,最简单的就是为in_array加第三个参数为true,即变为严格比较,同时还要比较类型,这样避免了PHP自作聪明的转换类型,跑起来果然快多了,代码如下:

<?php
$y="1800";
$x = array();
for($j=0;$j<2000;$j++){
        $x[]= "{$j}";
}

for($i=0;$i<3000;$i++){
        if(in_array($y,$x,true)){
                continue;
        }
}
?>
shell$ time /usr/local/php/bin/php test.php
real0m0.267s
user0m0.247s
sys0m0.020s

快了好多倍啊!!!可以看到sys耗时几乎没有太大变化。我们再次ltrace一把,还是要把$x直接赋值,排除malloc调用的干扰,因为我们实际应用中是从缓存里一次拉出来的,所以也不存在示例代码中这样的循环来申请内存的情况。
再次执行

shell$ ltrace -c /usr/local/php/bin/php  test.php

如下图:

4

__ctype_tolower_loc占用了最多的时间!查了一下库函数__ctype_tolower_loc是干嘛的:简单的理解是将字符串转换成小写,那么这说明in_array比较字符串不区分大小写吗?其实这个函数调用已经和我们这个in_array感觉联系不大了,关于in_array的实现,还是去看看PHP的源码,大概理解的更为透彻了,好了,没法往下说了,欢迎与我交流,写的不对的地方请多多斧正。

原文地址:http://blogread.cn/it/article/6649

原文地址:http://blogread.cn/it/article/3605?f=wb

 昨天,一位老上级邀请我一起吃午餐。当坐在哪里等待上菜时,我们缅怀起早期这个公司的往事。他有一句话让我心里一虚:

    啊,你这个判官…我记得当你看到Dan(公司的第一位程序员)写的代码时的样子。你说:“这代码写的真烂,需要重写!”

    我恐怕是没有足够的勇气告诉他,我这“代码需要重写”的主张是错误的。不错,我认为这代码写的很乱。但是,据过去历次的经验,我感觉大部分的程序员看着别人写的程序时都会想:这代码写的真烂。事实上,当一个程序员数年后再看自己写过的程序时也会想:这代码写的真烂。也许他们想的是对的;这代码确实很烂。

    但是,如果你认为代码需要重写,你将犯下一个低级错误。

    公司里有一些想当然的看法会让你可能现在不能认识到这点。大量的不成文的想当然的观点可能会让你无法解释清楚。

    我喜欢Joel Spolsky说的关于这种事情的话,有些事情你永远不要去做

    我们是程序员。程序员,在他们自己的心里,是建筑师,当他们来到一个地点,第一件想要做的事情就是:把这地方推平,盖上辉煌的建筑。他们对慢慢的修缮没有兴趣:小修小补,改善,培植花草。

    有一种不可捉摸的原因让程序员们总是希望丢掉这些代码、重新再写。原因是他们认为老的代码是混乱的。可是,你会观察到一种非常有趣的现象:他们的判断通常是错的。他们之所以会认为老的代码很烂的原因来自于一个重要的、基本的编程定律:

    读代码比写代码要难。

    这就是为什么代码很难重用的原因。这就是为什么每个团队喜欢用自己不同的函数来做把字符串拆分成数组操作的原因。他们要写自己的方法,这更容易,更有趣,不需要弄清楚老的函数的工作原理。

    根据这种定律必然得出这样的一个结论,你现在可以问一问任何一个程序员,问他们对正在写的程序感觉如何。“乱的不能再乱了,”他们会这样告诉你。“我宁愿把它们都删了重新再写。”

    当你招募来了一个程序员,如果他想重写看来工作的不错的程序,你要抵制。他也许会说Java过时了,太慢,Ruby on Rails如何的酷。也许他会向你抛了一大堆专业名称术语。不管他如何做,你要三思而行。

    你觉得呢?

原文地址:http://blogread.cn/it/article/3605?f=wb