??xml version="1.0" encoding="utf-8" standalone="yes"?>少妇高潮惨叫久久久久久,免费精品久久天干天干,久久精品国产99国产精品亚洲http://www.shnenglu.com/hex108/懂历?==> 知未? zh-cnWed, 07 May 2025 05:43:06 GMTWed, 07 May 2025 05:43:06 GMT60[扑ַ作]法结http://www.shnenglu.com/hex108/archive/2011/08/24/154248.htmlhex108hex108Wed, 24 Aug 2011 13:39:00 GMThttp://www.shnenglu.com/hex108/archive/2011/08/24/154248.htmlhttp://www.shnenglu.com/hex108/comments/154248.htmlhttp://www.shnenglu.com/hex108/archive/2011/08/24/154248.html#Feedback0http://www.shnenglu.com/hex108/comments/commentRss/154248.htmlhttp://www.shnenglu.com/hex108/services/trackbacks/154248.htmlZ个问题寻扄法的q程Q有点像一个穷举过E:(x)搜烦已有知识Qƈq行重组的过E。所以把常用的算法记住,然后一个一个试用,看是否可行,不失Z个好Ҏ(gu)?div>
如果q个Ҏ(gu)不行呢?不妨写出最直观的解{(即用“蛮力?#8221;Q,然后从中看出可以优化的地方在哪里Q进而进行优化?/div>


如何定该问题可以用哪类Ҏ(gu)来解{呢Q首先,需要对q些常用的算法的基本思想非常熟?zhn)?br />常用的算法可以分Z下几c:(x)
1. Divide & conquer
   分治法Q将问题分ؓ(f)两个1Q?规模大小的子问题Q然后解冟뀂如merge sort

2. Decrease & conquer
   减治?: 问题规模从 n 变ؓ(f) n - 1Q然后在规模n-1的基上解x问题?如insertion sort  
   q不是递归么?

3. Transform & conquer
   变治?Q变换结构。如heap sort   

4. Brute force
   蛮力法Q可以说是必杀技吧,大部分问题都可以用此Ҏ(gu)解决?如selection sort
   使用蛮力法的优点是简单不Ҏ(gu)出错Q缺Ҏ(gu)复杂度有时很高,所以我们可以在ID法的基础上进行改q,q样能达C丑֏得的效果?br />    Backtracking(1. 法里面极大一部分内容是如何有效地q行搜烦Q这里的"有效"可以分ؓ(f)Q避免不必要的计(如A*寻\以及(qing)所有的启发式剪枝)Q缓存重复计(如所有的?态规划)?br />2.本质上,l习(fn)q不产生新能力。然而练?fn)最重要的一个作用就是将外显记忆转化?a title="内隐记忆" >内隐记忆。用大白话来说就是将qx需要用脑子LQ参与)的东西{化ؓ(f)内在的习(fn)惯。譬如我们一开始学骑自行R的时候需要不断提醒自己注意^衡,但随着不断的联p,q种技能就内化成了所谓的

hex108 2011-08-24 21:39 发表评论
]]>
[扑ַ作]动态规划与贪心法http://www.shnenglu.com/hex108/archive/2011/08/24/154243.htmlhex108hex108Wed, 24 Aug 2011 12:51:00 GMThttp://www.shnenglu.com/hex108/archive/2011/08/24/154243.htmlhttp://www.shnenglu.com/hex108/comments/154243.htmlhttp://www.shnenglu.com/hex108/archive/2011/08/24/154243.html#Feedback0http://www.shnenglu.com/hex108/comments/commentRss/154243.htmlhttp://www.shnenglu.com/hex108/services/trackbacks/154243.html1.       注意Q如果划分的子问题之间存在依赖,那么该问题就不适合用动态规划解冟뀂(见CLRS 15.3 subtlties节Q?br />
    4) reconsturcting an optimal solution     
      用动态规划有个问题就是在最后得到最优解时不能知道选择的过E,有如下两U方法可以解冻I(x)
      a. 可以Ҏ(gu)我们存下来的信息推导出前一步的选择是什么,如:(x)diff.java
      b. C选择?br />        如果选择较少可以采用Ҏ(gu)aQ否则选择Ҏ(gu)2比较好。这是一个时I权衡问题?/div>
    5Q运用动态规划有几个需要注意的地方Q?br />        a.  We must ensure that when we search for the correct place to spilt the product, we have considered all possible places so that we are sure of         
            having examined the optimal one.
       b.  The subproblems are independent.
       c.  不要形成困定思维: 一惛_动态规划,马上联想到LCSQ然后觉得动态规划的表结构就是一个二l数l?/div>     6)思?br />        子问题有最优解Q那么该问题得到的一定是最优解吗? 如果不是Q那么什么情况下是全局最优解Q什么情冉|局部最优解?
        以<~程之美Q上的一个例子D例说明如?:(有时间再补上)

2. 贪心法  
      A greedy algorithm always makes the choice that looks best at the moment. That is , it makes a locally optimal choce in the hope that chis choce will lead to a globally optimal solution.

     贪心法能解决的问题,动态规划基本都能解冟뀂(CLRS 16.2 Nevertheless, beneath every greedy algorithm, ther is almost always a more cumbersome dynamic-progrmming solutionQ?/div>
     但是QFor many optimization problems, using dynamic programming to determine the best choices is overkill; Simpler, more effiiect algorithms will do. (eg: greedy algorithm)

     1Q适合用贪心法解决的问?
         必须要有Greedy-choice property : a globally optiaml solution can be arrivedat by making a locally optimal (greedy) choice.
         如:(x)Huffman~码Q最生成树(wi)
 
      2Q贪心法的一般步?nbsp;     
          a. 原问题划分为子2个子问题Q非overlap的)Q此时就能用动态规划求解了
          b. 扑ֈ一个划分点Q让其中一个子问题变ؓ(f)I,则只剩下一个子问题了,q就是贪心算?/div>  
       3Q用贪心法时必M证:(x)
           We must prove that a greedy choice at each step yields a golbally optimal solution, and this is where cleverness may be required.
           q点也是最隄。所以有个问?span style="color: red;">“什么情况下Q局部最优最l会(x)产生全局最优的l果Q?#8221;

       4Q适用贪心法的问题有 greedy-choice properttyQ需要找C个贪心策略?br />
       5Q对于找不到全局最优解的问题(如NP问题Q,可以考虑贪心法?br />
3. 动态规划与分治法的比较

      分治法适合于那些能被分解ؓ(f)独立子问题的问题Q动态规划更适用于子问题之间不是独立的,而是?x)share subproblems。动态规划的q个特点得益于它把子问题的结果都保存在一个表中了Q动态规划的英文名字是Dynamic ProgrammingQ这里的Programming可理解ؓ(f)a tabular method(表格Ҏ(gu))Q,q样p去重复子问题的计算?所以动态规划可以算作是分治法在overlapping 子问题里的一个优化(q个优化在程序中是常见的优化Ҏ(gu)MemoizationQhttp://en.wikipedia.org/wiki/MemoizationQ)

4. 动态规划与贪心法的比较
   1) 相同?br />      a. 问题要有optimal substructure 
        A problem exhibits optimalsubstructure if an optimal solution to the problem contains within it optimal solutions to subproblems.       
        q是能用贪心法与动态规划解{的问题的关键因素?br />      b. 都需要划分子问题Q但是划分子问题的方式有些区别,见下面的不同炏V?br />  
   2Q不同点
     a.  划分子问?
        如果你把划分的子问题有交?overloapping subproblem)Q这很昄地将你引入了动态规划的思维Q以"An activity-selection problem"举例说明Q?br />
        对于问题 "An activity-selection problem"Q很Ҏ(gu)p惛_动态规划的解法
int select_activity(int *a, int n, int i)
{
    if(i >=n )
        return 0;
    for(j= i + 1; j < n; j ++){
        if(a[j].start >= a[i].end)
            break;
    }
    int sum1 = select_activity(a, n, j) + 1;   //select the ith activity
    int sum2 = select_activity(a, n, i + 1);   //not select the ith activity
    
    if(sum1 > sum2)
        return sum1;
    else
        return sum2;
}
    但是如何它转化心算法呢Q?br />       {案是:(x)pU方法是不易转化心法的。上面这U划分子问题的方式表明了它更适合于动态规划,像在CLRS 383里说到?-1背包问题QThe problem formulated in this way gives rise to many over-lapping subproblems Q?a hallmark of dynamic programming.
 
    b.  贪心法:(x) make whaterver choice seems best a the moment and then solve the subproblem arising after the choice is made.
        动态规划:(x)make a choice at each step, but the choice usually depends on the solutions to subproblems.

    c.  贪心法:(x)top-down fashinon        
        动态规划:(x)bottom-up manner

   
 


hex108 2011-08-24 20:51 发表评论
]]>[扑ַ作]数据l构结http://www.shnenglu.com/hex108/archive/2011/08/24/154241.htmlhex108hex108Wed, 24 Aug 2011 12:15:00 GMThttp://www.shnenglu.com/hex108/archive/2011/08/24/154241.htmlhttp://www.shnenglu.com/hex108/comments/154241.htmlhttp://www.shnenglu.com/hex108/archive/2011/08/24/154241.html#Feedback0http://www.shnenglu.com/hex108/comments/commentRss/154241.htmlhttp://www.shnenglu.com/hex108/services/trackbacks/154241.html
1. 位图
    位图的威力可以在Q编E珠玑>的开头就体会(x)到。另外在Find an integer not among four billion given ones中的q用也很_ֽ?br />
2. ?br />
   在<~程珠玑Q里重点q用了该l构Q直接导致我以后l常惛_q用该l构?br />   不得不说Q它真的很有用,如:(x)找N个数中最大/最的k个数?br />   实现优先U队列时也有用?/div>
3. ?br />
     二叉搜烦?wi)?x)是一个很Ҏ(gu)p惛_的结构,只要让一二叉树(wi)满以下一个特性就可以了:(x)对于Ml点NQ其左子?wi)结点left满key(x) <= key(N)Q其叛_?wi)结点right满key(y) >= key(N)Q其优点是操作简单,~点是插入,删除l点的复杂度高,为O(N)
     二叉搜烦?wi)复杂度高的原因为?x)?wi)的高度不确?不稳定,有可能ؓ(f)nQ所以问题的关键是:(x)如何控制?wi)的高?br />     很多人灵Z?产生了一pdq二叉?wi),如?x)AVL?wi),Red-Black?wi)?a title="Treap" >Treap
     也生了很多q二叉?wi)的变种Q如Q?a title="Weight balanced tree" >Weight balanced treeQk-neighbor tree{?
     Skip List 也是q二叉?wi)之外的另一U选择
     Suffix_tree后缀?wi)?br />
4. hash
    hash的两个关键点在于Qa. hash桶大的讑֮Q一般ؓ(f)一个素敎ͼ b. 冲突处理机制Q如可以用一个链表处理hash值相同的元素?br />    我很考虑hashQ觉得复杂度不好把握。以后倒是可以考虑用用Q如Q在问题“判断两个链表是否怺”有可以用hashQ?#8220;判断链表有没有环”用hash也很l力?/div>

hex108 2011-08-24 20:15 发表评论
]]>linux信号机制 Q?用户堆栈和内核堆栈的变化http://www.shnenglu.com/hex108/archive/2011/07/26/151886.htmlhex108hex108Tue, 26 Jul 2011 10:27:00 GMThttp://www.shnenglu.com/hex108/archive/2011/07/26/151886.htmlhttp://www.shnenglu.com/hex108/comments/151886.htmlhttp://www.shnenglu.com/hex108/archive/2011/07/26/151886.html#Feedback0http://www.shnenglu.com/hex108/comments/commentRss/151886.htmlhttp://www.shnenglu.com/hex108/services/trackbacks/151886.html此文只简单分析发送信L(fng)用户E序后,用户堆栈和内核堆栈的变化。没有分析实时信P当然整个q程基本一致。很多参考了Q情景分析>Q所以有些代码和现在的内核可能不同,比如RESTORE_ALLQ但大体的机制是cM的?br />
1. 一个信号小例子

hex@Gentoo ~/signal $ cat sigint.c
#include <stdio.h>
#include <stdlib.h>
#include <signal.h>

void sig_int(int signo)
{
    printf("hello\n");
}

int main()
{
    if(signal(SIGINT, sig_int) == SIG_ERR){
        printf("can't catch SIGINT\n");
        exit(-1);
    }

    for(;;)
        ;

    return 0;
}

2. 用户堆栈里发生的故事

2.1 ~译q行该程?q设|断点在sig_int函数开?0x80482e8)Qƈ讄SIGINT信号的处理方?br />hex@Gentoo ~/signal $ gdb ./sigint
(gdb) b *0x80482e8
Breakpoint 1 at 0x80482e8: file sigint.c, line 6.
(gdb) handle SIGINT noprint pass
SIGINT is used by the debugger.
Are you sure you want to change it? (y or n) y
Signal        Stop    Print    Pass to program    Description
SIGINT        No    No    Yes        Interrupt
(gdb) r
Starting program: /home/gj/signal/sigint

2.2 向该E序发送信? kill -INT 此程序的pid?br />hex@Gentoo ~/signal $ kill -INT 4639

2.3 该程序收C号后停在断点?br />Breakpoint 1, sig_int (signo=2) at sigint.c:6
6    {
(gdb) i r esp
esp            0xbfffe7ec    0xbfffe7ec
(gdb) x/40a 0xbfffe7ec
0xbfffe7ec:    0xb7fff400    0x2    0x33    0x0
0xbfffe7fc:    0x7b    0x7b    0x8048930 <__libc_csu_init>    0x80488f0 <__libc_csu_fini>
0xbfffe80c:    0xbfffed58    0xbfffed40    0x0    0x0
0xbfffe81c:    0xbfffec18    0x0    0x0    0x0
0xbfffe82c:    0x8048336 <main+58>    0x73    0x213    0xbfffed40
0xbfffe83c:    0x7b    0xbfffead0    0x0    0x0
0xbfffe84c:    0x0    0x0    0x0    0x0
0xbfffe85c:    0x0    0x0    0x0    0x0
0xbfffe86c:    0x0    0x0    0x0    0x0
0xbfffe87c:    0x0    0x0    0x0    0x0
栈上的内容ؓ(f)信号栈sigframeQ?br />Ҏ(gu)此结构可以知道:(x)
1). q回地址0xb7fff400Q它指向vdso里的sigreturn
(gdb) x/10i 0xb7fff400
   0xb7fff400 <__kernel_sigreturn>:    pop    %eax
   0xb7fff401 <__kernel_sigreturn+1>:    mov    $0x77,%eax
   0xb7fff406 <__kernel_sigreturn+6>:    int    $0x80
q个地址Ҏ(gu)内核的不同而不同,我的内核版本?.6.38?br />2). 信号处理E序完成后,?x)回?eip = 0x8048336 的地址l箋执行?br />

2.4 执行完sig_int函数后,q入了__kernel_sigreturnQ接着回到了代?x8048336处,一切恢复了正常?br />(gdb) x/5i $pc
=> 0x8048336 <main+58>:    jmp    0x8048336 <main+58>
(gdb) i r esp
esp            0xbfffed40    0xbfffed40

在用户层我们能看到的只有上面q么多信息了Q可能有一个地方不能理解:(x)在上面过Ec??xbfffe7ec起那一块栈上的内容从哪来的Q(正常情况下堆栈esp应该一直指向在q程d中显C的esp?xbfffed40Q?br />
现在来看看在上面q些现象之下Q内核的堆栈发生了怎样的变化?br />
3. 内核堆栈里发生的故事
3.1 发信h
?2.2 里当执行kill -INT 4639后,pid?639的程序(也就是我们运行的 ./sigintQ会(x)收到一个信P但是信号实际都是在内栔R实现的。每个进E(q里只讲q程的情况,U程cMQ线E有一个tidQ都有一个pidQ与此pid对应有一个结?task_struct Q在task_struct里有一个变?struct sigpending pendingQ当该进E收ChQƈ不会(x)立即作出反应Q只是让内核把这个信可在了此变量里Q它里面是一个链表结构)。当Ӟ此时与内核堆栈还没有多大关系?br />
3.2 (g)信?br />  如果只记录了信号Q但没有相应反应Q那有什么用啊。一个进E在什?情况下会(x)(g)信L(fng)存在呢??lt;情景分析>里说CQ?#8220;在中断机制中Q处理器的硬件在每条指o(h)l束旉要检是否有中断h的存在。信h制是UY件的Q当然不能依靠硬件来(g)信L(fng)到来。同Ӟ要在每条指o(h)l束旉来检显然是不现实的Q甚x不可能的。所以对信号的检机制是Q每当从pȝ调用Q中断处理或异常处理q回到用L(fng)间的前夕Q还有就是当q程被从睡眠中唤醒(必定是在pȝ调用中)的时候,此时若发现有信号在等待就要提前从pȝ调用q回。总而言之,不管是正常返回还是提前返回,在返回到用户I间的前夕L要检信L(fng)存在q作出反应?#8221;

  因此Q对收到的信号做出反应的旉?从内核返回用L(fng)间的前夕Q那么有那些情况?x)让E序q入内核呢?{案是中断,异常和系l调用。简单了解一下它们发生时内核堆栈的变化?br />
  //-----中断Q异常,pȝ调用 : 开?
   1)在用L(fng)间发生中断时QCPU?x)自动在内核I间保存用户堆栈的SSQ?用户堆栈的ESPQ?EFLAGS, 用户I间的CS, EIP, 中断?- 256
   | 用户堆栈的SS | 用户堆栈的ESP | EFLAGS | 用户I间的CS | EIP | 中断?Q?256
   q入内核后,?x)进行一个SAVE_ALLQ这样内核栈上的内容为:(x)
   | 用户堆栈的SS | 用户堆栈的ESP | EFLAGS | 用户I间的CS | EIP | 中断?Q?256 | ES | DS | EAX | EBP | EDI | ESI | EDX | ECX | EBX

   好了Q一切都处理完时Q内核jmp到RESTORE_ALLQ它是一个宏Q例Q在x86_32体系l构下,/usr/src/kernel/arch/286/kernel/entry_32.S文g里包含该宏的定义Q?br />
   RESTORE做的工作Q从它的代码里就可以看出来了Q?nbsp;  
   首先把栈上的 ES | DS | EAX | EBP | EDI | ESI | EDX | ECX | EBX pop到对应的寄存器里
   然后esp Q?4 ?“中断?Q?256” pop?
   此时内核栈上的内容ؓ(f)Q?br />   | 用户堆栈的SS | 用户堆栈的ESP | EFLAGS | 用户I间的CS | EIP
   最后执行iret指o(h)Q此时CPU?x)从内核栈上取出SS, ESP, ELFGAS, CS, EIPQ然后接着q行?br />
   2) 在用L(fng)间发生异常时QCPU自动保存在内核栈的内容ؓ(f)Q?br />   | 用户堆栈的SS | 用户堆栈的ESP | EFLAGS | 用户I间的CS | EIP | 出错代码 error_code
   Q注QCPU只是在进入异常时才知道是否应该把出错代码压入堆栈Qؓ(f)什?Q,而从异常处理通过iret指o(h)q回时已l时q境q,CPU已经无从知当初发生异常的原因Q因此不?x)自动蟩q这一,而要靠相应的异常处程序对堆栈加以调整Q得在CPU开始执行iret指o(h)时堆栈顶部是q回地址Q?br />
   q入内核后,没有q行SAVE_ALLQ而是q入相应的异常处理函敎ͼq个函数是包装后的,真正的处理函数在后面Q(在此函数里会(x)把真正的处理函数的地址push到栈上)Q然后jmp到各U异常处理所q的程序入口error_codeQ它?x)像SAVE_ALL那样保存相应的寄存器Q没有保存ESQ,此时内核I间上的内容为:(x)
   | 用户堆栈的SS | 用户堆栈的ESP | EFLAGS | 用户I间的CS | EIP | 出错代码 error_code | 相应异常处理函数入口 | DS | EAX | EBP | EDI | ESI | EDX | ECX | EBX
   Q注Q如果没有出错代码,则此gؓ(f)0Q?br />
   最后结束时与中断类|RESTORE_ALLQ?br />
   3) 发生pȝ调用ӞCPU自动保存在内核栈的内容ؓ(f):
   | 用户堆栈的SS | 用户堆栈的ESP | EFLAGS | 用户I间的CS | EIP
   Z与中断和异常的栈一_(d)在进入系l调用入口(ENTRY(system_call)Q后?x)首先push %eaxQ然后进行SAVE_ALLQ此时内核栈上的内容?br />   | 用户堆栈的SS | 用户堆栈的ESP | EFLAGS | 用户I间的CS | EIP | EAX | ES | DS | EAX | EBP | EDI | ESI | EDX | ECX | EBX
 
   最后结束时与中断类|RESTORE_ALLQ?br />   //-----中断Q异常,pȝ调用 : l束

   中断Q异常,pȝ调用q部分有一炚w漏的地方Q检信L(fng)时机是紧挨着RESTORE_ALL之前发生的?br />
3.3 Ҏ(gu)到的信号做出反?br />  如果(g)到有要处理的信hQ就要开始做一些准备工作了Q此时内栔R的内容ؓ(f)Q进入内核现场时的内容)
  | 用户堆栈的SS1 | 用户堆栈的ESP1 | EFLAGS1 | 用户I间的CS1 | EIP1 | ? | ES1 | DS1 | EAX1 | EBP1 | EDI1 | ESI1 | EDX1 | ECX1 | EBX1
  Q注Q?的值有三个选择Q中断号 Q?256Q出错代?error_codeQ出错代?error_codeQ?
  假设要处理的信号对应的信号处理E序是用戯p|的Q即本文中SIGINT对应的信号处理程序sig_int?br />  现在要做的事情是让cpuL行信号处理程序sig_intQ但是执行前需要做好准备工作:(x)
  3.3.1  setup_frame
  在用L(fng)间设|好信号?struct sigframe)(假设讄好栈后esp的gؓ(f)sigframe_espQ在本文中其gؓ(f)0xbfffe7ec)Q即?.3里看到的栈内宏V?br />  注:(x)struct sigframe里至包含以下内容:(x)
  用户堆栈的SS1Q?用户堆栈的ESP1Q?EFLAGS1Q?用户I间的CS1Q?EIP1Q?ES1Q?DS1Q?EAX1Q?EBP1Q?EDI1Q?ESI1Q?EDX1Q?ECX1Q?EBX1

  3.3.2 讄卛_q行的eip的gؓ(f)信号处理函数sig_int的地址Qؓ(f)0x80482e8Q,q设|用户ESP的gؓ(f)sigframe_esp(?xbfffe7ec)Q这是通过修改内核栈里的EIP和ESP的值实现的Q因为在从系l调用里iretӞ?x)从内核栈里取EIPQESP?br />  q时内核栈的内核?
  | 用户堆栈的SS1 | 0xbfffe7ec | EFLAGS1 | 用户I间的CS1 | 0x80482e8 | ? | ES1 | DS1 | EAX1 | EBP1 | EDI1 | ESI1 | EDX1 | ECX1 | EBX1
 
  最后,q行RESTORE_ALLQ内核栈上的内容为:(x)
  | 用户堆栈的SS1 | 0xbfffe7ec | EFLAGS1 | 用户I间的CS1 | 0x80482e8
 
  RESTORE_ALL里执行完iret后,寄存器内容ؓ(f)Q?EIP?x80482e8(即sig_int),esp?xbfffe7ec ?于是用户I间C步骤 2.3

3.4 信号处理E序完成以后
  2.3 -> 2.4Q进入了sig_returnpȝ调用Q在sig_return里,内核栈的内容为(每个名字后面加一?以便与前面的1区分Q?br />  | 用户堆栈的SS2 | 用户堆栈的ESP2 | EFLAGS2 | 用户I间的CS2 | EIP2 | ? | ES2 | DS2 | EAX2 | EBP2 | EDI2 | ESI2 | EDX2 | ECX2 | EBX2
  sig_return要做的主要工作就是根据用h里sigframe的g改内核栈里的内容Q内核栈变?
  | 用户堆栈的SS1 | 用户堆栈的ESP1 | EFLAGS1 | 用户I间的CS1 | EIP1 | ? | ES1 | DS1 | EAX1 | EBP1 | EDI1 | ESI1 | EDX1 | ECX1 | EBX1
                                                  
  x内核栈里的内容和q行信号处理前一样了。经qRESTORE_ALL后,用户堆栈里的内容也和以前一P主要指ESP的gP?

  "kill -INT 4639" 只是一D小插曲。程序从原处开始运行?/div>

hex108 2011-07-26 18:27 发表评论
]]>
?lt;~程珠玑>Q不要忘了还有这本经?/title><link>http://www.shnenglu.com/hex108/archive/2011/07/07/150403.html</link><dc:creator>hex108</dc:creator><author>hex108</author><pubDate>Thu, 07 Jul 2011 12:47:00 GMT</pubDate><guid>http://www.shnenglu.com/hex108/archive/2011/07/07/150403.html</guid><wfw:comment>http://www.shnenglu.com/hex108/comments/150403.html</wfw:comment><comments>http://www.shnenglu.com/hex108/archive/2011/07/07/150403.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.shnenglu.com/hex108/comments/commentRss/150403.html</wfw:commentRss><trackback:ping>http://www.shnenglu.com/hex108/services/trackbacks/150403.html</trackback:ping><description><![CDATA[<div>     ȝq程真是一Un受。看到好的代码,好的思想QM(x)忍不住默记几遍?br /><br />     看到觉得有点意味的地Ҏ(gu)好多x来龙去脉Q想想ؓ(f)什么,因ؓ(f)紧接着的会(x)是o(h)人惊喜的解说?多写写书上的代码Q感觉不错(写完以后感觉忘了很久的算法又重新回来了)?每章?#8220;原理”部分是高度性的概括Q??fn)?是很好的Q促使你L考,做习(fn)题是很有必要的,不想“费”旉?#8220;做习(fn)?#8221;了的l果可能是以后会(x)用更多的旉才能xq些问题Q还有不要只想着看答案,你会(x)很失望,因ؓ(f)有些题目是没有答案的 :)  psQ有很多面试题来自其中的?fn)?br /><br />     对一些算法有了更好的理解Q也许是看第二遍的原因,也许是从不同的角度看?x)有不同的效果?span>所?/span><span style="color: red;">好书要多读,每重Mơ会(x)有新的收?/span>Q。比如:(x)在动态规划算法里Q程序可以用递归法和用表格化方法实现。递归法的缺Ҏ(gu)Q有部分g(x)被重,解决Ҏ(gu)是用一个数l把已经计算q的值存hQ这样就不会(x)重复计算了。表格化的算法是Q没有递归法好理解,解决办法是:(x)在代码开头加个注释,注释是那几条递归规则Q大不了再加上说?#8220;此代码用的是动态规?#8221;?psQlinux里diff的基本算法就是动态规划吧Q感觉和最长公共子串类|自己实现了一?<a title="diff.pl">diff.pl</a>)(更新Q今天在|上看到了关于diff用动态规划实现的信息Q?a title="Dynamic programming Creative Exercises 2 Unix diff" >Dynamic programming Creative Exercises 2 Unix diff</a>, 其源码ؓ(f)<a title="diff.java" >diff.java</a> Q比我的好了N多倍,打印l果的那D代码的思想相当好!代码z清淅。另外,我开始觉得用表格化的Ҏ(gu)实现动态规划更帅了?nbsp; Q-2011.7.22 )?br /><br />    读这本书收获很多Q列丑և个吧Q?br />    1. 书里?#8220;<a href="http://www.shnenglu.com/hex108/archive/2011/06/18/148907.html" title="E序验证">E序验证</a>” 技术很靠谱Q让E序看v来清晰易懂,q能从一定程度保证正性?br />    2. “哨兵”(<a title="Sentinel value">Sentinel value</a> )被几ơ用CQ感觉还不错Q代码看h更简单了Q还能带来一点小效率?br />    3. 时空折中与双赢。在原始设计的算法ƈ非最x案时Q通过改善法是可以达到双赢的?br />    4. 用只分配一个较大内存块的方案来替换通用内存分配Q这样就消除了很?开销较大的调用,而且也用空间的利用更加有效?br />    5. 数学模型的徏立是很重要的。把数ax用集合[a,a + 1)表示是第9章中二分查找代码调优的核心思想。数l旋转那个算法也实在是太nb了?br />    6. 一个写得很好的代码Q在几个地方看到q,M(x)忘,q次CQ?br /><div style="background-color:#eeeeee;font-size:13px;border:1px solid #CCCCCC;padding-right: 5px;padding-bottom: 4px;padding-left: 4px;padding-top: 4px;width: 98%;word-break:break-all"><span style="color: #000000; ">  链表里有一个哨兵元素,初始? head </span><span style="color: #000000; ">=</span><span style="color: #000000; "> sentinel </span><span style="color: #000000; ">=</span><span style="color: #000000; "> </span><span style="color: #0000FF; ">new</span><span style="color: #000000; "> Node(value, </span><span style="color: #000000; ">0</span><span style="color: #000000; ">);<br />  向链表插入元素:(x) <br />  insert(v)<br />      </span><span style="color: #0000FF; ">for</span><span style="color: #000000; ">(p </span><span style="color: #000000; ">=</span><span style="color: #000000; "> </span><span style="color: #000000; ">&</span><span style="color: #000000; ">head; (</span><span style="color: #000000; ">*</span><span style="color: #000000; ">p)</span><span style="color: #000000; ">-></span><span style="color: #000000; ">val </span><span style="color: #000000; "><</span><span style="color: #000000; "> t; p </span><span style="color: #000000; ">=</span><span style="color: #000000; "> </span><span style="color: #000000; ">&</span><span style="color: #000000; ">((</span><span style="color: #000000; ">*</span><span style="color: #000000; ">p)</span><span style="color: #000000; ">-></span><span style="color: #000000; ">next))<br />          ;<br />      </span><span style="color: #0000FF; ">if</span><span style="color: #000000; ">  (</span><span style="color: #000000; ">*</span><span style="color: #000000; ">p)</span><span style="color: #000000; ">-></span><span style="color: #000000; ">val </span><span style="color: #000000; ">==</span><span style="color: #000000; "> v <br />          </span><span style="color: #0000FF; ">return</span><span style="color: #000000; "><br />      </span><span style="color: #000000; ">*</span><span style="color: #000000; ">p </span><span style="color: #000000; ">=</span><span style="color: #000000; "> </span><span style="color: #0000FF; ">new</span><span style="color: #000000; "> node(v, </span><span style="color: #000000; ">*</span><span style="color: #000000; ">p)<br /><br />  下面是我写的Q?br />  insert(v)<br />        p </span><span style="color: #000000; ">=</span><span style="color: #000000; "> head;<br />        </span><span style="color: #0000FF; ">while</span><span style="color: #000000; ">(p</span><span style="color: #000000; ">-></span><span style="color: #000000; ">val </span><span style="color: #000000; "><</span><span style="color: #000000; "> t)<br />            p </span><span style="color: #000000; ">=</span><span style="color: #000000; "> p</span><span style="color: #000000; ">-></span><span style="color: #000000; ">next<br />        </span><span style="color: #0000FF; ">if</span><span style="color: #000000; ">(p</span><span style="color: #000000; ">-></span><span style="color: #000000; "> val </span><span style="color: #000000; ">==</span><span style="color: #000000; "> v)<br />            </span><span style="color: #0000FF; ">return</span><span style="color: #000000; "><br />        q </span><span style="color: #000000; ">=</span><span style="color: #000000; "> node(t,p)<br />        </span><span style="color: #0000FF; ">if</span><span style="color: #000000; ">(p </span><span style="color: #000000; ">==</span><span style="color: #000000; "> head)<br />             head </span><span style="color: #000000; ">=</span><span style="color: #000000; "> q;</span></div><br />    另外Q注意到一本书Q?a title="法设计与分析基">法设计与分析基</a>Q?Q用不同的方式讲法Q把法按其通用E度提出?个最基本的算法思想QBrute force Q?Divide & conquer Q?Decrease & conquerQ?nbsp; Transform & conquer?<br /><br />    最后摘录一?W?版跋 里给的几个徏?<br />    1. 解决正确的问题?首先d理解问题<br />    2. 探烦所有可能的解决Ҏ(gu)<br />    3. 观察数据<br />    4. 使用_略估算<br />    5. 得用对称?<br />    6. 利用lg做设? <br />    7. 建立原型 <br />    8. 必要时进行权? <br />    9. 保持? <br />    10.q求优美</div><img src ="http://www.shnenglu.com/hex108/aggbug/150403.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.shnenglu.com/hex108/" target="_blank">hex108</a> 2011-07-07 20:47 <a href="http://www.shnenglu.com/hex108/archive/2011/07/07/150403.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>关于法的一些资?/title><link>http://www.shnenglu.com/hex108/archive/2011/07/01/149939.html</link><dc:creator>hex108</dc:creator><author>hex108</author><pubDate>Fri, 01 Jul 2011 12:27:00 GMT</pubDate><guid>http://www.shnenglu.com/hex108/archive/2011/07/01/149939.html</guid><wfw:comment>http://www.shnenglu.com/hex108/comments/149939.html</wfw:comment><comments>http://www.shnenglu.com/hex108/archive/2011/07/01/149939.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.shnenglu.com/hex108/comments/commentRss/149939.html</wfw:commentRss><trackback:ping>http://www.shnenglu.com/hex108/services/trackbacks/149939.html</trackback:ping><description><![CDATA[<span style="font-family: verdana, 'courier new'; font-size: 14px; line-height: 21px; ">法的过E很详细Q美中不的?/span>最基本最常用的那些算法其实是比较?yu)的Q花Ҏ(gu)间多xZ么,知其然还要知其所以然(<a title="1" >1</a>Q?a title="2">2</a>)Q这h能活学活用?br /><br />1. ? <br />1.1 <a title="~程珠玑">~程珠玑</a><br />    a意赅Q回xI本书的|络版在 <a title="http://netlib.bell-labs.com/cm/cs/pearls/">http://netlib.bell-labs.com/cm/cs/pearls/</a> 上,附有源代码?<a href="http://www.shnenglu.com/hex108/archive/2011/07/07/150403.html" title="q里">q里</a>有我的读书ȝ?受到此书的媄响,我对代码产生了很强的z癖Q坚信代码还可以写得更优,更艺术。此外面对一个问题时分析的角度更多了?br /><br />1.2 <a title="~程之美" >~程之美</a><br />     书上的每个题都会(x)仔细地做Qƈ完成代码。思考的乐趣是无IL(fng)Q时怼(x)有乐?br /><br />1.3 <a title="法D" >法D<br /></a>   l典但是比较厚,适合pȝ地学?fn)算法,而后每次遇到不懂的可以再查阅Q?div style="display: inline-block; "></div>法的过E很详细Q美中不的是没有知其所以然的感觉。看此书W一遍时Q是按照书的序看的Q对q些法大致都有熟?zhn)了。后来会(x)偶尔查阅。现在ؓ(f)了准备算法,?x)时常查阅此书?a title="法D" ><br /></a><br />2. 文章<br />2.1 <a title="Do We Teach the Right Algorithm Design Techniques ?" >Do We Teach the Right Algorithm Design Techniques ?</a> <br />   把算法按光用E度提出?个最基本的算法思想QBrute force Q?Divide & conquer Q?Decrease & conquerQ?nbsp; Transform & conquer?br />   d后可以对法的整体有更好的掌握?br /><br />3. |络教程<br />3.1 <a title="Top Coder的algorithm tutorial">Top Coder的algorithm tutorial</a><img src ="http://www.shnenglu.com/hex108/aggbug/149939.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.shnenglu.com/hex108/" target="_blank">hex108</a> 2011-07-01 20:27 <a href="http://www.shnenglu.com/hex108/archive/2011/07/01/149939.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>二分查找 -- 来自~程珠玑http://www.shnenglu.com/hex108/archive/2011/06/18/148907.htmlhex108hex108Sat, 18 Jun 2011 07:02:00 GMThttp://www.shnenglu.com/hex108/archive/2011/06/18/148907.htmlhttp://www.shnenglu.com/hex108/comments/148907.htmlhttp://www.shnenglu.com/hex108/archive/2011/06/18/148907.html#Feedback3http://www.shnenglu.com/hex108/comments/commentRss/148907.htmlhttp://www.shnenglu.com/hex108/services/trackbacks/148907.htmlBinary search algorithmQ是一个很常见的算法,从<~程珠玑Q里再次看到时又有新的收莗?br />      直接看代码吧Q下面是常见的实C码:(x)
    
int binary_search(int *a, int num, int t)
{
    
int start = 0, end = num - 1;
    
    
while(end >= start){
        
int middle = (start + end) / 2;
        
int tmp = a[middle];
        
if(tmp < t){
            start 
= middle + 1;
        }
else if(tmp > t){
            end 
= middle - 1;
        }
else{
            
return middle;
        }
    }

    
return -1;
}   

      优化后的代码为(q个优化的思想也挺好的Q不知道有没有一套系l的Ҏ(gu)来思考出q个优化思\Q:(x)
     
int binary_search(int *a, int num, int t)
{
    
int low = -1, high = num - 1;
    
    
while(low + 1 != high){
        
int middle = (low + high) / 2;
        
if(a[middle] < t){
            low 
= middle;
        }
else{
            high 
= middle;
        }
    }
    
    
if(a[high] != t)
        
return -1;
    
else
        
return high;
}
 
     如果直接看这D代码,有可能不知道是怎么回事。但是运用书中提到的“E序验证”的方法后Q原理就显而易见了Q修改后的代码ؓ(f)Q?br />
 1 int binary_search(int *a, int num, int t)
 2 {
 3     int low = -1, high = num - 1;
 4     
 5     //invariant: low < high && a[low] < t && a[high] >= t
 6     while(low + 1 != high){
 7         int middle = (low + high) / 2Q=Q?/span>  int middle = low + (high - low) / 2;   //防止溢出
 8         if(a[middle] < t){
 9             low = middle;
10         }else{
11             high = middle;
12         }
13     }   
14    //assertQ low +1 = high && a[low] < t && a[high] >= t
15   
16     if(a[high] != t)
17         return -1;
18     else
19         return high;
20 }
21 

      “E序验证” 的思想可以qCؓ(f)Q不是验证一个函敎ͼq是一条语句,一个控制结构(循环Qif分支{)Q都可以采用两个断言Q前|条件和后置条gQ来辑ֈq个目的。前|条件是在执行该处代码之前就应该成立的条Ӟ后置条g的正性在执行完该处代码后必须得到保证。(ps: 断言也算是一U验证的手段Q?br />
  上面q段代码的原理是l定一D区?(low, high] Q如果満?a[low] < t  && a[high] >=t && high = low + 1Q那么有两种情况存在Q?. a[high] = t ; 2.与t相等的元素不存在。由于数la 肯定满条ga[low] < t  && a[high] >=tQ所以该法要做的就是把区间 (-1, num -1] ~小?low, low+1]? 
      1. 在执行代?~17行时Q?span>始终保证low < high && a[low] < t && a[high] >= t 成立?/span>
  
2. 在执行完6~17行后Q肯定滿x件a[low] < t  && a[high] >=t && high = low + 1Q因为@环退出的条g?high = low + 1Q而该循环始终保证上面W1条?br />  l过q样的分析后Q我们能对程序的正确性有更好的掌握,同时E序也更易理解?br />
参考:(x)
  Q? 基本上摘自<~程珠玑Q,很不错的一本书Q让我对法有了新的思考,以前只是看看法D如何实现的,没有思考该法是如何想出来的,有没有更单的法Q思考的q程cM刘未鹏的Q?a title="知其所以然Q箋Q?>知其所以然Q箋Q?/a>Q)Q要坚持q个思考过E需要很多功夫与旉Q但效果也很明显Q能对算法有更好的掌握?img src ="http://www.shnenglu.com/hex108/aggbug/148907.html" width = "1" height = "1" />

hex108 2011-06-18 15:02 发表评论
]]>
gdb,strace那些不常用的功能http://www.shnenglu.com/hex108/archive/2011/05/17/146600.htmlhex108hex108Tue, 17 May 2011 13:14:00 GMThttp://www.shnenglu.com/hex108/archive/2011/05/17/146600.htmlhttp://www.shnenglu.com/hex108/comments/146600.htmlhttp://www.shnenglu.com/hex108/archive/2011/05/17/146600.html#Feedback3http://www.shnenglu.com/hex108/comments/commentRss/146600.htmlhttp://www.shnenglu.com/hex108/services/trackbacks/146600.html
gdbq行时会(x)首先加蝲 ~/.gdbinit文g
例如Q我在debugӞ每次都需要进行handle SIGBUS noprint pass来处理SIGBUS信号Q这U情况就可以把它写入 .gdbinit文g?
?gdbinit里也可以定义?
eg: ?gdbinit里定义print_regs
def print_regs
i r eax ebx ecx edx
end
(gdb) print_regs
eax 0xbffff4a4 -1073744732
ebx 0x28bff4 2670580
ecx 0x902c5562 -1876142750
edx 0x1 1  阅读全文

hex108 2011-05-17 21:14 发表评论
]]>
Debughttp://www.shnenglu.com/hex108/archive/2011/05/17/146592.htmlhex108hex108Tue, 17 May 2011 12:26:00 GMThttp://www.shnenglu.com/hex108/archive/2011/05/17/146592.htmlhttp://www.shnenglu.com/hex108/comments/146592.htmlhttp://www.shnenglu.com/hex108/archive/2011/05/17/146592.html#Feedback0http://www.shnenglu.com/hex108/comments/commentRss/146592.htmlhttp://www.shnenglu.com/hex108/services/trackbacks/146592.html     debug可以帮助熟?zhn)pȝQ可是时间长了会(x)很疲P特别是机械的调试Q如果还要面Ҏ(gu)q代码Q更是雪上加霜。所以要学着从debug中钻探快乐,在系l的调试q程中发挥想象,试不同的debugҎ(gu)?/p>

    最q看了《Y件调试实战》,l合自己的经历,ȝ了一下:(x)

    1. 与测试用例相?/p>

       a. 如果不能辑ֈ“试先行”Q至应该在写完代码后有相对完整的测试用例。对于正性的保证和以后重构代码都是有好处的?/p>

       b. 每次d新功能或修复了一个bugӞ都应该增加测试用例!A历经千辛万苦l于fix 了一个bugQ很久很久以后,B觉得q段代码需要改改,于是改了改,后来的结果还是改了,而且利提交C库里Q因为A当时遇到的bug q没有出玎ͼQ?/p>

       c. 回归试

         修改代码后进行回归测试。每ơ提交一个版本后自动q行回归试Q保证库里的代码的正性?

       d. 化测试用?

         好处Q可以排除不起作用的因素Q减测试用例的q行旉Q最重要的是Q用测试用例更Ҏ(gu)调试Q谁愿意处理那些填充了数百或数千的数据容器呢?Q?

         Ҏ(gu)如:(x) 如果试例子比较好改Q可以将其改;输入集改小

       e. 完成代码Q清理后重新q行所有测试用例?

    2. 关于E序的编?

      a. 重视~译期间的warningQ最好把warning数减?. 不要忽略~译器警告,即它们可能是无害的?

egQ?

int add(int a,int b){

        return a +b ;

}

l果头文仉声明成了 extern int add(long a,int b)

?x)调试死人啊Q调E序的时候一看程序定义是对的啊,怎么传的参数一下就变了Q?

b. 如果出现莫名其妙的错?

      如果是用Makefilel织工程Ӟ考虑make cleanQ有可能修改数据l构或头文g后改变了一些东西,但是׃一些未知原因该文gq未重新~译。如果函数是C函数Q有可能调用者和?调用者的参数的成员和cd不同。如果一个类Ҏ(gu)Q则讉KMcL?都将发生错误Q因两个cȝ内存而已几乎是完全不同的。这可能DSegmentation falut,或是很久之后才能(g)到的内存破坏?

3. 关于链接

a. 链接器的基本工作原理

       ~译器或汇编E序源代码转换为机器代码,q输出对象谁的。对象文件中包含W号Q函数或变量Q,q些W号有的在本模块定义的,有的在其他模块定义的Q链接器在链接对象文g时把q些未定义的W号与定义它的模块对应v来?

b. 链接序

     有库和归档文件时 链接法是不一L(fng)?nbsp;   

     链接器参数顺序很重要Q对于编译单元(如对象文件和库)和搜索\径来说都是如此?

c. C++中用C代码Ӟ用extern c{} 把C代码包装一下?

     关于 c++W号和名U改~:(x)C++允许重蝲函数Qؓ(f)了生成C++代码元素的唯一W号Q编译器使一U称为名U改~(name manglingQ的技术,它将对象的准规D明(如会(x)员名I间和函数参数的个数?qing)类型)~码到符号中。(可以用c++filt解析出来~ eg: c++filt _Z9factoriali的结果ؓ(f)factorial(int)Q?

d. 环境变量

   LD_LIBRARY_PATH?x)媄响动态加载的库,用LDD可以看到E序依赖哪个动态库

4. 自动化测?

   让一切自动化h。如果重复的做一件事Q就很有必要考虑自动化了?

5. 关于那些怪异的错?

    在一些显而易见有内存问题的情况下Q如Q间歇故障和无法解释的随为,q时考虑使用内存调试器了Q?

    如valgrindQ很好用Q也很简单?

    valgrind –tool=massif your_program q行内存剖析Q检内存分配情况,优化内存使用Q?

    valgrind –tool=memcheck your_program q行内存?gu)(g)查((g)无效的写访问,(g)对未初始化的内存的d操作Q检内存泄露等Q?

    valgrind –tool=helgrind your_program 查找竞争条gQ可以用来辅助调试多U程E序

    valgrid –-db-attac=yes的功能很好用Q可以将内存高度器和源代码测试器Q如gdbQ结合v来,q样可以即时查看当时的变量的|很好用!

6. 静态检查器

   作ؓ(f)常规软g构徏q程中的一部分q行Q用于查找一些可通过静态源代码分析发现的特定bug?

7. 关于q行时剖析工?

     不要~写自己的运行时剖析时工P(x)自己霞友云朋一的剖?工具通常使用pȝ调用time()或ctime()来测量时间。这些系l调用的问题是开销很高Q而且准确度低。另处在剖析期间要收集大量数据,可能?x)媄响程序本w的行ؓ(f)?

8. 环境变量

  如程序的行ؓ(f)可能 依赖于当前工作目录。在linux上,目录被注册到环境变量CWD上。这个bug到q,q导致了死锁?

9. d恰当的错误消?

  某个地方出错Ӟ满屏都是错误消息Ӟ应该重点x哪些消息Q?

  Answer: 首先出现的那些消息!因ؓ(f)后面的消息有可能是前面导致的。这和编译出错时的情景一_(d)(x)~译错误有很多,我们肯定?x)直觉地d扄一个出错的 地方Q谁知道是不是少了个括号D后面一q串的错误?

10. bug不会(x)自动消失

      如果某个版本有bugQupdate后,bug消失了,“真好Q?#8221;Q一定要弄清楚bug出现的原因是什么。以前遇到过一个bugQ增加一条printf语句后,bug消失了!最后发现问题是数组界了,而修Ҏ(gu)代码?x)导致代码段Q数据段的布局{改变,所以会(x)D偶尔寏V(q种情况可以求助于内存调试工h者静态检查的工具Q?

11. 学习(fn)使用gcc, gdb,strace {工兗(熟?zhn)以后可以再挖掘挖掘,可能有惊喜?

12. cvs/svn commit之前一定要diff一下,看做了哪些修改,以避免不心删掉一些东西后Q然?#8221;被提?#8221;了?

最后,最强大的工具不在计机中,而是调试者的判断力和分析技巧?/p>

   参考资料:(x)

   1. 《Y件调试实战》:(x)http://book.douban.com/subject/4231293/



hex108 2011-05-17 20:26 发表评论
]]>
shell~程 : Remember that the shell spends a lot of its life substituting texthttp://www.shnenglu.com/hex108/archive/2011/04/23/144812.htmlhex108hex108Fri, 22 Apr 2011 16:23:00 GMThttp://www.shnenglu.com/hex108/archive/2011/04/23/144812.htmlhttp://www.shnenglu.com/hex108/comments/144812.htmlhttp://www.shnenglu.com/hex108/archive/2011/04/23/144812.html#Feedback0http://www.shnenglu.com/hex108/comments/commentRss/144812.htmlhttp://www.shnenglu.com/hex108/services/trackbacks/144812.html        对shell不熟Q偶?dng)?x)C些我无法理解的现象。此时该q行debug了,可选的Ҏ(gu)?
        a. echo变量的?nbsp;
        b. shell –x
   
        此外Q?font color="#ff0000">Remember that the shell spends a lot of its life substituting text.Q?a >http://linuxcommand.org/wss0100.phpQ例如,对于下面的程序:(x)
hex108@Gentoo ~ $ cat test.sh 
#!/bin/sh
var=
if [ $var = "y" ] ;then
    echo "yes"
fi
        if语句里的var变量l替换后变ؓ(f) if [ = "y" ]Q些时当然会(x)出错?br />
hex108@Gentoo ~ $ ./test.sh 
./test.sh: line 3: [: =: unary operator expected

          
        ps:现在写脚本的时候們֐于用perl,而较?yu)用shell Q因为对于经怋用的脚本Q可能会(x)l常需要对它不停地q行改进Q慢慢的Q程序越来越大,该考虑重构了,   此时才会(x)发现perl(python{?#8220;真正?#8221;脚本语言)比shell相对来说更好重构?/p>

hex108 2011-04-23 00:23 发表评论
]]> þþþAVվ| 99þþƷѿ| ޾Ʒþþþþþþþþþ| Ʒ˾þþ| ԭۺϾþ| 69Ʒþþþ9999APGF | þ㽶߿ۿ| ŷԴƬxxxxxþþ| 91þþƷ91þɫ| þþƷ޾Ʒŷ| պ뾫Ʒþþò| ƷþþĻ| þˬˬƬAV| ɫۺϾþþþĻ| 99þһa| þݺҹҹ2020һ| ۲ӰԺþùƷ| vaĻþò| þþþþëƬѿ| þۺ϶㼤þ| պAVþһ| ɫþþۺ| þþþۺϹŷһ| þòþüƵ7| 97Ʒ97þþþþ| þþžžþƷ| ޳˾þ| ŷ龫Ʒþþþ| Ʒ9999þþþ| þùƷ77777| þˬˬAV | þþƷȫۿ| 99þþƷëƬ| þþƷƵ| ƷþӰԺ| þ㽶߿ۿ99| ݺɫþ| þ99Ļþ| aëƬþѲ| þùƷһ| ƷŷƬþùŷ|