in

SDT Community Server

SDT Forums, Blogs, Photos server.

This Blog

Syndication

Coolboy

  • 雷人的话..

    1. ~QQ上多了,什么企鹅没见过。 

    2. 从今天开始,我只讨厌你一个人,欺负你,虐待你,你开心我就弄的你不开心,你不开心我就超级开心,别人欺负你我就在第一时间出来踩你,对你说的每一句话都是假话,答应你的每一件事都懒得去做 

    3. 有人把你放心上、有人把你放床上 

    4. 如果你的心里装的下另外一个女人 那么 我的床上就可以睡下另外一个男人 

    5. 珍爱生命 远离天蝎 

    6.我爱你时,你说什么就是什么。我不爱你时,你说你是什么。 

    7.如果我不能死在她的心里,那么就让她死在我的手里 

    8. 早知道尕妹妹的心变了,谈他妈的恋爱是做啥呢:

    9. 你的一生我只借一晚:

    10. 现在的你,已经不会再让我哭了:

    11. 把你的铁石心肠含在我的樱桃小口中:

    12. 有那么一棵树值得你放弃整片森林 

    13. 每天早上醒来,看见你和阳光都在,这就是我想要的未来 

    14. 听说你过得不好,那我也就放心了 

    15. 青春就是疯狂奔跑,然后华丽的跌倒 

    16. 只留青春,不留遗憾 

    17. 所谓低调,其实就是不露痕迹的高调 

    18.LZ:“我五八年的,征个女友” 
    回复:“恋爱就不必谈了,遗产直接打我卡上吧。” 

    19.buffet不妨食过份,出猫唔好太高分。 

    20.因为以前太掏心掏肺了,所以搞的现在没心没肺。 

    ----------------------------------------------------------------------------- 


    21.一人做事一人当,小叮当做事小叮当! 
    22.X是一样的X,脸上见高低 

    23.别问我是谁,请与我交配 

    24.好男人都有男朋友了 

    25.收银员说:没零钱了,找你两个塑料袋吧 

    26.我要让全世界知道我很低调~ 

    27.心里想的是“妈的”嘴上说的是“好的” 

    28.谁在催我成长,失去迷途的方向 

    29.别人都装处,我只好装经验丰富 

    30.搏一搏,单车变摩托 

    31.有情人终成圈猪 

    32.我看着饭岛爱的AV长大,去年她死了;我看杰克逊的MV长大,今年他也死了;现在,我决定看着CCTV长大…… 

    33.我是你转身就忘的路人甲,凭什么陪你蹉跎年华到天涯? 

    34.你永远是我的大姨妈 

    35.省油的灯绝不是好灯! 

    36.时间是最好的老师,但遗憾的是——最后他把所有的学生都弄死了。 

    37.对男人好不如勾引男人对自己好。。 

    38.这群不知道什么叫骨感的农民欣赏不了我空前绝后的美 

    39.我要努力去做一个高尚的人,一个纯粹的人,一个有道德的人,一个脱离了低级趣味的人,一个有益于人民的人。 

    40.当我不知道自己是否爱一个人时,我会假设自己爱,然后弄假成真,就这样,我成了佛,普爱众生。 



    ----------------------------------------------------------------------------- 



    41.有钱男子汉 没钱汉子难 

    42.“要有上班以外的生活”,于是有了加班 

    43.我正游走在无拘无束的自赏自省与自恋之间 

    44.bt bt就是b里面有个t 

    45.别和我谈理想,戒了...... 

    46.男人/女人何其贱,何必痴痴恋 这个怨念很深 

    47.只要你过得比我好~ 死得比我早.. 

    48.年轻有嘛了不起,你丫老过吗 

    49.不想当裁缝的厨子不是好司机 

    50.承诺就像“操你妈”,说得出做不到。 

    51.装比卖老,一刀放倒。 

    52.别跟姐说白头偕老,姐要永远黑发飘飘。 

    53.我们,不要去羡慕别人所拥有的幸福。你以为你没有的,可能在来的路上,你以为她拥有的,可能在去的途中 

    54.高中本來人就少 再説質量也不好 

    55.MM,你长得很像我下一任GF 

    56.信耶稣,死后成神;信如来,死后成佛;信春哥,死后满状态原地复活。 

    57.不舍,不得。 

    58.执子之手,方知子丑,泪流满面,你不走我走 

    59.他同我演戏,我回报以演技. 

    60.连老天爷也发烧了,38-40度,是不是H1N1啊………… 



    ----------------------------------------------------------------------------- 



    61.每次听到别人对自己说“我爱你” 我心里忍不住在后面加上“的…” 

    62.没有医保和寿险的,天黑后不要见义勇为…… 

    63.糟糕时模仿心情好,犹如烧焦的菜盛装打扮。 

    64.我又不是咸蛋超人。干吗为了你和全世界作战。 

    65.流氓会武术谁都挡不住,流氓有文化谁见都害怕 

    66.喝醉了我谁都不服,我就扶墙。 

    67.拿着卖白菜的钱,操着卖白粉的心 

    68.对,从事文艺这行工作的人们,一老师说评价工资待遇---- ( 吃不饱也饿不死 ) 

    69.我自是笑别人的,却原来当局者迷 。 

    70.如果不是看见发春的猫,我这个和尚都忘了些俗事 

    71.我说的你就信,你智商低呀! 

    72.曾经有个小女孩跑过来对我说,哥哥你真帅,我冲上去就是两巴掌.废话!!! 

    73.其实我是个天使 因为体重原因 我回不了天堂。。。 

    74.男人都是消耗品 

    75.生容易,活容易,生活真他妈的不容易 

    76.我就是你要的那颗糖果,有一天你会发现,除了我,再也没有别人,就算你再拆开多少糖果纸,永远也不会忘我 

    77.那是你惟一一次放我鸽子,一放就是一辈子。 

    78.他总是这样,一脚把你踩在尘埃里,还抱怨,你站的太低,我看不到你了。 

    79.也许你不算最美的女孩子,但你一定是最美好的女孩子。 

    80.放開那個少婦,我是警察 



    ----------------------------------------------------------------------------- 



    81.生前何必久睡,死后必定长眠! 

    82.有些人,你不当着他面操他妈他就不知道你是他爸 

    83.现在的男人都不像男人了,好不容易找到一个像男人的,还喜欢男人。 

    现在的女人都不像女人了,好不容易找到一个像女人的,还喜欢女人。 

    84.the love taught me to lie ,the life taught me to die(爱教会我撒谎,生活教会我死亡。) 

    85.撒尿靠压力,拉屎靠重力 

    86.但凡还有膀子力气。就去做自己想做的事。 

    87.对不起,我是个NPC 

    88.长大要嫁给唐僧玩腻了就把他吃掉 

    89.你喜欢我哪一点? 
    我喜欢你离我远一点!! 

    90.你不服吗,不服你就去吃老鼠药死掉啊 

    91.女为悦己者容 男为悦己者穷 

    92.两情若是长久时,又岂在猪猪肉肉```` 

    93.I am not young enough to know everything (我还没有年轻到什么都懂的地步。) 

    94.再过几十年就过去了 

    95.问 世 间 情 为 何 物 。 直 叫 人 月兑 衣 月兑 裤 

    96.一见钟情,再而衰,三而竭。 

    97.若你转身牵我手,天涯海角也岁你走。 

    98.不要在你发现你自己丑时才觉得你真的很丑 

    99.某女事后踢掉被子说:来世我也要当一个大苦瓜,让吃我的人都尝尝我的苦 

    100.理想很丰满,现实很骨感。 

    ----------------------------------分割线----------------------------------------- 



    101.此人已死,有事烧纸。小事招魂,大事挖坟~ 

    102.记得当时年纪小 你是傻逼我也要 

    103.我以后生个女儿就叫美丽,别人见到我都叫美丽的妈妈 

    104.没有拆不散的情侣,只有不努力的小三 ;反过来,没有赶不走的小三,只有不努力的正牌~ 

    105.马桶一定要刷得铮铮发亮,才能心安理得地享受如厕的快感 

    106.你看我的头像牛B吗? 断句: 你看我的头,像牛B吗? 

    107.微裝淡裝素裝不及不裝還裝死裝 

    108.你变个影分身,我们玩3P吧 

    109.既宅又腐,前途未卜~ 

    110.天都爱我 何况是你 

    111.燃烧吧~阴毛~( 

    112.你才非主流 你们全家非主流 你妈黑袜子 你爸锡纸头 

    113.学海无涯 回头是岸 


    114.敏感的人,都是很自尊与很自傲的,同时也有着自卑的情结。 

    115.人生就是学会怎么去死 

    116.我的每一次飞机都是为你打的 (豆瓣名人~! 

    117.花前月下 不如花钱日下 

    118.谈钱伤感情 谈感情伤钱 

    119.如果我不在装逼,就在装逼的路上。 

    120.我曾经泪流满面地嘶吼着自己将再也不会为一个女人流泪,结果换来母亲的一顿毒打——那年我8岁。。。 



    ----------------------------------------------------------------------------- 



    121.你想发财吗?你想交桃花运吗?你想当官吗?你想一夜成名吗?你想永葆青春吗?————不要瞎想了,好好工作吧! 

    122.这年头,情侣一多,黄瓜就不好卖了... 

    123.好好学习,天天想上 

    124.故作坚强是因为你其实比谁都软弱 你是那么不愿意去承认这一点。 

    125.等待你的关心 等到我关上了心 

    126.拿你当人的时候,你尽量走人道好吗。。 

    127.爱,从我们开始那天,已经偷偷倒数计时。。。。 

    128.手拿菜刀砍电线,一路火花带闪电。 

    129.与其相濡以沫,不如相忘于江湖~ 

    130.恋爱的“恋”就是,变态的“变”的上半部分加上变态的“态”的下半部分 

    131.有时候装逼比卖逼更可耻! 

    132.我纯洁的一刻,胜于你一世谎言。 

    133.傻逼就像南方的农作物,一年三熟,都不带歇气儿的 

    134.我们什么都做不了,也什么都不想做。 
    我们哪里都去不了,也哪里都不想去。 

    不相信努力就会有结果,因为懒得去努力。 
    不相信出门就有好天气,因为家里不下雨。 

    大家都以为我们在思考,其实我们在发呆。 
    大家都以为我们有内涵,其实我们是废柴 



    135.尘归尘,土归土,挥手告别二百五 

    136.你肺活量是多少啊,能把牛逼吹得这么大 

    137.一个人要令另一个人讨厌不是难事,能让所有的人都讨厌也是一种本事。 

    138.请不要把我对你的容忍,当成你不要脸的资本。 

    139.我那么喜欢你,你喜欢我一下会死啊。 

    140.时间对了,地点对了,感情对了,却发现人物不对!!! 

    ----------------------------------------------------------------------------- 



    141.差点是美女/帅哥…… 

    142.肉是疯长的东西,胸是瘪下去的东西 

    143.给我一个女人,我能创造一个兽族。 

    144.我允许你走进我的世界,但不许你在我的世界里走来走去 

    145.人哪有好的`只是坏的程度不一样而已 好腹黑 

    146.有什么不开心的 说出来让大家开心开心 

    147.胸有激雷而面如平湖者可拜上将军 

    148.那些都是很好很好的,只是我不喜欢 

    149.白领:今天领了薪水,交了房租水电,买了油米泡面,摸了口袋,感叹一声,这个月工资又白领了… 

    150.一夜醒来 装清纯 

    151.幸福是什麽?幸福是我吃魚你吃肉,看著别人啃骨頭。 

    152.她像根天线,她太美了。。。 

    153.都说男人有钱就变坏,tmd我都当了二十多年的好人了! 

    154.有的人对你好,是因为你对他好, 有的人对你好,是因为懂得你的好 

    155.把钻石留下,王老五带走~ 

    156.你在不理我,我就成包子了,而且是天津最出名的那个 

    157.什么是残忍? 对男人,我就打断他三条腿。 对公狗,我就打断它五条腿。 

    158.好男人就是反复睡一个姑娘,一睡就是一辈子。 

    159.问世间情为何物,只教人吃饭想吐 

    160.马不停蹄的错过,轻而易举的辜负,不知不觉的陌路 

    ----------------------------------------------------------------------------- 



    161.通往牛逼的路上,你能一路勃起吗? 

    162.总有一天你的名字会出现在我家户口簿上。 

    163.别以为我长的帅就认为我遥不可及高不可攀,其实我是海纳百川啊. 

    164.昨个看到一句特逗 说酒井法子没有失踪 她就在我的c盘 d盘 f盘... 

    165.我必须学会新的卖弄啊 这样你们才会继续的喜欢我~~~ 

    166.以后只要你一挥手,我就是傻逼青年壮劳力,哪里需要哪里去! 

    167.看在愚蠢的分上 就不说你什么了 

    168.你也算是变态界的一朵奇葩 

    169.我今天心情不好 只想讲四句话 包括前两句 我的话讲完了 

    170.脱了衣服我是禽兽,穿上衣服我是衣冠禽兽 

    171.只要目光笔直 不怕眼眶涨热 

    172.欺骗一个人的最好办法,就是利用自己的真感情,也许不是我遗忘了,只是我不原意想起而已 

    173.流氓,是一种气质;老流氓,是一种信仰。 

    174.嘛时候凹凸曼才能被我打倒啊?! 

    175.你对我很重要,你是我心目中考试用的标准铅笔 

    176.心情不好的時候去超市捏方便麵·· 

    177.又到了这个学长勾引学妹,学妹勾搭学长,学姐垂涎学弟,学弟攀附学姐,学姐嫉妒学妹,学妹憎恨学姐,学长抛弃学姐,学姐报复学长,学长欺瞒学弟,学弟巴结学长,学弟追求学妹,学妹拒绝学弟的季节… 

    178.上班时间请勿打扰,下班时间敬请骚扰。 

    179.你个双料婊子养的两条腿小畜生 

    180.让您贱笑了 

    ----------------------------------------------------------------------------- 


    181.我是你的过客 ,你是我的定格 

    182.孔子曰 中午不睡下午崩溃 孟子曰 孔子说的对 

    183.喜好文艺,想要流浪,路过爱情,解放感情,沉迷音乐,动情电影,繁画图片,念与文字,坚强行动,就爱不靠谱 

    184.小螺号瞎JB吹 海鸥跟着瞎JB飞 

    185.闷骚就是自己对自己放荡 

    186.成不了楷模 当个凯子也是可以的 

    187.爷爷都是从孙子走过来的 

    188.除了诱惑 有什么我抵挡不了的 

    189.床 钱 明月 光 ,衣 失 地上 爽 

    190.我真想亲口管你爷爷叫声爹 

    191.一觉醒来 天都黑了 

    192.你爸妈要是把那十分钟用来散步多好 

    193.男人的话就像老太太的牙齿 有多少是真的 

    194.男人勃(河蟹)起的时候是没有道德可言的 

    195.生活就是不择手段的活着 

    196.师太 你是我心中的魔 我离你越近 就离佛越远 

    197.你来我信你不会走,你走我当你没来过 

    198.我想我是太久没吃鸡了,昨晚看见鸡毛掸子,居然有点激动。。。。。 

    199.别人看我是荒谬 我看自己是绝伦 

    200.脑壳多了 啥子发型都有 

  • 南非世界杯预测

    又四年了... 说明这个blog已经开了四年了...啥都别说,先看我预测.

     

  • Oracle 语法之 OVER (PARTITION BY ..) 及开窗函数 转载

    oracle的分析函数over 及开窗函数
    一:分析函数over
    Oracle从8.1.6开始提供分析函数,分析函数用于计算基于组的某种聚合值,它和聚合函数的不同之处是
    对于每个组返回多行,而聚合函数对于每个组只返回一行。
    下面通过几个例子来说明其应用。                                       
    1:统计某商店的营业额。        
         date       sale
         1           20
         2           15
         3           14
         4           18
         5           30
        规则:按天统计:每天都统计前面几天的总额
        得到的结果:
        DATE   SALE       SUM
        ----- -------- ------
        1      20        20           --1天           
        2      15        35           --1天+2天           
        3      14        49           --1天+2天+3天           
        4      18        67            .          
        5      30        97            .
         
    2:统计各班成绩第一名的同学信息
        NAME   CLASS S                         
        ----- ----- ----------------------
        fda    1      80                     
        ffd    1      78                     
        dss    1      95                     
        cfe    2      74                     
        gds    2      92                     
        gf     3      99                     
        ddd    3      99                     
        adf    3      45                     
        asdf   3      55                     
        3dd    3      78              
       
        通过:   
        --
        select * from                                                                       
        (                                                                            
        select name,class,s,rank()over(partition by class order by s desc) mm from t2
        )                                                                            
        where mm=1
        --
        得到结果:
        NAME   CLASS S                       MM                                                                                        
        ----- ----- ---------------------- ----------------------
        dss    1      95                      1                      
        gds    2      92                      1                      
        gf     3      99                      1                      
        ddd    3      99                      1          
       
        注意:
        1.在求第一名成绩的时候,不能用row_number(),因为如果同班有两个并列第一,row_number()只返回一个结果          
        2.rank()和dense_rank()的区别是:
          --rank()是跳跃排序,有两个第二名时接下来就是第四名
          --dense_rank()l是连续排序,有两个第二名时仍然跟着第三名
         
         
    3.分类统计 (并显示信息)
        A   B   C                      
        -- -- ----------------------
        m   a   2                      
        n   a   3                      
        m   a   2                      
        n   b   2                      
        n   b   1                      
        x   b   3                      
        x   b   2                      
        x   b   4                      
        h   b   3
       select a,c,sum(c)over(partition by a) from t2                
       得到结果:
       A   B   C        SUM(C)OVER(PARTITIONBYA)      
       -- -- ------- ------------------------
       h   b   3        3                        
       m   a   2        4                        
       m   a   2        4                        
       n   a   3        6                        
       n   b   2        6                        
       n   b   1        6                        
       x   b   3        9                        
       x   b   2        9                        
       x   b   4        9                        
      
       如果用sum,group by 则只能得到
       A   SUM(C)                            
       -- ----------------------
       h   3                      
       m   4                      
       n   6                      
       x   9                      
       无法得到B列值       
      
    =====

    select * from test

    数据:
    A B C
    1 1 1
    1 2 2
    1 3 3
    2 2 5
    3 4 6


    ---将B栏位值相同的对应的C 栏位值加总
    select a,b,c, SUM(C) OVER (PARTITION BY B) C_Sum
    from test

    A B C C_SUM
    1 1 1 1
    1 2 2 7
    2 2 5 7
    1 3 3 3
    3 4 6 6



    ---如果不需要已某个栏位的值分割,那就要用 null

    eg: 就是将C的栏位值summary 放在每行后面

    select a,b,c, SUM(C) OVER (PARTITION BY null) C_Sum
    from test

    A B C C_SUM
    1 1 1 17
    1 2 2 17
    1 3 3 17
    2 2 5 17
    3 4 6 17

     

    求个人工资占部门工资的百分比

    SQL> select * from salary;

    NAME DEPT SAL
    ---------- ---- -----
    a 10 2000
    b 10 3000
    c 10 5000
    d 20 4000

    SQL> select name,dept,sal,sal*100/sum(sal) over(partition by dept) percent from salary;

    NAME DEPT SAL PERCENT
    ---------- ---- ----- ----------
    a 10 2000 20
    b 10 3000 30
    c 10 5000 50
    d 20 4000 100

    二:开窗函数           
          开窗函数指定了分析函数工作的数据窗口大小,这个数据窗口大小可能会随着行的变化而变化,举例如下:
    1:     
       over(order by salary) 按照salary排序进行累计,order by是个默认的开窗函数
       over(partition by deptno)按照部门分区
    2:
      over(order by salary range between 5 preceding and 5 following)
       每行对应的数据窗口是之前行幅度值不超过5,之后行幅度值不超过5
       例如:对于以下列
         aa
         1
         2
         2
         2
         3
         4
         5
         6
         7
         9
       
       sum(aa)over(order by aa range between 2 preceding and 2 following)
       得出的结果是
                AA                       SUM
                ---------------------- -------------------------------------------------------
                1                       10                                                      
                2                       14                                                      
                2                       14                                                      
                2                       14                                                      
                3                       18                                                      
                4                       18                                                      
                5                       22                                                      
                6                       18                                                                
                7                       22                                                                
                9                       9                                                                 
                 
       就是说,对于aa=5的一行 ,sum为   5-1<=aa<=5+2 的和
       对于aa=2来说 ,sum=1+2+2+2+3+4=14     ;
       又如 对于aa=9 ,9-1<=aa<=9+2 只有9一个数,所以sum=9    ;
                  
    3:其它:
         over(order by salary rows between 2 preceding and 4 following)
              每行对应的数据窗口是之前2行,之后4行
    4:下面三条语句等效:           
         over(order by salary rows between unbounded preceding and unbounded following)
              每行对应的数据窗口是从第一行到最后一行,等效:
         over(order by salary range between unbounded preceding and unbounded following)
               等效
         over(partition by null)
  • 橡皮鸭程序调试法

    下面,让我来为你介绍一个程序调试大法——“橡皮鸭程序调试法”,这个方法在调试界是很出众的,实施起来相当方便和简易,几乎可以随时随地地实验,几乎不需要借助任何的软件和硬件的支持,你甚至可以把你的程序打印出来,在纸面上进行调试。

    那么,为什么这个方法要叫做橡皮鸭呢?因为橡皮鸭子是西方人在泡澡时最喜欢玩的一个小玩具,所以,这个东西应该家家户户都必备的。因为,这个方法由西方人发明,所以,就被取名为“橡皮鸭”了。

    好了,话不多说,下面是整个调试方法的流程。

    1. 找一个橡皮鸭子。你可以去借,去偷,去抢,去买,自己制作……反正你要搞到一个橡皮鸭子。 Rubber Duck
    2. 把这个橡皮鸭子放在你跟前。标准做法是放在你的桌子上,电脑显示器边,或是键盘边,反正是你的跟前,面朝你。
    3. 然后,打开你的源代码。不管是电脑里的还是打印出来的。
    4. 对着那只橡皮鸭子,把你写下的所有代码,一行一行地,精心地,向这只橡皮鸭子解释清楚。记住,这是解释,你需要解释出你的想法,思路,观点。不然,那只能算是表述,而不是解释。
    5. 当你在向这只始终保持沉默的橡皮鸭子解释的过程中,你会发现你的想法,观点,或思路和实际的代码相偏离了,于是你也就找到了代码中的bug。
    6. 找到了BUG,一定要记得感谢一下那个橡皮鸭子哦。

    什么?你觉得这个方法太“愚蠢”,太“弱智”了?是的,看上去,会这样做的人脑子好像是有点毛病。不过,我要告诉你的是,这个方法的确有效。因为,这就是“Code Review”的雏形!下面让我来给你解释一下。

    Once a problem is described in sufficient detail, its solution is obvious.

    上面这句话的意思是

    一旦一个问题被充分地描述了他的细节,那么解决方法也是显而易见的。

    我相信在座的各位都有过这样的经历,当你死活都找不到问题的原因的时候,当你寻求他人的帮助时,对别人解释整个你的想法和意图或是问题背景的时候,你自己都没有解释完,就已经找到问题的原因了。这样的经历,相信大家一定有过。这就是这个方法的意义所在。

    所以,“橡皮鸭”只是一个形式,其主要目的是要你把自己写的代码做“自查”,也就是自己解释给自己听。当然,为了不让你像个“精神分裂”的程序员,引入“橡皮鸭”是很有必要的(虽然这样还是有点精神病,但比起精神分裂来说算是好的了,嘻嘻)。所以,真实的本质是Code Review。关于代码评审,大家可以看一下我的这篇文章《Code Review中的几个提示》,你会明白其中更多的东西的。

    最后,我想和大家说一下道具“橡皮鸭”。是的,在我们的身边,你不一定能找得“橡皮鸭”,但你可以找到你你的同事,你的朋友,来做这个“橡皮鸭”,当然,他们并不一定有“橡皮鸭”好使,因为你的那些同事或朋友一定会在你解释的时候,随意地发表意见和看法,相当的令人annoying。《Code Review中的几个提示》和《结对编程的利与弊》也谈到了一些,供你借鉴。

    (全文完)

  • [推荐]程序员是不是只在乎自己的一亩三分地

    其实想说这句话很久了,和很多同事接触,有时候或多或少的都会发现大家会陷入在自己的一亩三分地里面.

    主要表现得症状

    1.PD(产品设计师 Product designer)的需求就是目标,踏实的实现,不懂的就猜。

    2.经验盖过一切,设计系统就是要够完备够复杂。

    从开发人员角度来看,第一种人多半比较有自己的想法,同时也有不少的工作经验,同时可能对技术比较着迷。另一种人多半是刚刚工作或者经验不足,要么就是习惯性把工作当任务,而不是爱好,写程序也就是一份赚钱的活。但看起来其实各自都在自己的一亩三分地上捣鼓,忘记了作为一个开发人员最基本的原则:“满足客户需求”。

    先说1类型吧,在我们的Team有一个刚毕业一年多的同学,很勤奋,不论从学习以及工作,实实在在,踏踏实实。我们这边来需求,通常大需求我们都会全体过一下,一些小点的需求他就自己考虑一下就作了。那天正要上线,突然说了一下设计修改的内容,发现不仅满足不了PD原有的需求,而且给系统带来了缓存暴增的隐患。然后找来PD一谈,其实他要的功能已经在现有系统中已经实现,只是需要做部分的修改,而不需要新的去建立一套机制。这样的情况其实在前前后后出现了不少次数了,但其实一直没有和他细谈。后来我下班时候和他一起回家的时候说:“很多时候, PD为了让你理解,从开发的角度想要去描述一个需求,但其实最终失去了他自己想要的东西。因此对你来说第一步不是急忙的去考虑如何实现PD的想法或者和他争论他的设计是否合理,而是需要先问他:你想要什么,想要实现的东西最终目的是什么,能满足客户的什么需求?当他能够说清楚他想要什么,也知道要的东西能给客户带来什么价值的时候,我们再回过头来看,究竟应该怎么做?”这其实和我每次和同学分享一些设计的时候步骤是一样的,首先为什么要这么做,然后才是考虑如何从我的目标去寻找行动的方法方式,不然你会发现你和别人讨论了许久的东西,实现出来的时候已经背离了你的目标很远。因此在做任何需求或者设计的时候第一个问题就要问自己为什么要做,作的过程中时刻要记得我的目标是什么。这让我想起了我在离开阿软的那些日子和王坚博士谈话以及听他的一些对于设计的理念,很多时候还没有到规模化的情况下,先解决客户的需求,在解决客户需求以后,逐步的去考虑规模化问题的设计。(当然不是说第一版设计就可以随便作,良好的基础能够提升后续改进的速度)。

    二类型的就比较多了,其实是很多开发人员的通病,包括有时候我自己也会陷入这样的误区。通常情况下有两种场景会陷入这样的误区,同时当事人却又不愿意改变。第一种情况就是觉得自己有不少的经验,同时对技术很执着,希望设计出来的都是很完美的,一次发布就可以满足个1,2年,但其实从这些年的设计角度来看,首先系统都是不断迭代进化的,因此一步到位的说法基本上不靠谱(除非就是一模一样的场景代码重复使用),其次系统的架构要做的足够灵活,通常情况就需要先做核心功能,预留出足够的空间和切入点,这样对未来扩展和需求变化有足够的适应度。从这两点来看,其实设计初期就是要求找到客户最想要的,扩展可以实现客户可能要的,防范客户没有估量到的。但这其实就需要和我们的产品设计师有充分的交流,好的产品设计师不会告诉你你怎么去实现,但是他会告诉你我想要的是什么,这些能给客户带来什么,这时候你可以告诉他我能够通过什么方式来满足你的需求。这样的开发和产品设计交流的结果才是技术化的产品,大家各司其职,同时也通晓对方领域的一些情况,对对方领域的只能给出建议,不是指导,这点在TOP我很庆幸有很好的黑羽同学,我们的交流就是这样产生良性互动。这有点撤远了,刚才说了第一种场景,然后说说第二种场景,就是初期其实大家都没有明确细节,但是在实施过程中开发人员会根据自己的接触面来选择一些技术和架构设计,最后看起来很复杂,很完美,但其实越是复杂的设计背后有越多的隐患。但是此时因为已经设计好了,就不愿意再去简化,也不愿意听任何人的意见,其实这是很危险的。我过去也犯过类似的错误,但是其实当你冷静下来,想想那句话,我们的目标是什么:“满足客户需求”,这时候你就会考虑,这么复杂的系统会不会给客户带来更多的不稳定以及复杂度,其实客户不关心你背后如何实现的,但是你需要满足客户的最基本的需求,用起来方便,高效,实实在在提供了解决问题的手段。

    今天下午面试了一个外部的同学,工作年限比我长,看了简历也经历了很多项目,同时在描述的时候写了对高并发,分布式等等都很熟悉和热衷,我开始看了简历就担心,可能我这边不一定要他,因为我怕他开口就是说一大堆如何做高并发和分布式的内容。在我看来如果你没有搞清楚你什么时候要用牛刀,什么时候要用剪刀的人,和你谈论牛刀的构造其实没啥意思,因为在我看来,技术只要你肯花时间去学,没什么学不到的,但是做事方式和项目设计经验却是长时间积累的。幸好今天和他一谈,他对于技术的态度以及架构设计的思想都和我想的比较接近,不是为了技术而技术,不是为了过程而过程,了解如何从简如繁,再从繁入简,最终能够找到自己的目标。当然后来还是谈了很多技术细节的问题,毕竟干活还是要一个好手,作了那么多年如果没有经验和技术积累也是很可怕的事情。最后我问了他两个问题:1.你学习一个新技术的过程是怎么样的?2.你和你同事如果在设计方案上有冲突你怎么解决?他告诉我他学习新技术首先会去考虑这个技术的特点是什么,和其他技术的差别,他的擅长领域是什么,这样才能够用到实处。第二个问题他和我说就是开会讨论,最后大家群体决定。我对他第一个问题感到很满意,因为我就需要这样的同事,第二个问题我给了他一个建议,其实在很多时候,将别人的架构设计的优点融入到自己的设计中,不再以方案作为边界,那么大家最终就很容易达成一致,因为你在接受别人的思想时其实能够看到自己的不足,同时对待别人不是用否定的态度,会让你更容易得到认可和接受。(这点作起来需要不断的改变程序员自身的好胜个性,我起码还是出于变化中…)

    我记得我小时候上政治课的时候,老师给我们划分了三种人:有能力但是没有道德的人是危险的人,没有能力但是有道德的人是对社会无害的人(觉得像葛优说的那个对社会无害的海龟一个概念),有能力同时也有道德的人是对社会有益的人。我觉得其实程序员也就可以从两个纬度看:

    1.      有能力,有经验,对技术有追求。

    2.      对产品化和客户没有任何感觉。

    拥有了素质1但是没有素质2,那么最多也就只能说是试验室的花朵,在大学搞搞研究还不错,实际要做出产品来可能就是纸上谈兵,好钢始终用不到刀刃上,有力没地使。

    素质1有所欠缺,素质2很明晰,对自己目标不断追求,其实这样的人,有时候笨鸟也会飞的比聪明的鸟更高。

    拥有1,2的人,当然就是最好的人,只需要学会做人那么就可以发挥自己的能量。(程序员有时候就是很难改变自己的个性,去学会如何沟通和理解)
           
    最后一类就是自以为有1和2的人,这类人最怕就是面试的时候被考官通过,那么后续的问题就大了。

    说了怎么多,其实也无非想说出一个程序员这些年的经历,从做开发到做基础平台,到做业务平台,该怎么踏实做事,该在什么时候找到自己的瓶颈,该在什么时候改变自己的状态,都需要自己好好的让自己冷静下来想想。做基础平台需要耐得住寂寞,同时也要知道自己是有客户的,服务不好客户,那么基础组件平台就是玩具。做业务平台需要学会去分析和沟通,需要去了解每一个层次的设计如何协作,同时在兼顾业务需求的同时满足隐性需求(稳定性,可用性,响应速度,规模化等等)。但归根到底,能给开发人员不断能量的不是技术本身,而是你用技术给你的客户带来的价值,对你的认可是长期做事的一个最基本的动力,因为当你现在觉得纯做技术能够支持你不断向前走的时候,其实在不远的将来你会体会到原来过程和目标是同样重要的。走出自己的一亩三分地,给自己多一点的空间,会让自己看得更远,走的更高。

  • JavaScript多线程编程

    AJAX 开发中的难题

    让我们通过一个简单的例子来认识这个问题。假设你要建立一个树形结构的公告栏系统(BBS),它可以根据用户请求与服务器进行交互,动态加载每篇文章的信息,而不是一次性从服务器载入所有文章信息。每篇文章有四个相关属性:系统中可以作为唯一标识的ID、发贴人姓名、文章内容以及包含其所有子文章ID的数组信息。首先假定有一个名为getArticle()的函数可以加载一篇文章信息。该函数接收的参数是要加载文章的ID,通过它可从服务器获取文章信息。它返回的对象包含与文章相关的四条属性:id,name,content和children。例程如下:

    function ( id ) {
         var a = getArticle(id);
         document.writeln(a.name + "
    " + a.content);
     } 

    然而你也许会注意到,重复用同一个文章ID调用此函数,需要与服务器之间进行反复且无益的通信。想要解决这个问题,可以考虑使用函数 getArticleWithCache(),它相当于一个带有缓存能力的getArticle()。在这个例子中,getArticle()返回的数据只是作为一个全局变量被保存下来:

    var cache = {};
     function getArticleWithCache ( id ) {
         if ( !cache[id] ) {
             cache[id] = getArticle(id);
         }
         return cache[id];
     } 

    现在已将读入的文章缓存起来,让我们再来考虑一下函数backgroundLoad(),它应用我们上面提到的缓存机制加载所有文章信息。其用途是,当读者在阅读某篇文章时,从后台预加载它所有子文章。因为文章数据是树状结构的,所以很容易写一个递归的算法来遍历树并且加载所有的文章:

    function backgroundLoad ( ids ) {
         for ( var i=0; i < ids.length; i++ ) {
             var a = getArticleWithCache(idsIdea);
             backgroundLoad(a.children);
         }
     } 

    backgroundLoad ()函数接收一个ID数组作为参数,然后通过每个ID调用前面定义过的getArticldWithCache()方法,这样就把每个ID对应的文章缓存起来。之后再通过已加载文章的子文章ID数组递归调用backgroundLoad()方法,如此整个文章树就被缓存起来。

    到目前为止,一切似乎看起来都很完美。然而,只要你有过开发AJAX应用的经验,你就应该知晓这种幼稚的实现方法根本不会成功,这个例子成立的基础是默认 getArticle()用的是同步通信。可是,作为一条基本原则,JavaScript要求在与服务器进行交互时要用异步通信,因为它是单线程的。就简单性而言,把每一件事情(包括GUI事件和渲染)都放在一个线程里来处理是一个很好的程序模型,因为这样就无需再考虑线程同步这些复杂问题。另一方面,他也暴露了应用开发中的一个严重问题,单线程环境看起来对用户请求响应迅速,但是当线程忙于处理其它事情时(比如说调用getArticle()),就不能对用户的鼠标点击和键盘操作做出响应。

    如果在这个单线程环境里进行同步通信会发生什么事情呢?同步通信会中断浏览器的执行直至获得通信结果。在等待通信结果的过程中,由于服务器的调用还没有完成,线程会停止响应用户并保持锁定状态直到调用返回。因为这个原因,当浏览器在等待服务器响应时它不能对用户行为作出响应,所以看起来像是冻结了。当执行 getArticleWithCache()和backgroundLoad()会有同样的问题,因为它们都是基于getArticle()函数的。由于下载所有的文章可能会耗费很可观的一段时间,因此对于backgroundLoad()函数来说,浏览器在此段时间内的冻结就是一个很严重的问题——既然浏览器都已经冻结,当用户正在阅读文章时就不可能首先去执行后台预加载数据,如果这样做连当前的文章都没办法读。

    如上所述,既然同步通信在使用中会造成如此严重的问题,JavaScript就把异步通信作为一条基本原则。因此,我们可以基于异步通信改写上面的程序。 JavaScript要求以一种事件驱动的程序设计方式来写异步通信程序。在很多场合中,你都必须指定一个回调程序,一旦收到通信响应,这个函数就会被调用。例如,上面定义的getArticleWithCache()可以写成这样:

    var cache = {};
     function getArticleWithCache ( id, callback ) {
         if ( !cache[id] ) {
             callback(cache[id]);
         } else {
             getArticle(id, function( a ){
                 cache[id] = a;
                 callback(a);
             });
         }
     } 

    这个程序也在内部调用了getArticle()函数。然而需要注意的是,为异步通信设计的这版getArticle()函数要接收一个函数作为第二个参数。当调用这个getArticle()函数时,与从前一样要给服务器发送一个请求,不同的是,现在函数会迅速返回而非等待服务器的响应。这意味着,当执行权交回给调用程序时,还没有得到服务器的响应。如此一来,线程就可以去执行其它任务直至获得服务器响应,并在此时调用回调函数。一旦得到服务器响应, getArticle()的第二个参数作为预先定义的回调函数就要被调用,服务器的返回值即为其参数。同样的,getArticleWithCache ()也要做些改变,定义一个回调参数作为其第二个参数。这个回调函数将在被传给getArticle()的回调函数中调用,因而它可以在服务器通信结束后被执行。

    单是上面这些改动你可能已经认为相当复杂了,但是对backgroundLoad()函数做得改动将会更复杂,它也要被改写成可以处理回调函数的形式:

    function backgroundLoad ( ids, callback ) {
         var i = 0;
         function l ( ) {
             if ( i < ids.length ) {
                 getArticleWithCache(ids[i++], function( a ){
                     backgroundLoad(a.children, l);
                 });
             } else {
                 callback();
             }
         }
         l();
     } 

    改动后的backgroundLoad()函数看上去和我们以前的那个函数已经相去甚远,不过他们所实现的功能并无二致。这意味着这两个函数都接受ID数组作为参数,对于数组里的每个元素都要调用getArticleWithCache(),再应用已经获得子文章ID递归调用backgroundLoad ()。不过同样是对数组的循环访问,新函数中的就不太好辨认了,以前的程序中是用一个for循环语句完成的。为什么实现同样功能的两套函数是如此的大相径庭呢?

    这个差异源于一个事实:任何函数在遇到有需要同服务器进行通信情况后,都必须立刻返回,例如getArticleWithCache()。除非原来的函数不在执行当中,否则应当接受服务器响应的回调函数都不能被调用。对于JavaScript,在循环过程中中断程序并在稍后从这个断点继续开始执行程序是不可能的,例如一个for语句。因此,本例利用递归传递回调函数实现循环结构而非一个传统循环语句。对那些熟悉连续传送风格(CPS)的人来说,这就是一个 CPS的手动实现,因为不能使用循环语法,所以即便如前面提到的遍历树那么简单的程序也得写得很复杂。与事件驱动程序设计相关的问题是控制流问题:循环和其它控制流表达式可能比较难理解。

    这里还有另外一个问题:如果你把一个没有应用异步通信的函数转换为一个使用异步通信的函数,那么重写的函数将需要一个回调函数作为新增参数,这为已经存在的APIs造成了很大问题,因为内在的改变没有把影响限于内部,而是导致整体混乱的APIs以及API的其它使用者的改变。

    造成这些问题目的根本原因是什么呢?没错,正是JavaScript单线程机制导致了这些问题。在单线程里执行异步通信需要事件驱动程序设计和复杂的语句。如果当程序在等待服务器的响应时,有另外一个线程可以来处理用户请求,那么上述复杂技术就不需要了。

    试试多线程编程

    让我来介绍一下Concurrent.Thread,它是一个允许JavaScript进行多线程编程的库,应用它可以大大缓解上文提及的在AJAX开发中与异步通信相关的困难。这是一个用JavaScript写成的免费的软件库,使用它的前提是遵守Mozilla Public License和GNU General Public License这两个协议。你可以从他们的网站 下载源代码。

    马上来下载和使用源码吧!假定你已经将下载的源码保存到一个名为Concurrent.Thread.js的文件夹里,在进行任何操作之前,先运行如下程序,这是一个很简单的功能实现:

    <script type="text/javascript" src="Concurrent.Thread.js"></script>
     <script type="text/javascript">
         Concurrent.Thread.create(function(){
             var i = 0;
             while ( 1 ) {
                 document.body.innerHTML += i++ + "<br>";
             }
         });
     </script>

    执行这个程序将会顺序显示从0开始的数字,它们一个接一个出现,你可以滚屏来看它。现在让我们来仔细研究一下代码,他应用while(1)条件制造了一个不会中止的循环,通常情况下,象这样不断使用一个并且是唯一一个线程的JavaScript程序会导致浏览器看起来象冻结了一样,自然也就不会允许你滚屏。那么为什么上面的这段程序允许你这么做呢?关键之处在于while(1)上面的那条Concurrent.Thread.create()语句,这是这个库提供的一个方法,它可以创建一个新线程。被当做参数传入的函数在这个新线程里执行,让我们对程序做如下微调:

    <script type="text/javascript" src="Concurrent.Thread.js"></script>
     <script type="text/javascript">
         function f ( i ){
             while ( 1 ) {
                 document.body.innerHTML += i++ + "<br>";
             }
         }
         Concurrent.Thread.create(f, 0);
         Concurrent.Thread.create(f, 100000);
     </script> 

    在这个程序里有个新函数f()可以重复显示数字,它是在程序段起始定义的,接着以f()为参数调用了两次create()方法,传给create()方法的第二个参数将会不加修改地传给f()。执行这个程序,先会看到一些从0开始的小数,接着是一些从100,000开始的大数,然后又是接着前面小数顺序的数字。你可以观察到程序在交替显示小数和大数,这说明两个线程在同时运行。

    让我来展示Concurrent.Thread的另外一个用法。上面的例子调用create()方法来创建新线程。不调用库里的任何APIs也有可能实现这个目的。例如,前面那个例子可以这样写:

    <script type="text/javascript" src="Concurrent.Thread.js"></script>
     <script type="text/x-script.multithreaded-js">
         var i = 1;
         while ( 1 ) {
             document.body.innerHTML += i++ + "<br>";
         }
     </script> 

    在script 标签内,很简单地用JavaScript写了一个无穷循环。你应该注意到标签内的type属性,那里是一个很陌生的值(text/x- script.multithreaded-js),如果这个属性被放在script标签内,那么Concurrent.Thread就会在一个新的线程内执行标签之间的程序。你应当记住一点,在本例一样,必须将Concurrent.Thread库包含进来。

    有了Concurrent.Thread,就有可能自如的将执行环境在线程之间进行切换,即使你的程序很长、连续性很强。我们可以简要地讨论下如何执行这种操作。简言之,需要进行代码转换。粗略地讲,首先要把传递给create()的函数转换成一个字符串,接着改写直至它可以被分批分次执行。然后这些程序可以依照调度程序逐步执行。调度程序负责协调多线程,换句话说,它可以在适当的时候做出调整以便每一个修改后的函数都会得到同等机会运行。 Concurrent.Thread实际上并没有创建新的线程,仅仅是在原本单线程的基础上模拟了一个多线程环境。

    虽然转换后的函数看起来是运行在不同的线程内,但是实际上只有一个线程在做这所有的事情。在转换后的函数内执行同步通信仍然会造成浏览器冻结,你也许会认为以前的那些问题根本就没有解决。不过你不必耽心,Concurrent.Thread提供了一个应用JavaScript 的异步通信方式实现的定制通信库,它被设计成当一个线程在等待服务器的响应时允许其它线程运行。这个通信库存于 Concurrent.Thread.Http下。它的用法如下所示:

    <script type="text/javascript" src="Concurrent.Thread.js"></script>
     <script type="text/x-script.multithreaded-js">
         var req = Concurrent.Thread.Http.get(url, ["Accept", "*"]);
         if (req.status == 200) {
             alert(req.responseText);
         } else {
             alert(req.statusText);
         }
     </script> 

    get()方法,就像它的名字暗示的那样,可以通过HTTP的GET方法获得指定URL的内容,它将目标URL作为第一个参数,将一个代表HTTP请求头的数组作为可选的第二个参数。get()方法与服务器交互,当得到服务器的响应后就返回一个XMLHttpRequest对象作为返回值。当get()方法返回时,已经收到了服务器响应,所以就没必要再用回调函数接收结果。自然,也不必再耽心当程序等待服务器的响应时浏览器冻结的情况了。另外,还有一个 post()方法可以用来发送数据到服务器:

    <script type="text/javascript" src="Concurrent.Thread.js"></script>
     <script type="text/x-script.multithreaded-js">
         var req = Concurrent.Thread.Http.post(url, "key1=val1&key2=val2");
         alert(req.statusText);
     </script> 

    post()方法将目的URL作为第一个参数,要发送的内容作为第二个参数。像get()方法那样,你也可以将请求头作为可选的第三个参数。

    如果你用这个通信库实现了第一个例子当中的getArticle()方法,那么你很快就能应用文章开头示例的那种简单的方法写出getArticleWithCache(),backgroundLoad ()以及其它调用了getArticle()方法的函数了。即使是那版backgroundLoad()正在读文章数据,照例还有另外一个线程可以对用户请求做出响应,浏览器因此也不会冻结。现在,你能理解在JavaScript中应用多线程有多实用了?

    想了解更多

    我向你介绍了一个可以在JavaScript中应用多线程的库:Concurrent.Thread。这篇文章的内容只是很初级的东西,如果你想更深入的了解,我推荐您去看the tutorial。它提供有关Concurrent.Thread用法的更多内容,并列出了可供高级用户使用的文档,是最适合起步的材料。访问他们的网站也不错,那里提供更多信息。

  • 无题

    从前,有一只鹰蛋不小心落到了鸡窝里,被当成鸡孵了出来。从出生那天起,它就与鸡窝里的兄弟姐妹们不一样:没有五彩斑斓的羽毛,不会用泥灰为自己洗澡,不会三啄两扒就从土里刨出一只小虫来。矮小的鸡窝总是碰它的头,而小鸡们总是笑它笨。它对自己失望极了,于是跑到悬崖上,想跳下去结束自己的生命。就在它纵身跃下时,它本能地展开了翅膀,结果飞上了蓝天。它这才发现,自己原来是一只鹰,鸡窝和虫子不属于它。

    Posted Dec 11 2009, 01:09 PM by Coolboy with 3 comment(s)
    Filed under: , ,
  • 日记

    7月7日
        我知道我不算帅哥,但曾经有人看我满月的照片时,也说过我左边的鼻孔很偶像派。
      
      8月30日
        独守空房,让人只能浪费;妻妾成群,让人懂得节俭。可是我现在,却在终日浪费中向往节俭。
      
      5月10日
        我想我是个变态,我有恋母和喜欢极品熟女的癖好。不然为什么每次看到我们超市主管的那张脸,我都想操她奶奶?
      
      3月18日
        和女朋友分手之后,我终于明白,幸福要掌握在自己的手中,而不是在别人的嘴里!
      
      7月9日
        今天看书,看到康熙皇帝在二十三岁的时候已经贵为一国之君,绩伟功丰,我很沮丧;但又看到同治皇帝在二十三岁时已经死了四年了,我平饬恕?
      
      11月11日
        情人节,孤单的我在饭馆吃面,听到收音机里的点歌节目说:“有一位先生给所有恋人们点歌来表达他的祝福,下面请听《无言的结局》。”……我觉得很不好,人可以无爱,但不能无耻,于是我也打电话点播了一首歌——梁静茹的《分手快乐》。
      
      7月20日
        以前喜欢过一个女孩,表白了,那女孩问我为什么喜欢她,我说:如果你是我,也会喜欢上你自己的;
      
        后来,她把我拒绝了,我很伤心,她不了解我,我告诉她:如果我是你,肯定早就喜欢上我自己了!
      
      12月9日
        今天饭馆的白酒又兑水了!妈的!等我有钱了,也到大酒楼去喝人头马、XO什么的!而且绝对不让他们用八六年和七二年的糊弄我,要喝就来瓶今年的!www.5dhz.com
      
      9月12日
        其实馒头是万能的,饿了就可以吃。想吃饼,就把馒头拍扁;想吃面条,就把馒头用梳子梳;想吃汉堡,就把馒头切开夹菜吃……
      
       
      9月10日
        单身很痛苦,单身久了更痛苦,前几天我看见一头母猪,都觉得它眉清目秀的……
      
      6月22日
        男人分两种,一种是好色,一种是十分好色;
      
        女人也分两种,一种是假装清纯,一种是假装不清纯。
      
      1月19日
        有些人的爱情是A片,有些是三级片,有些是喜剧片,有些是文艺片;
      
        我最惨,我的爱情过程是文艺片、喜剧片、三级片、A片、悬疑片、动作片,最后是KB片,更可气的是,还他 妈插播广告……
      
      2月13日
        明天情人节,我辗转找到一个我中学暗恋的女生的电话,给她发了一条短信:如果只有一碗粥,你先喝半碗,剩下的半碗,我放在怀里给你保温……
      
        几分钟后,她回了一条短信:你是谁介绍的?一次四百,包夜七百。
      
      2月14日
        舍不得孩子套不着狼,舍不得媳妇抓不着流氓,舍不得更新得不着收藏……
      
        今天心情一直不好,昨晚的短信让我知道了,我以前暗恋的女生堕落了,竟然跟我说一次四百……
      
        当时我很伤心,一边伤心一边翻了翻钱包:
      
        于是我更伤心了,我连陪她堕落一次的资本都没有……
      
      4月15日
        你问我,幸福在哪里?我告诉你,你踮起脚尖,就能离幸福更近一些,你闭上眼,就能感受到幸福了……
      
        许久,我们分开,我看着你羞红的脸颊,轻声问你,感觉到幸福了么?
      
        你温柔的低头,娇声回了一句:你今天,吃蒜了。
      
      5月10日
      
        什么叫残忍?
        是男人,我就打断他三条腿;是公狗,我就打断它五条腿!
      
      6月9日
        今天心情不好。我只有四句话想说。包括这句和前面的两句。我的话说完了……
      
      7月23日
      
        对付凶恶的人,就要比他更凶恶;对付卑鄙的人,就要比他更卑鄙;
      
        对付潇洒的人,就要比他更潇洒;对付英俊的人,就要……毁他的容!
      
      7月23日
      
        上一次恋爱给我的教训是:不要找一个喜欢吃辣的女孩作女朋友。
      
        每一次请她吃完麻辣火锅,我们在一起亲热时,我都会在痛苦不堪中想起一首歌:《燃烧吧!火鸟》。
      
      5月23日
        我的原则是:人不犯我,我不犯人;人若犯我,我就生气!
      
      5月23日
        忽然想起上大学时,老师出对联:国兴旺,家兴旺,国家兴旺。
      
        班长对下联:天恢弘,地恢弘,天地恢弘!
      
        后来我被赶出了教室……
      
        因为我对的下联是:你 妈 的,他 妈 的,你 他 妈的!
      
      5月23日
        偶然看见书上所谓的当代女子择偶标准:有车有房,父母双亡。
      
        郁闷。遂写下幻想中的选妻标准:
      
        家中财产过亿,美貌天下第一,贤惠温柔性感,岳父癌症晚期……
      
      7月17日
        凤凰重生就是涅盘,野鸡重生就是尸变。
      
      7月11日
        人生啊,不能在一棵树上吊死,要在附近几棵树上多死几次试试。
      
      5月19日
        这个世界不公平就在于:
        上帝说:我要光!——于是有了白天。
      
        美女说:我要钻戒!——于是她有了钻戒。
      
        富豪说:我要女人!——于是他有了女人。
      
        我说:我要洗澡!——居然停水了!
      
      5月8日
        吃了晚饭在阳台抽烟享受,忽见夜空中一个光点转瞬即逝的划过,心里一激动:流星!于是马上许愿……
        许了六七个愿望,睁眼,烟已经抽完了,顺手扔出阳台,忽然听见楼下一个女孩的声音:“哇!流星!快许愿……”
      
      3月22日
        记得刚毕业不久的一天,女友给我发了一条短信:“我们还是分手吧!”
      
        我还没来得及伤心呢,女友又发来一条:“对不起,发错了。”
      
        这下可以彻底伤心了……
      
      8月15日
        野猫:走哪儿睡哪儿。
      
        野狗:逮什么吃什么。
      
        野男人:见一个爱一个。
      
      3月17日
        在街上看美女,目光高一点就是欣赏,目光低一点就是流氓。
      
      9月6日
          父亲问我人生有什么追求?
      
        我回答金钱和美女,父亲凶狠的打了我的脸;
      
        我回答事业与爱情,父亲赞赏的摸了我的头。
        
      5月17日
        香荷碧水动风凉,水动风凉夏日长,长日夏凉风动水,凉风动水碧荷香。
      
      10月31日
        有人说春天把女朋友埋到地下,到了秋天就会收获很多很多女朋友。
      
        我朋友相信并照做了,他在春天把女朋友埋到了地下,到了秋天,他被警 察叔叔埋到了地下……
      
      2月27日
        面对困难时:死都不怕,还怕活着吗?
      
        面对危险时:活着都不怕,还怕死吗?
      
        这就是爱因斯坦的相对论……
         
      10月28日
        今天约见了一女网友,名叫“稚嫩小妹”,暗号是拿着一只玫瑰花,在约会地点张望,见一女握玫瑰做翘首状,遂逃,晚上联网,质问对方:怎么是你妈来替你见网友?……从此我安静的躺在了她的黑名单里。
        
       5月17日
        每个人都是天上落下的天使,只不过有的是完好无损的着陆,有的是脸先着地,有的更倒霉,下落的时候直接骑在了围墙栏杆上……
         
      2月10日
        我喜欢把人生交给命运:早上醒来我都会抛硬币,如果正面朝上,我就继续睡觉;如果背面朝上,我就躺在床上看电视。如果硬币落地后是立起来的,我就起来收拾屋子。
         
      6月12日
        凶残的人——没事找个人来杀杀。
      
        风流的人——没事找个美女睡睡。
      
        富有的人——没事买辆新车开开。
      
         我——没事捡个烟头抽抽……
      
      6月12日
        年少的时候有一段时间,一直想表现自己彪悍的一面,于是想纹身,最终没有实施的原因是:我一直在犹豫是纹蜡笔小新好,还是纹铁臂阿童木好。
             
      3月11日
        我把她从女孩变成了女人;她把我从男孩变成了....................穷人。
       
      3月11日
        我退化了,到现在我还不会游泳,要知道在我出生之前,我绝对是游的最快的那个……www.sou1sou.com
      
      7月21日
        人要学会自己寻找一些小幸福,比如到街上看一看那些不属于自己的美女,去银行看一看那些不属于自己的钞票,到车展上看一看那些不属于自己的跑车,然后在街上找一个乞丐看,告诉自己:没关系,刚才的那些也不属于他……
      
      7月21日
        这几天一直下雨,我猜是玉皇大帝在哭,一定是他和王母娘娘的婚姻不幸福,这种不幸福有两种可能,一种是王母娘娘离开了,一种是王母娘娘不肯离开……

    Posted Oct 22 2009, 10:40 PM by Coolboy with no comments
    Filed under:
  • 加菲猫的人生歪理

    1、 今天吃得下的千万别搁到明天。
      
    2、爱情来得快去得也快,只有猪肉卷是永恒的。
      
    3、欧迪,我们去吃冰淇淋吧,不过你得看着我吃。
      
    4、肚子大不可怕,可怕的是肚子里没有好东西。
      
    5 「欧迪在窗外冻得瑟瑟发抖,真可怜。我真有点不忍心看他这样。
      不,难道我能坐视不管吗?我必须做点什么。」加菲拉上了窗 帘。
      
    6、 失败的人特点是会不断地失败。
      如果你想看看他的失败的话,他是不会让你失望的。
      
    7、如果你不能击败你的敌人,那么就加入他们。
      
    8、球状也是身材。
      
    9、我向星星许了个愿。我并不是真的相信它,但是反正也是免费的,而且也没有证据证明它不灵。
      
    10、睡了美美的一觉,16个小时,我是喜欢睡短觉的。
      
    11、加菲在饭桌旁等着开饭,乔恩却忙着要出门。
      加菲:嗨,你没有忘记什么重要的事情吗?
      .......??
      加菲:要知道,在有些州换猫做早饭是重罪。
      
    12、我并不胖。按照我的体重我只是稍微矮了一点。
      
    13、如果你想显得聪明,就要多跟蠢人为伍。
      
    14、我胖我懒——可是我自豪!
      
    15、工作好有意思耶!尤其是看着别人工作。
      
    16、如果早晨晚一点儿来的话,我会喜欢早晨的。
      
    17、每个人都应该热爱动物,因为它们很好吃。 ( … )
      
    18、要用心去爱你的邻居,不过不要让她的老公知道。
      
    19、不要等明天交不上差再找借口,今天就要找好。
      
    20、懒惰有一点特别招人喜欢,那就是,不用学就会。 

    21、哦?吃老鼠?如果世界上已经有了意大利面,那还吃老鼠干什么?
      
    22、巧克力的麻烦是:你把它吃了,它就没了。
      
    23、钞票不是万能的,有时还需要信用卡。
      
    24、要节约用水,尽量和女友一起洗澡。
      
    25、神决定了谁是你的亲戚,幸运的是在选择朋友方面他给你留了余地。
      
    26、这个世界上还有很多比钱更重要的东西,比如说意大利面。
      
    27、有人管这叫懒惰,我称其为深思。
      
    28、乔恩:加菲!你不是说你只吃到下午三点吗?现在已经五点了!
      
      加菲:是啊,我是说吃到下午三点,可是我没说哪一天啊。
      
    29、乔恩:加菲猫,你猜我给你带什么来了?
      加菲:不管是什么,只要能吃就行。
      
    30、乔恩在洗澡,加菲在睡觉。
      加菲:那些一边洗澡一边唱歌的人应该拉到街上去枪毙。
      
    31、加菲猫节食秘诀:
       1.不要打算吃不够再来第二轮,第一次就要拿够食物
       2.把磅秤的零点调成负5公斤 3.绝对不吃减肥糖
       4.不要结交家里开餐厅或糕饼店的女朋友
       5.减肥应多吃蔬菜,所以该多吃南瓜派,蔬菜饼干等
       6.冷食不宜多吃(但冰淇淋除外)
       7.每餐留一点儿,不要统统吃下肚——
       比方说,冰淇淋圣代上的那颗樱桃
       8.多跟比你胖的人在一起。

    32、值得做的事都值得一做再做。
      
    33、你能不能用英语来说中国话?否则什么都别说。
      
    34、从今以后,我将不再贪吃,而只是爱吃而已。
      
    35、我的体重是我自己的事。
      
    36、爱情就像照片,需要大量的暗房时间来培养。
      
    37、应该有更好的方式开始新一天,而不是千篇一律地在每个上午都醒来
      
    38、努力工作不会导致死亡!不过我不会用自己去证明。
      
    39、再快乐的单身汉迟早也会结婚,幸福不是永久的嘛。
      
    40、聪明人都是未婚的,结婚的人很难再聪明起来。
      
    41、(加菲把嘴张得尽可能地大然后用尺子量尺寸)乔恩,我的生日蛋糕要这么大的。
      
    42、乔恩:加菲猫,我不想说你胖,但是你的下巴上的褶快赶上一本字典了。
      
    43、人们为什么喜欢玩具熊呢,这是因为他们的个性,他们不会吃你的东西,不会和你约的女孩跳舞,不会抢你的风头。
      
    44、乔恩:抓住那只老鼠,杀了它。
       加菲:我是受过教育的猫,才不干那种野蛮的事呢。

    45、人们为什么总是希望我们吃老鼠呢?这只老鼠可能是一群孩子的母亲,
      也可能是老鼠课堂的教师……
      
    46、乔恩:加菲猫,我不想说你胖,但如果你节食的话,两个发展中国家就有足够的粮食了。
      
    47、再没有比一边喝热气腾腾的咖啡,一边看报纸更舒服的事了。
      我要是能看懂的话就更好了。
      
    48、乔恩:加菲,你在屋子里的时间太长了。我怎么才能使你对户外感兴趣呢?
      加菲:可以把他搬到屋子里来,那样就行了。
      
    49、你可以抓我的毛,可以侮辱我的母亲,可以揍我的狗,可以玩我的橡皮老鼠,
      但是你不许吃我的食物,不许在我的床上睡觉!
      
    50、乔恩:加菲猫,你的烦恼是,你自己认为你是人类。
      加菲:你说对了!我得想办法克服这种自卑感才行。
      
    51、乔恩:加菲猫,等等,大多数的蜘蛛是无害的。
      加菲:你说的对,尤其是死了的那一种。
      
    52、乔恩,快带我看兽医!我有失眠的毛病,每过12或者13小时,我就醒了。

    Posted Oct 14 2009, 08:46 AM by Coolboy with no comments
    Filed under:
  • vi编辑器的使用

    vi编辑器是任何Unix及Linux系统下标准的编辑器,他的强大不逊色于任何最新的文本编辑器,这里只是简单地介绍一下他的用法和一小部分指令。由于对Unix及Linux系统的任何版本,vi编辑器是完全相同的,因此您能够在其他任何介绍vi的地方进一步了解他。Vi也是Linux中最基本的文本编辑器,学会他后,您将在Linux的世界里畅行无阻。  
    1、vi的基本概念  
      基本上vi能够分为三种状态,分别是命令模式(command mode)、插入模式(Insert mode)和底行模式(last line mode),各模式的功能区分如下:  
        1) 命令行模式command mode)  
      控制屏幕光标的移动,字符、字或行的删除,移动复制某区段及进入Insert mode下,或到 last line mode。  
        2) 插入模式(Insert mode)  
      只有在Insert mode下,才能够做文字输入,按「ESC」键可回到命令行模式。  
        3) 底行模式(last line mode)  
      将文档保存或退出vi,也能够配置编辑环境,如寻找字符串、列出行号……等。  
        但是一般我们在使用时把vi简化成两个模式,就是将底行模式(last line mode)也算入命令行模式command mode)。  
    2、vi的基本操作  
    a) 进入vi  
        在系统提示符号输入vi及文档名称后,就进入vi全屏幕编辑画面:
       $ vi myfile  
      但是有一点要特别注意,就是您进入vi之后,是处于「命令行模式(command mode)」,您要转换到「插入模式(Insert mode)」才能够输入文字。初次使用vi的人都会想先用上下左右键移动光标,结果电脑一直哔哔叫,把自己气个半死,所以进入vi后,先不要乱动,转换到「插入模式(Insert mode)」再说吧!  
    b) 转换至插入模式(Insert mode)编辑文档  
      在「命令行模式(command mode)」下按一下字母「i」就能够进入「插入模式(Insert mode)」,这时候您就能够开始输入文字了。  
    c) Insert 的转换  
      您现在处于「插入模式(Insert mode)」,您就只能一直输入文字,假如您发现输错了字!想用光标键往回移动,将该字删除,就要先按一下「ESC」键转到「命令行模式(command mode)」再删除文字。  
    d) 退出vi及保存文档  
      在「命令行模式(command mode)」下,按一下「:」冒号键进入「Last line mode」,例如:  
    : w filename (输入 「w filename」将文章以指定的文档名filename保存)  
    : wq (输入「wq」,存盘并退出vi)  
    : q! (输入q!, 不存盘强制退出vi)  
    3、命令行模式(command mode)功能键  
    1). 插入模式  
           按「i」转换进入插入模式「insert mode」,按"i"进入插入模式后是从光标当前位置开始输入文档;  
      按「a」进入插入模式后,是从现在光标所在位置的下一个位置开始输入文字;  
      按「o」进入插入模式后,是插入新的一行,从行首开始输入文字。  
    2). 从插入模式转换为命令行模式  
          按「ESC」键。  
    3). 移动光标  
      vi能够直接用键盘上的光标来上下左右移动,但正规的vi是用小写英文字母「h」、「j」、「k」、「l」,分别控制光标左、下、上、右移一格。  
      按「ctrl」+「b」:屏幕往"后"移动一页。  
      按「ctrl」+「f」:屏幕往"前"移动一页。  
      按「ctrl」+「u」:屏幕往"后"移动半页。  
      按「ctrl」+「d」:屏幕往"前"移动半页。  
      按数字「0」:移到文章的开头。  
      按「G」:移动到文章的最后。  
      按「$」:移动到光标所在行的"行尾"。  
      按「^」:移动到光标所在行的"行首"  
      按「w」:光标跳到下个字的开头  
      按「e」:光标跳到下个字的字尾  
      按「b」:光标回到上个字的开头  
      按「#l」:光标移到该行的第#个位置,如:5l,56l。  
    4). 删除文字  
      「x」:每按一次,删除光标所在位置的"后面"一个字符。  
      「#x」:例如,「6x」表示删除光标所在位置的"后面"6个字符。  
      「X」:大写的X,每按一次,删除光标所在位置的"前面"一个字符。  
      「#X」:例如,「20X」表示删除光标所在位置的"前面"20个字符。  
      「dd」:删除光标所在行。  
      「#dd」:从光标所在行开始删除#行  
    5). 复制  
      「yw」:将光标所在之处到字尾的字符复制到缓冲区中。  
      「#yw」:复制#个字到缓冲区  
      「yy」:复制光标所在行到缓冲区。  
      「#yy」:例如,「6yy」表示拷贝从光标所在的该行"往下数"6行文字。  
      「p」:将缓冲区内的字符贴到光标所在位置。注意:任何和"y"有关的复制命令都必须和"p"配合才能完成复制和粘贴功能。  
    6). 替换  
      「r」:替换光标所在处的字符。  
      「R」:替换光标所到之处的字符,直到按下「ESC」键为止。  
    7). 回复上一次操作  
      「u」:假如您误执行一个命令,能够马上按下「u」,回到上一个操作。按多次"u"能够执行多次回复。  
    8). 更改  
      「cw」:更改光标所在处的字到字尾处  
      「c#w」:例如,「c3w」表示更改3个字  
    9). 跳至指定的行  
      「ctrl」+「g」列出光标所在行的行号。  
      「#G」:例如,「15G」,表示移动光标至文章的第15行行首。  
    4、Last line mode下命令简介  
      在使用「last line mode」之前,请记住先按「ESC」键确定您已处于「command mode」下后,再按「:」冒号即可进入「last line mode」。  
    A) 列出行号  
     「set nu」:输入「set nu」后,会在文档中的每一行前面列出行号。  
    B) 跳到文档中的某一行  
     「#」:「#」号表示一个数字,在冒号后输入一个数字,再按回车键就会跳到该行了,如输入数字15,再回车,就会跳到文章的第15行。  
    C) 查找字符  
     「/关键字」:先按「/」键,再输入您想寻找的字符,假如第一次找的关键字不是您想要的,能够一直按「n」会往后寻找到您要的关键字为止。  
     「?关键字」:先按「?」键,再输入您想寻找的字符,假如第一次找的关键字不是您想要的,能够一直按「n」会往前寻找到您要的关键字为止。  
    D) 保存文档  
     「w」:在冒号输入字母「w」就能够将文档保存起来。  
    E) 离开vi  
     「q」:按「q」就是退出,假如无法离开vi,能够在「q」后跟一个「!」强制离开vi。  
     「qw」:一般建议离开时,搭配「w」一起使用,这样在退出的时候还能够保存文档。  
    5、vi命令列表  
    1、下表列出命令模式下的一些键的功能:  
    h  
    左移光标一个字符  
    l  
    右移光标一个字符  
    k  
    光标上移一行  
    j  
    光标下移一行  
    ^  
    光标移动至行首  
    0  
    数字"0",光标移至文章的开头  
    G  
    光标移至文章的最后  
    $  
    光标移动至行尾  
    Ctrl+f  
    向前翻屏  
    Ctrl+b  
    向后翻屏  
    Ctrl+d  
    向前翻半屏  
    Ctrl+u  
    向后翻半屏  
    i  
    在光标位置前插入字符  
    a  
    在光标所在位置的后一个字符开始增加  
    o  
    插入新的一行,从行首开始输入  
    ESC  
    从输入状态退至命令状态  
    x  
    删除光标后面的字符  
    #x  
    删除光标后的#个字符  
    X  
    (大写X),删除光标前面的字符  
    #X  
    删除光标前面的#个字符  
    dd  
    删除光标所在的行  
    #dd  
    删除从光标所在行数的#行  
    yw  
    复制光标所在位置的一个字  
    #yw  
    复制光标所在位置的#个字  
    yy  
    复制光标所在位置的一行  
    #yy  
    复制从光标所在行数的#行  
    p  
    粘贴  
    u  
    取消操作  
    cw  
    更改光标所在位置的一个字  
    #cw  
    更改光标所在位置的#个字  
    2、下表列出行命令模式下的一些指令  
    w filename  
    储存正在编辑的文档为filename  
    wq filename  
    储存正在编辑的文档为filename,并退出vi  
    q!  
    放弃任何修改,退出vi  
    set nu  
    显示行号  
    /或?  
    查找,在/后输入要查找的内容  
    n  
    和/或?一起使用,假如查找的内容不是想要找的关键字,按n或向后(和/联用)或向前(和?联用)继续查找,直到找到为止。  
    对于第一次用vi,有几点注意要提醒一下:  
    1、用vi打开文档后,是处于「命令行模式(command mode)」,您要转换到「插入模式(Insert mode)」才能够输入文字。转换方法:在「命令行模式(command mode)」下按一下字母「i」就能够进入「插入模式(Insert mode)」,这时候您就能够开始输入文字了。  
    2、编辑好后,需从插入模式转换为命令行模式才能对文档进行保存,转换方法:按「ESC」键。  
    3、保存并退出文档:在命令模式下输入:wq即可!(别忘了wq前面的:)  

    Posted Sep 18 2009, 02:19 PM by Coolboy with no comments
    Filed under: ,
  • 应聘策划人员

  • [推荐] 炸弹是怎样爆炸的-动态装卸DLL

        我来设计一个例子,我在D目录运行程序A(土匪)。然后望D目录丢文件(炸弹)过去,土匪判断该文件是否炸弹(包含实现了接口IBomb的类),如果是,则执行IBomb的Explode方法让炸弹爆炸,当然炸了以后就没有了,文件将被删除。

       
    接口定义--编译为Interface.dll供炸弹和土匪引用。
     

    using System;
    namespace Interface
    {
       
    public interface IBomb
        {
           
    void Explode();
        }
    }

    炸弹定义--编译为ClassLibrary1.dll,准备交给土匪

    using System;
    namespace ClassLibrary1
    {
       
    public class Class1:Interface.IBomb
        {
           
    public void Explode()
            {
                Console.WriteLine(
    "bo~~~");
            }
        }
    }

    那么程序A,引爆炸弹而且能把炸弹扔掉的土匪--编译为AppDomainTest.exe

    using System;
    using System.Reflection;

    namespace AppDomainTest
    {
       
    /// <summary>
       
    /// 动态装卸dll程序集示例
       
    /// 这里用一个有趣的例子:
       
    ///
       
    /// 我把一个dll看作是炸弹,执行如下操作
       
    /// 1、炸弹扔到程序运行目录中
       
    /// 2、引爆炸弹
       
    /// 3、炸弹消失
       
    ///
       
    ///
       
    /// </summary>
        class Program
        {
           
    /// <summary>
           
    /// 使用FileSystemWatcher监视炸弹,如果有则引爆
           
    /// </summary>
           
    /// <param name="args"></param>
            static void Main(string[] args)
            {
                Console.WriteLine(
    "Press Any Key To Exit ...");

                System.IO.FileSystemWatcher fsWatcher
    = new System.IO.FileSystemWatcher();
                fsWatcher.Path
    =System.IO.Path.GetDirectoryName(System.Reflection.Assembly.GetExecutingAssembly().Location);
                fsWatcher.Filter
    = "*.dll";
                fsWatcher.EnableRaisingEvents
    = true;

                fsWatcher.Created
    += new System.IO.FileSystemEventHandler(fsWatcher_Created);

                Console.ReadKey();
            }

           
    /// <summary>
           
    /// 如果有炸弹丢过来则引爆
           
    /// </summary>
           
    /// <param name="sender"></param>
           
    /// <param name="e"></param>
            static void fsWatcher_Created(object sender, System.IO.FileSystemEventArgs e)
            {
                InvokeExplode(e.FullPath);
            }
           
    /// <summary>
           
    /// 不能炸着自己,创建一个AppDomain...
           
    /// </summary>
           
    /// <param name="fileName"></param>
            public static void InvokeExplode(string fileName)
            {
               
    try
                {
                    System.AppDomain app
    = System.AppDomain.CreateDomain(System.IO.Path.GetFileNameWithoutExtension(fileName));

                    System.Runtime.Remoting.ObjectHandle objLoader
    =
                        app.CreateComInstanceFrom(System.Reflection.Assembly.GetExecutingAssembly().Location,
    "AppDomainTest.RemoteLoader");

                    RemoteLoader loader
    = objLoader.Unwrap() as RemoteLoader;

                    loader.InvokeExplode(fileName);

                    System.AppDomain.Unload(app);

                    System.IO.File.Delete(fileName);
                }
               
    catch (Exception ex)
                {
                    Console.WriteLine(ex.Message);
                }

            }
        }

       
    /// <summary>
       
    /// 在这里爆炸,注意这里的Assembly不能被外面访问
       
    /// </summary>
        class RemoteLoader : MarshalByRefObject
        {
           
    public void InvokeExplode(string fileName)
            {
                Assembly assembly
    = Assembly.LoadFile(fileName);
               
    foreach (System.Type type in assembly.GetTypes())
                {
                   
    if (type.GetInterface(typeof(Interface.IBomb).FullName) != null)
                    {
                       
    object obj = assembly.CreateInstance(type.FullName,true);

                        ((Interface.IBomb)obj).Explode();
                    }
                }
            }
        }

        
    }
    --这三个文件怎么呢?第一个不能玩,是给第二个和第三个引用的。

    运行AppDomainTest.exe,然后把ClassLibrary1.dll扔到该运行目录。你应该看到如下输出之后ClassLibrary1.dll会自动消失。

     

    Assembly code
    Press Any Key To Exit ... bo~~~
    如果把ClassLibrary1.dll改为 
    using System;
    namespace ClassLibrary1
    {
        public class Class1:Interface.IBomb
        {
            public void Explode()
            {
                Console.WriteLine("bo~~~");
            }
        }
        public class Class2 : Interface.IBomb
        {
            public void Explode()
            {
                Console.WriteLine("乒~~~~乓~~~");
            }
        }
    }
    扔到正在运行AppDomainTest.exe的目录中,AppDomainTest.exe将会输出 
    Press Any Key To Exit ... bo~~~ bo~~~ 乒~~~~乓~~~  

     


     

  • 色调

    Posted Jul 08 2009, 08:46 AM by Coolboy with no comments
    Filed under:
  • bom表展开

    我在SQL数据库里有一个BOM表简单如下:
    母件号    子件号                                    但要通过SQL编程使它运行结果为:
    Y01        Y02                                         母件号    层次     子件号
    Y01        Y03                                          Y01         1         Y02
    Y01        Y04                                          Y01        .2         Y05
    Y02        Y05                                          Y01       ..3         Y06
    Y05        Y06                                          Y01         1         Y03
    Y04        Y06                                          Y01         1         Y04
    Y04        Y07                                          Y01        .2         Y06
                                                                 Y01        .2         Y07

     

     

    设定BOM表的个列的列名分别为mj,zj,下面的SQL能够输出你要的结果。
    SELECT 'Y01' dcmj --顶层母件
           ,CASE a.le
            WHEN 1 THEN '1'
            WHEN 2 THEN '.2'
            WHEN 3 THEN '..3'
            END le
           ,a.zj
    FROM (
    SELECT mj,zj,LEVEL le
    FROM BOM
    START WITH mj='Y01'
    CONNECT BY mj= PRIOR zj) a
     
     
    baan code
     
    SELECT '         0006100104' dcmj --顶层母件
           ,DECODE(a.le ,1,'1',2,'.2',3 ,'..3') AS currlevel       ,t$sitm
    FROM (
    SELECT t$mitm,t$sitm,LEVEL le
    FROM baan.ttibom010231
    START WITH t$mitm='         0006100104'
    CONNECT BY t$mitm= PRIOR t$sitm) a
     
     
    Posted Jul 02 2009, 04:10 PM by Coolboy with 2 comment(s)
    Filed under:
  • 什么是openDNS

        OpenDNS 是一个免费的域名解析服务提供商(DNS). 将DNS服务选项设置成如下两个地址便可以开始使用OpenDNS的服务:

          208.67.222.222 (Resolver1.OpenDNS.com)
          208.67.220.220 (Resolver2.OpenDNS.com)

          openDNS历史

          OpenDNS 在 2006年7月由 黑客/创业者 大卫·尤里维奇 ( David Ulevitch)创建. 之后获得了由CNET的创始人Halsey Minor创建的Minor Ventures公司提供的风险投资

          2006年7月10号,这项OpenDNS开始为digg[1]、slashdot[2]和Wired News[3]网站提供服务,这直接导致DNS请求数充7月9日的一百万猛增到30日的三千万。

          2006年10月2日,OpenDNS开始和Phishtank(钓鱼攻击信息厂商)合作,一项在线合作的反钓鱼数据库。

          2006年,OpenDNS开始使用DynDNS的接口来处理动态IP用户的DNS更新。

          从2007年一月开始,OpenDNS开始在以下地区设置服务器来提供服务:西雅图、帕洛阿尔托、纽约、华盛顿和伦敦,并计划扩展到芝加哥和香港。

          2007年6月11日,OpenDNS开始启用高级网页过滤系统来为他们的免费账户过滤成人内容。

          openDNS服务

          OpenDNS为个人和商业提供DNS方案,用户可以自行选择使用OpenDNS的服务或者使用当地ISP提供的DNS服务。将服务器组放置在具有战略意义的地方和使用大量的域名缓存可以使DNS查询进度可以更快得多地完成,从而加快页面的检索速度。DNS的查询结果有时被本地的操作系统或应用程序缓存下来,所以速度的增加也许不能在每次查询中体现出来,但本地缓存里没有的结果其查询速度的增加则显而易见。 其他特征包括一个反钓鱼过滤器和输入纠正(typo correction)〔举例说明,你输入wikipedia.og会被自动替换成wikipedia.org〕。通过收集恶意网站列表,当用户通过他们的服务来访问这些恶意网站时,OpenDNS将封锁这些恶意网站。OpenDNS最近启动了反钓鱼服务(Phishtank),这样全球的用户就可以报告和察看不可信的钓鱼网站。

          OpenDNS并不是像它的名字那样,它不是一款开源软件。

          OpenDNS的一部分收入来自他们不能自动更正的错误域名而出现的页面上的广告。 OpenDNS claims it is not the same as Site Finder as OpenDNS is purely an opt-in service and that the advertising revenue pays for the customized DNS service. OpenDNS也提供增强的DNS附加服务,当然,这是需要付费的。附加服务的一个例子是2007年4月22日启动的一项“快捷方式”服务,让用户设置本地DNS映射,比如把“mail”映射到“mail.yahoo.com”。这项功能被用在很多公共领域,包括纽约时报、Wired和PC World。

    Posted Jul 02 2009, 09:31 AM by Coolboy with no comments
    Filed under:
  • 关于oracle查询日期横向显示的问题

    表结构:
    人员编码 月份 工时 天数
      001    1    12  5
      001    2    20  6
      001    3    18  8
      002    1    12  5
      002    2    15  6
      002    3    18  7

    如何通过sql语句查询出如下显示结果
    人员编码  内容    1月  2月  3月 ......12月
      001    工时    12  20  18
      001    天数    5    6    8
      002    工时    12  15  18
      002    天数    5    6    7

     

    select 人员编码,
    decode(rn,
    1,'工时',2,'天数') 内容,
    sum(decode(月份,1,decode(rn,1,工时,2,天数),0)) 1月,
    sum(decode(月份,2,decode(rn,1,工时,2,天数),0)) 2月,
    sum(decode(月份,3,decode(rn,1,工时,2,天数),0)) 3月,
    sum(decode(月份,4,decode(rn,1,工时,2,天数),0)) 4月,
    sum(decode(月份,5,decode(rn,1,工时,2,天数),0)) 5月,
    sum(decode(月份,6,decode(rn,1,工时,2,天数),0)) 6月,
    sum(decode(月份,7,decode(rn,1,工时,2,天数),0)) 7月,
    sum(decode(月份,8,decode(rn,1,工时,2,天数),0)) 8月,
    sum(decode(月份,9,decode(rn,1,工时,2,天数),0)) 9月,
    sum(decode(月份,10,decode(rn,1,工时,2,天数),0)) 10月,
    sum(decode(月份,11,decode(rn,1,工时,2,天数),0)) 11月,
    sum(decode(月份,12,decode(rn,1,工时,2,天数),0)) 12月
    from mytab a,(select rownum as rn from dual connect by rownum<=2) b
    group by 人员编码,rn
    order by 人员编码,rn;

  • 温故而知新之Oracle110个函数

    1. ASCII
    返回与指定的字符对应的十进制数;
    SQL> select ascii(A) A,ascii(a) a,ascii(0) zero,ascii( ) space from dual;
    A A ZERO SPACE
    --------- --------- --------- ---------
    65 97 48 32

    2. CHR
    给出整数,返回对应的字符;
    SQL> select chr(54740) zhao,chr(65) chr65 from dual;
    ZH C
    -- -
    赵 A
    3. CONCAT
    连接两个字符串;
    SQL> select concat(010-,88888888)||转23 高乾竞电话 from dual;
    高乾竞电话
    ----------------
    010-88888888转23
    4. INITCAP
    返回字符串并将字符串的第一个字母变为大写;
    SQL> select initcap(smith) upp from dual;
    UPP
    -----
    Smith

    5.INSTR(C1,C2,I,J)
    在一个字符串中搜索指定的字符,返回发现指定的字符的位置;
    C1 被搜索的字符串
    C2 希望搜索的字符串
    I 搜索的开始位置,默认为1
    J 出现的位置,默认为1
    SQL> select instr(oracle traning,ra,1,2) instring from dual;
    INSTRING
    ---------
    9

    6.LENGTH
    返回字符串的长度;
    SQL> select name,length(name),addr,length(addr),sal,length(to_char(sal)) from gao.nchar_tst;
    NAME LENGTH(NAME) ADDR LENGTH(ADDR) SAL LENGTH(TO_CHAR(SAL))
    ------ ------------ ---------------- ------------ --------- --------------------
    高乾竞 3 北京市海锭区 6 9999.99 7

    7.LOWER
    返回字符串,并将所有的字符小写
    SQL> select lower(AaBbCcDd)AaBbCcDd from dual;
    AABBCCDD
    --------
    aabbccdd

    8.UPPER
    返回字符串,并将所有的字符大写
    SQL> select upper(AaBbCcDd) upper from dual;
    UPPER
    --------
    AABBCCDD

    9.RPAD和LPAD(粘贴字符)
    RPAD 在列的右边粘贴字符
    LPAD 在列的左边粘贴字符
    SQL> select lpad(rpad(gao,10,*),17,*)from dual;
    LPAD(RPAD(GAO,1
    -----------------
    *******gao*******
    不够字符则用*来填满

    10.LTRIM和RTRIM
    LTRIM 删除左边出现的字符串
    RTRIM 删除右边出现的字符串
    SQL> select ltrim(rtrim( gao qian jing , ), ) from dual;
    LTRIM(RTRIM(
    -------------
    gao qian jing

    11.SUBSTR(string,start,count)
    取子字符串,从start开始,取count个
    SQL> select substr(13088888888,3,8) from dual;
    SUBSTR(
    --------
    08888888

    12.REPLACE(string,s1,s2)
    string 希望被替换的字符或变量
    s1 被替换的字符串
    s2 要替换的字符串
    SQL> select replace(he love you,he,i) from dual;
    REPLACE(H
    ----------
    i love you

    13.SOUNDEX
    返回一个与给定的字符串读音相同的字符串
    SQL> create table table1(xm varchar(8));
    SQL> insert into table1 values(weather);
    SQL> insert into table1 values(wether);
    SQL> insert into table1 values(gao);
    SQL> select xm from table1 where soundex(xm)=soundex(weather);
    XM
    --------
    weather
    wether
    • 14.TRIM(s from string)
    LEADING 剪掉前面的字符
    TRAILING 剪掉后面的字符
    如果不指定,默认为空格符
    15.ABS
    返回指定值的绝对值
    SQL> select abs(100),abs(-100) from dual;
    ABS(100) ABS(-100)
    --------- ---------
    100 100

    16.ACOS
    给出反余弦的值
    SQL> select acos(-1) from dual;
    ACOS(-1)
    ---------
    3.1415927

    17.ASIN
    给出反正弦的值
    SQL> select asin(0.5) from dual;
    ASIN(0.5)
    ---------
    .52359878

    18.ATAN
    返回一个数字的反正切值
    SQL> select atan(1) from dual;
    ATAN(1)
    ---------
    .78539816

    19.CEIL
    返回大于或等于给出数字的最小整数
    SQL> select ceil(3.1415927) from dual;
    CEIL(3.1415927)
    ---------------
    4

    20.COS
    返回一个给定数字的余弦
    SQL> select cos(-3.1415927) from dual;
    COS(-3.1415927)
    ---------------
    -1
    21.COSH
    返回一个数字反余弦值
    SQL> select cosh(20) from dual;
    COSH(20)
    ---------
    242582598

    22.EXP
    返回一个数字e的n次方根
    SQL> select exp(2),exp(1) from dual;
    EXP(2) EXP(1)
    --------- ---------
    7.3890561 2.7182818

    23.FLOOR
    对给定的数字取整数
    SQL> select floor(2345.67) from dual;
    FLOOR(2345.67)
    --------------
    2345

    24.LN
    返回一个数字的对数值
    SQL> select ln(1),ln(2),ln(2.7182818) from dual;
    LN(1) LN(2) LN(2.7182818)
    --------- --------- -------------
    0 .69314718 .99999999

    25.LOG(n1,n2)
    返回一个以n1为底n2的对数
    SQL> select log(2,1),log(2,4) from dual;
    LOG(2,1) LOG(2,4)
    --------- ---------
    0 2

    26.MOD(n1,n2)
    返回一个n1除以n2的余数
    SQL> select mod(10,3),mod(3,3),mod(2,3) from dual;
    MOD(10,3) MOD(3,3) MOD(2,3)
    --------- --------- ---------
    1 0 2

    27.POWER
    返回n1的n2次方根
    SQL> select power(2,10),power(3,3) from dual;
    POWER(2,10) POWER(3,3)
    ----------- ----------
    1024 27

    28.ROUND和TRUNC
    按照指定的精度进行舍入
    SQL> select round(55.5),round(-55.4),trunc(55.5),trunc(-55.5) from dual;
    ROUND(55.5) ROUND(-55.4) TRUNC(55.5) TRUNC(-55.5)
    ----------- ------------ ----------- ------------
    56 -55 55 -55

    29.SIGN
    取数字n的符号,大于0返回1,小于0返回-1,等于0返回0
    SQL> select sign(123),sign(-100),sign(0) from dual;
    SIGN(123) SIGN(-100) SIGN(0)
    --------- ---------- ---------
    1 -1 0

    30.SIN
    返回一个数字的正弦值
    SQL> select sin(1.57079) from dual;
    SIN(1.57079)
    ------------
    1
    • 31.SIGH
    返回双曲正弦的值
    SQL> select sin(20),sinh(20) from dual;
    SIN(20) SINH(20)
    --------- ---------
    .91294525 242582598

    32.SQRT
    返回数字n的根
    SQL> select sqrt(64),sqrt(10) from dual;
    SQRT(64) SQRT(10)
    --------- ---------
    8 3.1622777

    33.TAN
    返回数字的正切值
    SQL> select tan(20),tan(10) from dual;
    TAN(20) TAN(10)
    --------- ---------
    2.2371609 .64836083

    34.TANH
    返回数字n的双曲正切值
    SQL> select tanh(20),tan(20) from dual;
    TANH(20) TAN(20)
    --------- ---------
    1 2.2371609

    35.TRUNC
    按照指定的精度截取一个数
    SQL> select trunc(124.1666,-2) trunc1,trunc(124.16666,2) from dual;
    TRUNC1 TRUNC(124.16666,2)
    --------- ------------------
    100 124.16

    36.ADD_MONTHS
    增加或减去月份
    SQL> select to_char(add_months(to_date(199912,yyyymm),2),yyyymm) from dual;
    TO_CHA
    ------
    200002
    SQL> select to_char(add_months(to_date(199912,yyyymm),-2),yyyymm) from dual;
    TO_CHA
    ------
    199910

    37.LAST_DAY
    返回日期的最后一天
    SQL> select to_char(sysdate,yyyy.mm.dd),to_char((sysdate)+1,yyyy.mm.dd) from dual;
    TO_CHAR(SY TO_CHAR((S
    ---------- ----------
    2004.05.09 2004.05.10
    SQL> select last_day(sysdate) from dual;
    LAST_DAY(S
    ----------
    31-5月 -04

    38.MONTHS_BETWEEN(date2,date1)
    给出date2-date1的月份
    SQL> select months_between(19-12月-1999,19-3月-1999) mon_between from dual;
    MON_BETWEEN
    -----------
    9
    SQL>selectmonths_between(to_date(2000.05.20,yyyy.mm.dd),to_date(2005.05.20,yyyy.mm.dd)) mon_betw from dual;
    MON_BETW
    ---------
    -60

    39.NEW_TIME(date,this,that)
    给出在this时区=other时区的日期和时间
    SQL> select to_char(sysdate,yyyy.mm.dd hh24:mi:ss) bj_time,to_char(new_time
    2 (sysdate,PDT,GMT),yyyy.mm.dd hh24:mi:ss) los_angles from dual;
    BJ_TIME LOS_ANGLES
    ------------------- -------------------
    2004.05.09 11:05:32 2004.05.09 18:05:32

    40.NEXT_DAY(date,day)
    给出日期date和星期x之后计算下一个星期的日期
    SQL> select next_day('18-5月-2001','星期五') next_day from dual;
    NEXT_DAY
    ----------
    25-5月 -01

    41.SYSDATE
    用来得到系统的当前日期
    SQL> select to_char(sysdate,dd-mm-yyyy day) from dual;
    TO_CHAR(SYSDATE,
    -----------------
    09-05-2004 星期日
    trunc(date,fmt)按照给出的要求将日期截断,如果fmt=mi表示保留分,截断秒
    SQL> select to_char(trunc(sysdate,hh),yyyy.mm.dd hh24:mi:ss) hh,
    2 to_char(trunc(sysdate,mi),yyyy.mm.dd hh24:mi:ss) hhmm from dual;
    HH HHMM
    ------------------- -------------------
    2004.05.09 11:00:00 2004.05.09 11:17:00

    42.CHARTOROWID
    将字符数据类型转换为ROWID类型
    SQL> select rowid,rowidtochar(rowid),ename from scott.emp;
    ROWID ROWIDTOCHAR(ROWID) ENAME
    ------------------ ------------------ ----------
    AAAAfKAACAAAAEqAAA AAAAfKAACAAAAEqAAA SMITH
    AAAAfKAACAAAAEqAAB AAAAfKAACAAAAEqAAB ALLEN
    AAAAfKAACAAAAEqAAC AAAAfKAACAAAAEqAAC WARD
    AAAAfKAACAAAAEqAAD AAAAfKAACAAAAEqAAD JONES

    43.CONVERT(c,dset,sset)
    将源字符串 sset从一个语言字符集转换到另一个目的dset字符集
    SQL> select convert(strutz,we8hp,f7dec) "conversion" from dual;
    conver
    ------
    strutz

    44.HEXTORAW
    将一个十六进制构成的字符串转换为二进制

    45.RAWTOHEXT
    将一个二进制构成的字符串转换为十六进制

    46.ROWIDTOCHAR
    将ROWID数据类型转换为字符类型

    47.TO_CHAR(date,format)
    SQL> select to_char(sysdate,yyyy/mm/dd hh24:mi:ss) from dual;
    TO_CHAR(SYSDATE,YY
    -------------------
    2004/05/09 21:14:41
    • 48.TO_DATE(string,format)
    将字符串转化为ORACLE中的一个日期

    49.TO_MULTI_BYTE
    将字符串中的单字节字符转化为多字节字符
    SQL> select to_multi_byte(高) from dual;
    TO
    --


    50.TO_NUMBER
    将给出的字符转换为数字
    SQL> select to_number(1999) year from dual;
    YEAR
    ---------
    1999
    51.BFILENAME(dir,file)
    指定一个外部二进制文件
    SQL>insert into file_tb1 values(bfilename(lob_dir1,image1.gif));

    52.CONVERT(x,desc,source)
    将x字段或变量的源source转换为desc
    SQL> select sid,serial#,username,decode(command,
    2 0,none,
    3 2,insert,
    4 3,
    5 select,
    6 6,update,
    7 7,delete,
    8 8,drop,
    9 other) cmd from v$session where type!=background;
    SID SERIAL# USERNAME CMD
    --------- --------- ------------------------------ ------
    1 1 none
    2 1 none
    3 1 none
    4 1 none
    5 1 none
    6 1 none
    7 1275 none
    8 1275 none
    9 20 GAO select
    10 40 GAO none

    53.DUMP(s,fmt,start,length)
    DUMP函数以fmt指定的内部数字格式返回一个VARCHAR2类型的值
    SQL> col global_name for a30
    SQL> col dump_string for a50
    SQL> set lin 200
    SQL> select global_name,dump(global_name,1017,8,5) dump_string from global_name;
    GLOBAL_NAME DUMP_STRING
    ------------------------------ --------------------------------------------------
    ORACLE.WORLD Typ=1 Len=12 CharacterSet=ZHS16GBK: W,O,R,L,D

    54.EMPTY_BLOB()和EMPTY_CLOB()
    这两个函数都是用来对大数据类型字段进行初始化操作的函数

    55.GREATEST
    返回一组表达式中的最大值,即比较字符的编码大小.
    SQL> select greatest(AA,AB,AC) from dual;
    GR
    --
    AC
    SQL> select greatest(啊,安,天) from dual;
    GR
    --


    56.LEAST
    返回一组表达式中的最小值
    SQL> select least(啊,安,天) from dual;
    LE
    --


    57.UID
    返回标识当前用户的唯一整数
    SQL> show user
    USER 为"GAO"
    SQL> select username,user_id from dba_users where user_id=uid;
    USERNAME USER_ID
    ------------------------------ ---------
    GAO 25

    58.USER
    返回当前用户的名字
    SQL> select user from dual;
    USER
    ------------------------------
    GAO

    59.USEREVN
    返回当前用户环境的信息,opt可以是:
    ENTRYID,SESSIONID,TERMINAL,ISDBA,LABLE,LANGUAGE,CLIENT_INFO,LANG,VSIZE
    ISDBA 查看当前用户是否是DBA如果是则返回true
    SQL> select userenv(isdba) from dual;
    USEREN
    ------
    FALSE
    SQL> select userenv(isdba) from dual;
    USEREN
    ------
    TRUE
    SESSION
    返回会话标志
    SQL> select userenv(sessionid) from dual;
    USERENV(SESSIONID)
    --------------------
    152
    ENTRYID
    返回会话人口标志
    SQL> select userenv(entryid) from dual;
    USERENV(ENTRYID)
    ------------------
    0
    INSTANCE
    返回当前INSTANCE的标志
    SQL> select userenv(instance) from dual;
    USERENV(INSTANCE)
    -------------------
    1
    LANGUAGE
    返回当前环境变量
    SQL> select userenv(language) from dual;
    USERENV(LANGUAGE)
    ----------------------------------------------------
    SIMPLIFIED CHINESE_CHINA.ZHS16GBK
    LANG
    返回当前环境的语言的缩写
    SQL> select userenv(lang) from dual;
    USERENV(LANG)
    ----------------------------------------------------
    ZHS
    TERMINAL
    返回用户的终端或机器的标志
    SQL> select userenv(terminal) from dual;
    USERENV(TERMINA
    ----------------
    GAO
    VSIZE(X)
    返回X的大小(字节)数
    SQL> select vsize(user),user from dual;
    VSIZE(USER) USER
    ----------- ------------------------------
    6 SYSTEM
    • 60.AVG(DISTINCT|ALL)
    all表示对所有的值求平均值,distinct只对不同的值求平均值
    SQLWKS> create table table3(xm varchar(8),sal number(7,2));
    语句已处理。
    SQLWKS> insert into table3 values(gao,1111.11);
    SQLWKS> insert into table3 values(gao,1111.11);
    SQLWKS> insert into table3 values(zhu,5555.55);
    SQLWKS> commit;
    SQL> select avg(distinct sal) from gao.table3;
    AVG(DISTINCTSAL)
    ----------------
    3333.33
    SQL> select avg(all sal) from gao.table3;
    AVG(ALLSAL)
    -----------
    2592.59

    61.MAX(DISTINCT|ALL)
    求最大值,ALL表示对所有的值求最大值,DISTINCT表示对不同的值求最大值,相同的只取一次
    SQL> select max(distinct sal) from scott.emp;
    MAX(DISTINCTSAL)
    ----------------
    5000

    62.MIN(DISTINCT|ALL)
    求最小值,ALL表示对所有的值求最小值,DISTINCT表示对不同的值求最小值,相同的只取一次
    SQL> select min(all sal) from gao.table3;
    MIN(ALLSAL)
    -----------
    1111.11

    63.STDDEV(distinct|all)
    求标准差,ALL表示对所有的值求标准差,DISTINCT表示只对不同的值求标准差
    SQL> select stddev(sal) from scott.emp;
    STDDEV(SAL)
    -----------
    1182.5032
    SQL> select stddev(distinct sal) from scott.emp;
    STDDEV(DISTINCTSAL)
    -------------------
    1229.951

    64.VARIANCE(DISTINCT|ALL)
    求协方差
    SQL> select variance(sal) from scott.emp;
    VARIANCE(SAL)
    -------------
    1398313.9

    65.GROUP BY
    主要用来对一组数进行统计
    SQL> select deptno,count(*),sum(sal) from scott.emp group by deptno;
    DEPTNO COUNT(*) SUM(SAL)
    --------- --------- ---------
    10 3 8750
    20 5 10875
    30 6 9400

    66.HAVING
    对分组统计再加限制条件
    SQL> select deptno,count(*),sum(sal) from scott.emp group by deptno having count(*)>=5;
    DEPTNO COUNT(*) SUM(SAL)
    --------- --------- ---------
    20 5 10875
    30 6 9400
    SQL> select deptno,count(*),sum(sal) from scott.emp having count(*)>=5 group by deptno ;
    DEPTNO COUNT(*) SUM(SAL)
    --------- --------- ---------
    20 5 10875
    30 6 9400

    67.ORDER BY
    用于对查询到的结果进行排序输出
    SQL> select deptno,ename,sal from scott.emp order by deptno,sal desc;
    DEPTNO ENAME SAL
    --------- ---------- ---------
    10 KING 5000
    10 CLARK 2450
    10 MILLER 1300
    20 SCOTT 3000
    20 FORD 3000
    20 JONES 2975
    20 ADAMS 1100
    20 SMITH 800
    30 BLAKE 2850
    30 ALLEN 1600
    30 TURNER 1500
    30 WARD 1250
    30 MARTIN 1250
    30 JAMES 950
    68. pl/sql中的case语句
    select  (case  when  DUMMY='X'  then  0  else  1  end)  as  flag  from  dual;
    case的第1种用法:
    case col when 'a' then 1
    when 'b' then 2
    else 0 end
    这种用法跟decode一样没什么区别
    case的第2种用法:
    case when score <60 then 'd'
    when score >=60 and score <70 then 'c'
    when score >=70 and score <80 then 'b'
    else 'a' end
    69.NVL(expr1, expr2)
    NVL(expr1, expr2)->expr1为NULL,返回expr2;不为NULL,返回expr1。注意两者的类型要一致
    NVL2 (expr1, expr2, expr3) ->expr1不为NULL,返回expr2;为NULL,返回expr3。expr2和expr3类型不同的话,expr3会转换为expr2的类型
    NULLIF (expr1, expr2) ->相等返回NULL,不等返回expr1
    • Oracle分析函数参考手册
    =============================================
    作者: xsb([url]http://xsb.itpub.net)[/url]
    发表于:2006.03.01 12:22
    分类: DW&BI
    出处:http://xsb.itpub.net/post/419/33028
    ---------------------------------------------------------------
        Oracle从8.1.6开始提供分析函数,分析函数用于计算基于组的某种聚合值,它和聚合函数的不同之处是对于每个组返回多行,
    而聚合函数对于每个组只返回一行。
    常用的分析函数如下所列:
    row_number() over(partition by ... order by ...)
    rank() over(partition by ... order by ...)
    dense_rank() over(partition by ... order by ...)
    count() over(partition by ... order by ...)
    max() over(partition by ... order by ...)
    min() over(partition by ... order by ...)
    sum() over(partition by ... order by ...)
    avg() over(partition by ... order by ...)
    first_value() over(partition by ... order by ...)
    last_value() over(partition by ... order by ...)
    lag() over(partition by ... order by ...)
    lead() over(partition by ... order by ...)

        下面例子中使用的表来自Oracle自带的HR用户下的表,如果没有安装该用户,可以在SYS用户下运行
    $ORACLE_HOME/demo/schema/human_resources/hr_main.sql来创建。
    除本文内容外,你还可参考:
    ROLLUP与CUBE [url]http://xsb.itpub.net/post/419/29159[/url]
    分析函数使用例子介绍:[url]http://xsb.itpub.net/post/419/44634[/url]
    本文如果未指明,缺省是在HR用户下运行例子。
    开窗函数的的理解:
    开窗函数指定了分析函数工作的数据窗口大小,这个数据窗口大小可能会随着行的变化而变化,举例如下:
    over(order by salary) 按照salary排序进行累计,order by是个默认的开窗函数
    over(partition by deptno)按照部门分区
    over(order by salary range between 50 preceding and 150 following)
    每行对应的数据窗口是之前行幅度值不超过50,之后行幅度值不超过150
    over(order by salary rows between 50 preceding and 150 following)
    每行对应的数据窗口是之前50行,之后150行
    over(order by salary rows between unbounded preceding and unbounded following)
    每行对应的数据窗口是从第一行到最后一行,等效:
    over(order by salary range between unbounded preceding and unbounded following)
    主要参考资料:《expert one-on-one》 Tom Kyte 《Oracle9i SQL Reference》第6章
    ohwww 2007-3-12 09:19


    70。AVG
    功能描述:用于计算一个组和数据窗口内表达式的平均值。
    SAMPLE:下面的例子中列c_mavg计算员工表中每个员工的平均薪水报告,该平均值由当前员工和与之具有相同经理的前一个和后一个三者的平均数得来;
    SELECT manager_id, last_name, hire_date, salary,
    AVG(salary) OVER (PARTITION BY manager_id ORDER BY hire_date
    ROWS BETWEEN 1 PRECEDING AND 1 FOLLOWING) AS c_mavg
    FROM employees;
    MANAGER_ID LAST_NAME HIRE_DATE SALARY C_MAVG
    ---------- ------------------------- --------- ---------- ----------
    100 Kochhar 21-SEP-89 17000 17000
    100 De Haan 13-JAN-93 17000 15000
    100 Raphaely 07-DEC-94 11000 11966.6667
    100 Kaufling 01-MAY-95 7900 10633.3333
    100 Hartstein 17-FEB-96 13000 9633.33333
    100 Weiss 18-JUL-96 8000 11666.6667
    100 Russell 01-OCT-96 14000 11833.3333
    71。CORR
    功能描述:返回一对表达式的相关系数,它是如下的缩写:
    COVAR_POP(expr1,expr2)/STDDEV_POP(expr1)*STDDEV_POP(expr2))
    从统计上讲,相关性是变量之间关联的强度,变量之间的关联意味着在某种程度
    上一个变量的值可由其它的值进行预测。通过返回一个-1~1之间的一个数, 相关
    系数给出了关联的强度,0表示不相关。
    SAMPLE:下例返回1998年月销售收入和月单位销售的关系的累积系数(本例在SH用户下运行)
    SELECT t.calendar_month_number,
    CORR (SUM(s.amount_sold), SUM(s.quantity_sold))
    OVER (ORDER BY t.calendar_month_number) as CUM_CORR
    FROM sales s, times t
    WHERE s.time_id = t.time_id AND calendar_year = 1998
    GROUP BY t.calendar_month_number
    ORDER BY t.calendar_month_number;
    CALENDAR_MONTH_NUMBER CUM_CORR
    --------------------- ----------
    1
    2 1
    3 .994309382
    4 .852040875
    5 .846652204
    6 .871250628
    7 .910029803
    8 .917556399
    9 .920154356
    10 .86720251
    11 .844864765
    12 .903542662

    72。COVAR_POP
    功能描述:返回一对表达式的总体协方差。
    SAMPLE:下例CUM_COVP返回定价和最小产品价格的累积总体协方差
    SELECT product_id, supplier_id,
    COVAR_POP(list_price, min_price)
    OVER (ORDER BY product_id, supplier_id) AS CUM_COVP,
    COVAR_SAMP(list_price, min_price)
    OVER (ORDER BY product_id, supplier_id) AS CUM_COVS
    FROM product_information p
    WHERE category_id = 29
    ORDER BY product_id, supplier_id;
    PRODUCT_ID SUPPLIER_ID CUM_COVP CUM_COVS
    ---------- ----------- ---------- ----------
    1774 103088 0
    1775 103087 1473.25 2946.5
    1794 103096 1702.77778 2554.16667
    1825 103093 1926.25 2568.33333
    2004 103086 1591.4 1989.25
    2005 103086 1512.5 1815
    2416 103088 1475.97959 1721.97619
    .
    .

    73。COVAR_SAMP
    功能描述:返回一对表达式的样本协方差
    SAMPLE:下例CUM_COVS返回定价和最小产品价格的累积样本协方差
    SELECT product_id, supplier_id,
    COVAR_POP(list_price, min_price)
    OVER (ORDER BY product_id, supplier_id) AS CUM_COVP,
    COVAR_SAMP(list_price, min_price)
    OVER (ORDER BY product_id, supplier_id) AS CUM_COVS
    FROM product_information p
    WHERE category_id = 29
    ORDER BY product_id, supplier_id;
    PRODUCT_ID SUPPLIER_ID CUM_COVP CUM_COVS
    ---------- ----------- ---------- ----------
    1774 103088 0
    1775 103087 1473.25 2946.5
    1794 103096 1702.77778 2554.16667
    1825 103093 1926.25 2568.33333
    2004 103086 1591.4 1989.25
    2005 103086 1512.5 1815
    2416 103088 1475.97959 1721.97619
    • 74。COUNT
    功能描述:对一组内发生的事情进行累积计数,如果指定*或一些非空常数,count将对所有行计数,如果指定一个表达式,count
    返回表达式非空赋值的计数,当有相同值出现时,这些相等的值都会被纳入被计算的值;可以使用DISTINCT来记录去掉一组中完全
    相同的数据后出现的行数。
    SAMPLE:下面例子中计算每个员工在按薪水排序中当前行附近薪水在[n-50,n+150]之间的行数,n表示当前行的薪水
    例如,Philtanker的薪水2200,排在他之前的行中薪水大于等于2200-50的有1行,排在他之后的行中薪水小于等于2200+150的行
    没有,所以count计数值cnt3为2(包括自己当前行);cnt2值相当于小于等于当前行的SALARY值的所有行数
    SELECT last_name, salary, COUNT(*) OVER () AS cnt1,
    COUNT(*) OVER (ORDER BY salary) AS cnt2,
    COUNT(*) OVER (ORDER BY salary RANGE BETWEEN 50 PRECEDING
    AND 150 FOLLOWING) AS cnt3 FROM employees;
    LAST_NAME SALARY CNT1 CNT2 CNT3
    ------------------------- ---------- ---------- ---------- ----------
    Olson 2100 107 1 3
    Markle 2200 107 3 2
    Philtanker 2200 107 3 2
    Landry 2400 107 5 8
    Gee 2400 107 5 8
    Colmenares 2500 107 11 10
    Patel 2500 107 11 10
    .
    .
    75。CUME_DIST
    功能描述:计算一行在组中的相对位置,CUME_DIST总是返回大于0、小于或等于1的数,该数表示该行在N行中的位置。例如,
    在一个3行的组中,返回的累计分布值为1/3、2/3、3/3
    SAMPLE:下例中计算每个工种的员工按薪水排序依次累积出现的分布百分比
    SELECT job_id, last_name, salary, CUME_DIST()
    OVER (PARTITION BY job_id ORDER BY salary) AS cume_dist
    FROM employees WHERE job_id LIKE 'PU%';
    JOB_ID LAST_NAME SALARY CUME_DIST
    ---------- ------------------------- ---------- ----------
    PU_CLERK Colmenares 2500 .2
    PU_CLERK Himuro 2600 .4
    PU_CLERK Tobias 2800 .6
    PU_CLERK Baida 2900 .8
    PU_CLERK Khoo 3100 1
    PU_MAN Raphaely 11000 1
    76。DENSE_RANK
    功能描述:根据ORDER BY子句中表达式的值,从查询返回的每一行,计算它们与其它行的相对位置。组内的数据按ORDER BY子句排序,然后给每一行赋一个号,从而形成一个序列,该序列从1开始,往后累加。每次ORDER BY表达式的值发生变化时,该序列也随之增加。有同样值的行得到同样的数字序号(认为null时相等的)。密集的序列返回的时没有间隔的数
    SAMPLE:下例中计算每个员工按部门分区再按薪水排序,依次出现的序列号(注意与RANK函数的区别)
    SELECT d.department_id , e.last_name, e.salary, DENSE_RANK()
    OVER (PARTITION BY e.department_id ORDER BY e.salary) as drank
    FROM employees e, departments d
    WHERE e.department_id = d.department_id
    AND d.department_id IN ('60', '90');
    DEPARTMENT_ID LAST_NAME SALARY DRANK
    ------------- ------------------------- ---------- ----------
    60 Lorentz 4200 1
    60 Austin 4800 2
    60 Pataballa 4800 2
    60 Ernst 6000 3
    60 Hunold 9000 4
    90 Kochhar 17000 1
    90 De Haan 17000 1
    90 King 24000 2

    77。FIRST
    功能描述:从DENSE_RANK返回的集合中取出排在最前面的一个值的行(可能多行,因为值可能相等),因此完整的语法需要在开始处加上一个集合函数以从中取出记录
    SAMPLE:下面例子中DENSE_RANK按部门分区,再按佣金commission_pct排序,FIRST取出佣金最低的对应的所有行,然后前面的MAX函数从这个集合中取出薪水最低的值;LAST取出佣金最高的对应的所有行,然后前面的MIN函数从这个集合中取出薪水最高的值
    SELECT last_name, department_id, salary,
    MIN(salary) KEEP (DENSE_RANK FIRST ORDER BY commission_pct)
    OVER (PARTITION BY department_id) "Worst",
    MAX(salary) KEEP (DENSE_RANK LAST ORDER BY commission_pct)
    OVER (PARTITION BY department_id) "Best"
    FROM employees
    WHERE department_id in (20,80)
    ORDER BY department_id, salary;
    LAST_NAME DEPARTMENT_ID SALARY Worst Best
    ------------------------- ------------- ---------- ---------- ----------
    Fay 20 6000 6000 13000
    Hartstein 20 13000 6000 13000
    Kumar 80 6100 6100 14000
    Banda 80 6200 6100 14000
    Johnson 80 6200 6100 14000
    Ande 80 6400 6100 14000
    Lee 80 6800 6100 14000
    Tuvault 80 7000 6100 14000
    Sewall 80 7000 6100 14000
    Marvins 80 7200 6100 14000
    Bates 80 7300 6100 14000
    .
    .
    .
    78。FIRST_VALUE
    功能描述:返回组中数据窗口的第一个值。
    SAMPLE:下面例子计算按部门分区按薪水排序的数据窗口的第一个值对应的名字,如果薪水的第一个值有多个,则从多个对应的名字中取缺省排序的第一个名字
    SELECT department_id, last_name, salary, FIRST_VALUE(last_name)
    OVER (PARTITION BY department_id ORDER BY salary ASC ) AS lowest_sal
    FROM employees
    WHERE department_id in(20,30);
    DEPARTMENT_ID LAST_NAME SALARY LOWEST_SAL
    ------------- ------------------------- ---------- --------------
    20 Fay 6000 Fay
    20 Hartstein 13000 Fay
    30 Colmenares 2500 Colmenares
    30 Himuro 2600 Colmenares
    30 Tobias 2800 Colmenares
    30 Baida 2900 Colmenares
    30 Khoo 3100 Colmenares
    30 Raphaely 11000 Colmenares

    79。LAG
    功能描述:可以访问结果集中的其它行而不用进行自连接。它允许去处理游标,就好像游标是一个数组一样。在给定组中可参考当前行之前的行,这样就可以从组中与当前行一起选择以前的行。Offset是一个正整数,其默认值为1,若索引超出窗口的范围,就返回默认值(默认返回的是组中第一行),其相反的函数是LEAD
    SAMPLE:下面的例子中列prev_sal返回按hire_date排序的前1行的salary值
    SELECT last_name, hire_date, salary,
    LAG(salary, 1, 0) OVER (ORDER BY hire_date) AS prev_sal
    FROM employees
    WHERE job_id = 'PU_CLERK';
    LAST_NAME HIRE_DATE SALARY PREV_SAL
    ------------------------- ---------- ---------- ----------
    Khoo 18-5月 -95 3100 0
    Tobias 24-7月 -97 2800 3100
    Baida 24-12月-97 2900 2800
    Himuro 15-11月-98 2600 2900
    Colmenares 10-8月 -99 2500 2600
    90。RATIO_TO_REPORT
    功能描述:该函数计算expression/(sum(BLOCKED EXPRESSION的值,它给出相对于总数的百分比,即当前行对sum(expression)的贡献。
    SAMPLE:下例计算每个员工的工资占该类员工总工资的百分比
    SELECT last_name, salary, RATIO_TO_REPORT(salary) OVER () AS rr
    FROM employees
    WHERE job_id = 'PU_CLERK';
    LAST_NAME SALARY RR
    ------------------------- ---------- ----------
    Khoo 3100 .223021583
    Baida 2900 .208633094
    Tobias 2800 .201438849
    Himuro 2600 .18705036
    Colmenares 2500 .179856115
    • 91。REGR_ (Linear Regression) Functions
    功能描述:这些线性回归函数适合最小二乘法回归线,有9个不同的回归函数可使用。
    REGR_SLOPE:返回斜率,等于COVAR_POP(expr1, expr2) / VAR_POP(expr2)
    REGR_INTERCEPT:返回回归线的y截距,等于
    AVG(expr1) - REGR_SLOPE(expr1, expr2) * AVG(expr2)
    REGR_COUNT:返回用于填充回归线的非空数字对的数目
    REGR_R2:返回回归线的决定系数,计算式为:
    If VAR_POP(expr2) = 0 then return NULL
    If VAR_POP(expr1) = 0 and VAR_POP(expr2) != 0 then return 1
    If VAR_POP(expr1) > 0 and VAR_POP(expr2 != 0 then
    return POWER(CORR(expr1,expr),2)
    REGR_AVGX:计算回归线的自变量(expr2)的平均值,去掉了空对(expr1, expr2)后,等于AVG(expr2)
    REGR_AVGY:计算回归线的应变量(expr1)的平均值,去掉了空对(expr1, expr2)后,等于AVG(expr1)
    REGR_SXX: 返回值等于REGR_COUNT(expr1, expr2) * VAR_POP(expr2)
    REGR_SYY: 返回值等于REGR_COUNT(expr1, expr2) * VAR_POP(expr1)
    REGR_SXY: 返回值等于REGR_COUNT(expr1, expr2) * COVAR_POP(expr1, expr2)
    (下面的例子都是在SH用户下完成的)
    SAMPLE 1:下例计算1998年最后三个星期中两种产品(260和270)在周末的销售量中已开发票数量和总数量的累积斜率和回归线的截距
    SELECT t.fiscal_month_number "Month", t.day_number_in_month "Day",
    REGR_SLOPE(s.amount_sold, s.quantity_sold)
    OVER (ORDER BY t.fiscal_month_desc, t.day_number_in_month) AS CUM_SLOPE,
    REGR_INTERCEPT(s.amount_sold, s.quantity_sold)
    OVER (ORDER BY t.fiscal_month_desc, t.day_number_in_month) AS CUM_ICPT
    FROM sales s, times t
    WHERE s.time_id = t.time_id
    AND s.prod_id IN (270, 260)
    AND t.fiscal_year=1998
    AND t.fiscal_week_number IN (50, 51, 52)
    AND t.day_number_in_week IN (6,7)
    ORDER BY t.fiscal_month_desc, t.day_number_in_month;
    Month Day CUM_SLOPE CUM_ICPT
    ---------- ---------- ---------- ----------
    12 12 -68 1872
    12 12 -68 1872
    12 13 -20.244898 1254.36735
    12 13 -20.244898 1254.36735
    12 19 -18.826087 1287
    12 20 62.4561404 125.28655
    12 20 62.4561404 125.28655
    12 20 62.4561404 125.28655
    12 20 62.4561404 125.28655
    12 26 67.2658228 58.9712313
    12 26 67.2658228 58.9712313
    12 27 37.5245541 284.958221
    12 27 37.5245541 284.958221
    12 27 37.5245541 284.958221
    SAMPLE 2:下例计算1998年4月每天的累积交易数量
    SELECT UNIQUE t.day_number_in_month,
    REGR_COUNT(s.amount_sold, s.quantity_sold)
    OVER (PARTITION BY t.fiscal_month_number ORDER BY t.day_number_in_month)
    "Regr_Count"
    FROM sales s, times t
    WHERE s.time_id = t.time_id
    AND t.fiscal_year = 1998 AND t.fiscal_month_number = 4;
    DAY_NUMBER_IN_MONTH Regr_Count
    ------------------- ----------
    1 825
    2 1650
    3 2475
    4 3300

    26 21450
    30 22200
    SAMPLE 3:下例计算1998年每月销售量中已开发票数量和总数量的累积回归线决定系数
    SELECT t.fiscal_month_number,
    REGR_R2(SUM(s.amount_sold), SUM(s.quantity_sold))
    OVER (ORDER BY t.fiscal_month_number) "Regr_R2"
    FROM sales s, times t
    WHERE s.time_id = t.time_id
    AND t.fiscal_year = 1998
    GROUP BY t.fiscal_month_number
    ORDER BY t.fiscal_month_number;
    FISCAL_MONTH_NUMBER Regr_R2
    ------------------- ----------
    1
    2 1
    3 .927372984
    4 .807019972
    5 .932745567
    6 .94682861
    7 .965342011
    8 .955768075
    9 .959542618
    10 .938618575
    11 .880931415
    12 .882769189
    SAMPLE 4:下例计算1998年12月最后两周产品260的销售量中已开发票数量和总数量的累积平均值
    SELECT t.day_number_in_month,
    REGR_AVGY(s.amount_sold, s.quantity_sold)
    OVER (ORDER BY t.fiscal_month_desc, t.day_number_in_month)
    "Regr_AvgY",
    REGR_AVGX(s.amount_sold, s.quantity_sold)
    OVER (ORDER BY t.fiscal_month_desc, t.day_number_in_month)
    "Regr_AvgX"
    FROM sales s, times t
    WHERE s.time_id = t.time_id
    AND s.prod_id = 260
    AND t.fiscal_month_desc = '1998-12'
    AND t.fiscal_week_number IN (51, 52)
    ORDER BY t.day_number_in_month;
    DAY_NUMBER_IN_MONTH Regr_AvgY Regr_AvgX
    ------------------- ---------- ----------
    14 882 24.5
    14 882 24.5
    15 801 22.25
    15 801 22.25
    16 777.6 21.6
    18 642.857143 17.8571429
    18 642.857143 17.8571429
    20 589.5 16.375
    21 544 15.1111111
    22 592.363636 16.4545455
    22 592.363636 16.4545455
    24 553.846154 15.3846154
    24 553.846154 15.3846154
    26 522 14.5
    27 578.4 16.0666667
    SAMPLE 5:下例计算产品260和270在1998年2月周末销售量中已开发票数量和总数量的累积REGR_SXY, REGR_SXX, and REGR_SYY统计值
    SELECT t.day_number_in_month,
    REGR_SXY(s.amount_sold, s.quantity_sold)
    OVER (ORDER BY t.fiscal_year, t.fiscal_month_desc) "Regr_sxy",
    REGR_SYY(s.amount_sold, s.quantity_sold)
    OVER (ORDER BY t.fiscal_year, t.fiscal_month_desc) "Regr_syy",
    REGR_SXX(s.amount_sold, s.quantity_sold)
    OVER (ORDER BY t.fiscal_year, t.fiscal_month_desc) "Regr_sxx"
    FROM sales s, times t
    WHERE s.time_id = t.time_id
    AND prod_id IN (270, 260)
    AND t.fiscal_month_desc = '1998-02'
    AND t.day_number_in_week IN (6,7)
    ORDER BY t.day_number_in_month;
    DAY_NUMBER_IN_MONTH Regr_sxy Regr_syy Regr_sxx
    ------------------- ---------- ---------- ----------
    1 18870.4 2116198.4 258.4
    1 18870.4 2116198.4 258.4
    1 18870.4 2116198.4 258.4
    1 18870.4 2116198.4 258.4
    7 18870.4 2116198.4 258.4
    8 18870.4 2116198.4 258.4
    14 18870.4 2116198.4 258.4
    15 18870.4 2116198.4 258.4
    21 18870.4 2116198.4 258.4
    22 18870.4 2116198.4 258.4

     

    • 92。ROW_NUMBER
    功能描述:返回有序组中一行的偏移量,从而可用于按特定标准排序的行号。
    SAMPLE:下例返回每个员工再在每个部门中按员工号排序后的顺序号
    SELECT department_id, last_name, employee_id, ROW_NUMBER()
    OVER (PARTITION BY department_id ORDER BY employee_id) AS emp_id
    FROM employees
    WHERE department_id < 50;
    DEPARTMENT_ID LAST_NAME EMPLOYEE_ID EMP_ID
    ------------- ------------------------- ----------- ----------
    10 Whalen 200 1
    20 Hartstein 201 1
    20 Fay 202 2
    30 Raphaely 114 1
    30 Khoo 115 2
    30 Baida 116 3
    30 Tobias 117 4
    30 Himuro 118 5
    30 Colmenares 119 6
    40 Mavris 203 1
    93。STDDEV
    功能描述:计算当前行关于组的标准偏离。(Standard Deviation)
    SAMPLE:下例返回部门30按雇佣日期排序的薪水值的累积标准偏离
    SELECT last_name, hire_date,salary,
    STDDEV(salary) OVER (ORDER BY hire_date) "StdDev"
    FROM employees
    WHERE department_id = 30;
    LAST_NAME HIRE_DATE SALARY StdDev
    ------------------------- ---------- ---------- ----------
    Raphaely 07-12月-94 11000 0
    Khoo 18-5月 -95 3100 5586.14357
    Tobias 24-7月 -97 2800 4650.0896
    Baida 24-12月-97 2900 4035.26125
    Himuro 15-11月-98 2600 3649.2465
    Colmenares 10-8月 -99 2500 3362.58829
    94。STDDEV_POP
    功能描述:该函数计算总体标准偏离,并返回总体变量的平方根,其返回值与VAR_POP函数的平方根相同。(Standard Deviation-Population)
    SAMPLE:下例返回部门20、30、60的薪水值的总体标准偏差
    SELECT department_id, last_name, salary,
    STDDEV_POP(salary) OVER (PARTITION BY department_id) AS pop_std
    FROM employees
    WHERE department_id in (20,30,60);
    DEPARTMENT_ID LAST_NAME SALARY POP_STD
    ------------- ------------------------- ---------- ----------
    20 Hartstein 13000 3500
    20 Fay 6000 3500
    30 Raphaely 11000 3069.6091
    30 Khoo 3100 3069.6091
    30 Baida 2900 3069.6091
    30 Colmenares 2500 3069.6091
    30 Himuro 2600 3069.6091
    30 Tobias 2800 3069.6091
    60 Hunold 9000 1722.32401
    60 Ernst 6000 1722.32401
    60 Austin 4800 1722.32401
    60 Pataballa 4800 1722.32401
    60 Lorentz 4200 1722.32401

     

    95。STDDEV_SAMP
    功能描述: 该函数计算累积样本标准偏离,并返回总体变量的平方根,其返回值与VAR_POP函数的平方根相同。(Standard Deviation-Sample)
    SAMPLE:下例返回部门20、30、60的薪水值的样本标准偏差
    SELECT department_id, last_name, hire_date, salary,
    STDDEV_SAMP(salary) OVER
    (PARTITION BY department_id ORDER BY hire_date
    ROWS BETWEEN UNBOUNDED PRECEDING AND CURRENT ROW) AS cum_sdev
    FROM employees
    WHERE department_id in (20,30,60);
    DEPARTMENT_ID LAST_NAME HIRE_DATE SALARY CUM_SDEV
    ------------- ------------------------- ---------- ---------- ----------
    20 Hartstein 17-2月 -96 13000
    20 Fay 17-8月 -97 6000 4949.74747
    30 Raphaely 07-12月-94 11000
    30 Khoo 18-5月 -95 3100 5586.14357
    30 Tobias 24-7月 -97 2800 4650.0896
    30 Baida 24-12月-97 2900 4035.26125
    30 Himuro 15-11月-98 2600 3649.2465
    30 Colmenares 10-8月 -99 2500 3362.58829
    60 Hunold 03-1月 -90 9000
    60 Ernst 21-5月 -91 6000 2121.32034
    60 Austin 25-6月 -97 4800 2163.33077
    60 Pataballa 05-2月 -98 4800 1982.42276
    60 Lorentz 07-2月 -99 4200 1925.61678

    96。SUM
    功能描述:该函数计算组中表达式的累积和。
    SAMPLE:下例计算同一经理下员工的薪水累积值
    SELECT manager_id, last_name, salary,
    SUM (salary) OVER (PARTITION BY manager_id ORDER BY salary
    RANGE UNBOUNDED PRECEDING) l_csum
    FROM employees
    WHERE manager_id in (101,103,108);
    MANAGER_ID LAST_NAME SALARY L_CSUM
    ---------- ------------------------- ---------- ----------
    101 Whalen 4400 4400
    101 Mavris 6500 10900
    101 Baer 10000 20900
    101 Greenberg 12000 44900
    101 Higgins 12000 44900
    103 Lorentz 4200 4200
    103 Austin 4800 13800
    103 Pataballa 4800 13800
    103 Ernst 6000 19800
    108 Popp 6900 6900
    108 Sciarra 7700 14600
    108 Urman 7800 22400
    108 Chen 8200 30600
    108 Faviet 9000 39600
    97。VAR_POP
    功能描述:(Variance Population)该函数返回非空集合的总体变量(忽略null),VAR_POP进行如下计算:
    (SUM(expr2) - SUM(expr)2 / COUNT(expr)) / COUNT(expr)
    SAMPLE:下例计算1998年每月销售的累积总体和样本变量(本例在SH用户下运行)
    SELECT t.calendar_month_desc,
    VAR_POP(SUM(s.amount_sold))
    OVER (ORDER BY t.calendar_month_desc) "Var_Pop",
    VAR_SAMP(SUM(s.amount_sold))
    OVER (ORDER BY t.calendar_month_desc) "Var_Samp"
    FROM sales s, times t
    WHERE s.time_id = t.time_id AND t.calendar_year = 1998
    GROUP BY t.calendar_month_desc;
    CALENDAR Var_Pop Var_Samp
    -------- ---------- ----------
    1998-01 0
    1998-02 6.1321E+11 1.2264E+12
    1998-03 4.7058E+11 7.0587E+11
    1998-04 4.6929E+11 6.2572E+11
    1998-05 1.5524E+12 1.9405E+12
    1998-06 2.3711E+12 2.8453E+12
    1998-07 3.7464E+12 4.3708E+12
    1998-08 3.7852E+12 4.3260E+12
    1998-09 3.5753E+12 4.0222E+12
    1998-10 3.4343E+12 3.8159E+12
    1998-11 3.4245E+12 3.7669E+12
    1998-12 4.8937E+12 5.3386E+12
    • 98。VAR_SAMP
    功能描述:(Variance Sample)该函数返回非空集合的样本变量(忽略null),VAR_POP进行如下计算:
    (SUM(expr*expr)-SUM(expr)*SUM(expr)/COUNT(expr))/(COUNT(expr)-1)
    SAMPLE:下例计算1998年每月销售的累积总体和样本变量
    SELECT t.calendar_month_desc,
    VAR_POP(SUM(s.amount_sold))
    OVER (ORDER BY t.calendar_month_desc) "Var_Pop",
    VAR_SAMP(SUM(s.amount_sold))
    OVER (ORDER BY t.calendar_month_desc) "Var_Samp"
    FROM sales s, times t
    WHERE s.time_id = t.time_id AND t.calendar_year = 1998
    GROUP BY t.calendar_month_desc;
    CALENDAR Var_Pop Var_Samp
    -------- ---------- ----------
    1998-01 0
    1998-02 6.1321E+11 1.2264E+12
    1998-03 4.7058E+11 7.0587E+11
    1998-04 4.6929E+11 6.2572E+11
    1998-05 1.5524E+12 1.9405E+12
    1998-06 2.3711E+12 2.8453E+12
    1998-07 3.7464E+12 4.3708E+12
    1998-08 3.7852E+12 4.3260E+12
    1998-09 3.5753E+12 4.0222E+12
    1998-10 3.4343E+12 3.8159E+12
    1998-11 3.4245E+12 3.7669E+12
    1998-12 4.8937E+12 5.3386E+12
    99。VARIANCE
    功能描述:该函数返回表达式的变量,Oracle计算该变量如下:
    如果表达式中行数为1,则返回0
    如果表达式中行数大于1,则返回VAR_SAMP
    SAMPLE:下例返回部门30按雇佣日期排序的薪水值的累积变化
    SELECT last_name, salary, VARIANCE(salary)
    OVER (ORDER BY hire_date) "Variance"
    FROM employees
    WHERE department_id = 30;
    LAST_NAME SALARY Variance
    ------------------------- ---------- ----------
    Raphaely 11000 0
    Khoo 3100 31205000
    Tobias 2800 21623333.3
    Baida 2900 16283333.3
    Himuro 2600 13317000
    Colmenares 2500 11307000
    100。RANK
    功能描述:根据ORDER BY子句中表达式的值,从查询返回的每一行,计算它们与其它行的相对位置。组内的数据按ORDER BY子句排序,
    然后给每一行赋一个号,从而形成一个序列,该序列从1开始,往后累加。每次ORDER BY表达式的值发生变化时,该序列也随之增加。
    有同样值的行得到同样的数字序号(认为null时相等的)。然而,如果两行的确得到同样的排序,则序数将随后跳跃。若两行序数为1,
    则没有序数2,序列将给组中的下一行分配值3,DENSE_RANK则没有任何跳跃。
    SAMPLE:下例中计算每个员工按部门分区再按薪水排序,依次出现的序列号(注意与DENSE_RANK函数的区别)
    SELECT d.department_id , e.last_name, e.salary, RANK()
    OVER (PARTITION BY e.department_id ORDER BY e.salary) as drank
    FROM employees e, departments d
    WHERE e.department_id = d.department_id
    AND d.department_id IN ('60', '90');
    DEPARTMENT_ID LAST_NAME SALARY DRANK
    ------------- ------------------------- ---------- ----------
    60 Lorentz 4200 1
    60 Austin 4800 2
    60 Pataballa 4800 2
    60 Ernst 6000 4
    60 Hunold 9000 5
    90 Kochhar 17000 1
    90 De Haan 17000 1
    90 King 24000 3

     

    101。RATIO_TO_REPORT
    功能描述:该函数计算expression/(sum(BLOCKED EXPRESSION的值,它给出相对于总数的百分比,即当前行对sum(expression)的贡献。
    SAMPLE:下例计算每个员工的工资占该类员工总工资的百分比
    SELECT last_name, salary, RATIO_TO_REPORT(salary) OVER () AS rr
    FROM employees
    WHERE job_id = 'PU_CLERK';
    LAST_NAME SALARY RR
    ------------------------- ---------- ----------
    Khoo 3100 .223021583
    Baida 2900 .208633094
    Tobias 2800 .201438849
    Himuro 2600 .18705036
    Colmenares 2500 .179856115
    • 102。REGR_ (Linear Regression) Functions
    功能描述:这些线性回归函数适合最小二乘法回归线,有9个不同的回归函数可使用。
    REGR_SLOPE:返回斜率,等于COVAR_POP(expr1, expr2) / VAR_POP(expr2)
    REGR_INTERCEPT:返回回归线的y截距,等于
    AVG(expr1) - REGR_SLOPE(expr1, expr2) * AVG(expr2)
    REGR_COUNT:返回用于填充回归线的非空数字对的数目
    REGR_R2:返回回归线的决定系数,计算式为:
    If VAR_POP(expr2) = 0 then return NULL
    If VAR_POP(expr1) = 0 and VAR_POP(expr2) != 0 then return 1
    If VAR_POP(expr1) > 0 and VAR_POP(expr2 != 0 then
    return POWER(CORR(expr1,expr),2)
    REGR_AVGX:计算回归线的自变量(expr2)的平均值,去掉了空对(expr1, expr2)后,等于AVG(expr2)
    REGR_AVGY:计算回归线的应变量(expr1)的平均值,去掉了空对(expr1, expr2)后,等于AVG(expr1)
    REGR_SXX: 返回值等于REGR_COUNT(expr1, expr2) * VAR_POP(expr2)
    REGR_SYY: 返回值等于REGR_COUNT(expr1, expr2) * VAR_POP(expr1)
    REGR_SXY: 返回值等于REGR_COUNT(expr1, expr2) * COVAR_POP(expr1, expr2)
    (下面的例子都是在SH用户下完成的)
    SAMPLE 1:下例计算1998年最后三个星期中两种产品(260和270)在周末的销售量中已开发票数量和总数量的累积斜率和回归线的截距
    SELECT t.fiscal_month_number "Month", t.day_number_in_month "Day",
    REGR_SLOPE(s.amount_sold, s.quantity_sold)
    OVER (ORDER BY t.fiscal_month_desc, t.day_number_in_month) AS CUM_SLOPE,
    REGR_INTERCEPT(s.amount_sold, s.quantity_sold)
    OVER (ORDER BY t.fiscal_month_desc, t.day_number_in_month) AS CUM_ICPT
    FROM sales s, times t
    WHERE s.time_id = t.time_id
    AND s.prod_id IN (270, 260)
    AND t.fiscal_year=1998
    AND t.fiscal_week_number IN (50, 51, 52)
    AND t.day_number_in_week IN (6,7)
    ORDER BY t.fiscal_month_desc, t.day_number_in_month;
    Month Day CUM_SLOPE CUM_ICPT
    ---------- ---------- ---------- ----------
    12 12 -68 1872
    12 12 -68 1872
    12 13 -20.244898 1254.36735
    12 13 -20.244898 1254.36735
    12 19 -18.826087 1287
    12 20 62.4561404 125.28655
    12 20 62.4561404 125.28655
    12 20 62.4561404 125.28655
    12 20 62.4561404 125.28655
    12 26 67.2658228 58.9712313
    12 26 67.2658228 58.9712313
    12 27 37.5245541 284.958221
    12 27 37.5245541 284.958221
    12 27 37.5245541 284.958221
    SAMPLE 2:下例计算1998年4月每天的累积交易数量
    SELECT UNIQUE t.day_number_in_month,
    REGR_COUNT(s.amount_sold, s.quantity_sold)
    OVER (PARTITION BY t.fiscal_month_number ORDER BY t.day_number_in_month)
    "Regr_Count"
    FROM sales s, times t
    WHERE s.time_id = t.time_id
    AND t.fiscal_year = 1998 AND t.fiscal_month_number = 4;
    DAY_NUMBER_IN_MONTH Regr_Count
    ------------------- ----------
    1 825
    2 1650
    3 2475
    4 3300
    .
    26 21450
    30 22200
    SAMPLE 3:下例计算1998年每月销售量中已开发票数量和总数量的累积回归线决定系数
    SELECT t.fiscal_month_number,
    REGR_R2(SUM(s.amount_sold), SUM(s.quantity_sold))
    OVER (ORDER BY t.fiscal_month_number) "Regr_R2"
    FROM sales s, times t
    WHERE s.time_id = t.time_id
    AND t.fiscal_year = 1998
    GROUP BY t.fiscal_month_number
    ORDER BY t.fiscal_month_number;
    FISCAL_MONTH_NUMBER Regr_R2
    ------------------- ----------
    1
    2 1
    3 .927372984
    4 .807019972
    5 .932745567
    6 .94682861
    7 .965342011
    8 .955768075
    9 .959542618
    10 .938618575
    11 .880931415
    12 .882769189
    SAMPLE 4:下例计算1998年12月最后两周产品260的销售量中已开发票数量和总数量的累积平均值
    SELECT t.day_number_in_month,
    REGR_AVGY(s.amount_sold, s.quantity_sold)
    OVER (ORDER BY t.fiscal_month_desc, t.day_number_in_month)
    "Regr_AvgY",
    REGR_AVGX(s.amount_sold, s.quantity_sold)
    OVER (ORDER BY t.fiscal_month_desc, t.day_number_in_month)
    "Regr_AvgX"
    FROM sales s, times t
    WHERE s.time_id = t.time_id
    AND s.prod_id = 260
    AND t.fiscal_month_desc = '1998-12'
    AND t.fiscal_week_number IN (51, 52)
    ORDER BY t.day_number_in_month;
    DAY_NUMBER_IN_MONTH Regr_AvgY Regr_AvgX
    ------------------- ---------- ----------
    14 882 24.5
    14 882 24.5
    15 801 22.25
    15 801 22.25
    16 777.6 21.6
    18 642.857143 17.8571429
    18 642.857143 17.8571429
    20 589.5 16.375
    21 544 15.1111111
    22 592.363636 16.4545455
    22 592.363636 16.4545455
    24 553.846154 15.3846154
    24 553.846154 15.3846154
    26 522 14.5
    27 578.4 16.0666667
    SAMPLE 5:下例计算产品260和270在1998年2月周末销售量中已开发票数量和总数量的累积REGR_SXY, REGR_SXX, and REGR_SYY统计值
    SELECT t.day_number_in_month,
    REGR_SXY(s.amount_sold, s.quantity_sold)
    OVER (ORDER BY t.fiscal_year, t.fiscal_month_desc) "Regr_sxy",
    REGR_SYY(s.amount_sold, s.quantity_sold)
    OVER (ORDER BY t.fiscal_year, t.fiscal_month_desc) "Regr_syy",
    REGR_SXX(s.amount_sold, s.quantity_sold)
    OVER (ORDER BY t.fiscal_year, t.fiscal_month_desc) "Regr_sxx"
    FROM sales s, times t
    WHERE s.time_id = t.time_id
    AND prod_id IN (270, 260)
    AND t.fiscal_month_desc = '1998-02'
    AND t.day_number_in_week IN (6,7)
    ORDER BY t.day_number_in_month;
    DAY_NUMBER_IN_MONTH Regr_sxy Regr_syy Regr_sxx
    ------------------- ---------- ---------- ----------
    1 18870.4 2116198.4 258.4
    1 18870.4 2116198.4 258.4
    1 18870.4 2116198.4 258.4
    1 18870.4 2116198.4 258.4
    7 18870.4 2116198.4 258.4
    8 18870.4 2116198.4 258.4
    14 18870.4 2116198.4 258.4
    15 18870.4 2116198.4 258.4
    21 18870.4 2116198.4 258.4
    22 18870.4 2116198.4 258.4
    • 103。ROW_NUMBER
    功能描述:返回有序组中一行的偏移量,从而可用于按特定标准排序的行号。
    SAMPLE:下例返回每个员工再在每个部门中按员工号排序后的顺序号
    SELECT department_id, last_name, employee_id, ROW_NUMBER()
    OVER (PARTITION BY department_id ORDER BY employee_id) AS emp_id
    FROM employees
    WHERE department_id < 50;
    DEPARTMENT_ID LAST_NAME EMPLOYEE_ID EMP_ID
    ------------- ------------------------- ----------- ----------
    10 Whalen 200 1
    20 Hartstein 201 1
    20 Fay 202 2
    30 Raphaely 114 1
    30 Khoo 115 2
    30 Baida 116 3
    30 Tobias 117 4
    30 Himuro 118 5
    30 Colmenares 119 6
    40 Mavris 203 1
    104。STDDEV
    功能描述:计算当前行关于组的标准偏离。(Standard Deviation)
    SAMPLE:下例返回部门30按雇佣日期排序的薪水值的累积标准偏离
    SELECT last_name, hire_date,salary,
    STDDEV(salary) OVER (ORDER BY hire_date) "StdDev"
    FROM employees
    WHERE department_id = 30;
    LAST_NAME HIRE_DATE SALARY StdDev
    ------------------------- ---------- ---------- ----------
    Raphaely 07-12月-94 11000 0
    Khoo 18-5月 -95 3100 5586.14357
    Tobias 24-7月 -97 2800 4650.0896
    Baida 24-12月-97 2900 4035.26125
    Himuro 15-11月-98 2600 3649.2465
    Colmenares 10-8月 -99 2500 3362.58829

     

    105。STDDEV_POP
    功能描述:该函数计算总体标准偏离,并返回总体变量的平方根,其返回值与VAR_POP函数的平方根相同。(Standard Deviation-Population)
    SAMPLE:下例返回部门20、30、60的薪水值的总体标准偏差
    SELECT department_id, last_name, salary,
    STDDEV_POP(salary) OVER (PARTITION BY department_id) AS pop_std
    FROM employees
    WHERE department_id in (20,30,60);
    DEPARTMENT_ID LAST_NAME SALARY POP_STD
    ------------- ------------------------- ---------- ----------
    20 Hartstein 13000 3500
    20 Fay 6000 3500
    30 Raphaely 11000 3069.6091
    30 Khoo 3100 3069.6091
    30 Baida 2900 3069.6091
    30 Colmenares 2500 3069.6091
    30 Himuro 2600 3069.6091
    30 Tobias 2800 3069.6091
    60 Hunold 9000 1722.32401
    60 Ernst 6000 1722.32401
    60 Austin 4800 1722.32401
    60 Pataballa 4800 1722.32401
    60 Lorentz 4200 1722.32401
    106。STDDEV_SAMP
    功能描述: 该函数计算累积样本标准偏离,并返回总体变量的平方根,其返回值与VAR_POP函数的平方根相同。(Standard Deviation-Sample)
    SAMPLE:下例返回部门20、30、60的薪水值的样本标准偏差
    SELECT department_id, last_name, hire_date, salary,
    STDDEV_SAMP(salary) OVER
    (PARTITION BY department_id ORDER BY hire_date
    ROWS BETWEEN UNBOUNDED PRECEDING AND CURRENT ROW) AS cum_sdev
    FROM employees
    WHERE department_id in (20,30,60);
    DEPARTMENT_ID LAST_NAME HIRE_DATE SALARY CUM_SDEV
    ------------- ------------------------- ---------- ---------- ----------
    20 Hartstein 17-2月 -96 13000
    20 Fay 17-8月 -97 6000 4949.74747
    30 Raphaely 07-12月-94 11000
    30 Khoo 18-5月 -95 3100 5586.14357
    30 Tobias 24-7月 -97 2800 4650.0896
    30 Baida 24-12月-97 2900 4035.26125
    30 Himuro 15-11月-98 2600 3649.2465
    30 Colmenares 10-8月 -99 2500 3362.58829
    60 Hunold 03-1月 -90 9000
    60 Ernst 21-5月 -91 6000 2121.32034
    60 Austin 25-6月 -97 4800 2163.33077
    60 Pataballa 05-2月 -98 4800 1982.42276
    60 Lorentz 07-2月 -99 4200 1925.61678

    107。SUM
    功能描述:该函数计算组中表达式的累积和。
    SAMPLE:下例计算同一经理下员工的薪水累积值
    SELECT manager_id, last_name, salary,
    SUM (salary) OVER (PARTITION BY manager_id ORDER BY salary
    RANGE UNBOUNDED PRECEDING) l_csum
    FROM employees
    WHERE manager_id in (101,103,108);
    MANAGER_ID LAST_NAME SALARY L_CSUM
    ---------- ------------------------- ---------- ----------
    101 Whalen 4400 4400
    101 Mavris 6500 10900
    101 Baer 10000 20900
    101 Greenberg 12000 44900
    101 Higgins 12000 44900
    103 Lorentz 4200 4200
    103 Austin 4800 13800
    103 Pataballa 4800 13800
    103 Ernst 6000 19800
    108 Popp 6900 6900
    108 Sciarra 7700 14600
    108 Urman 7800 22400
    108 Chen 8200 30600
    108 Faviet 9000 39600
    108。VAR_POP
    功能描述:(Variance Population)该函数返回非空集合的总体变量(忽略null),VAR_POP进行如下计算:
    (SUM(expr2) - SUM(expr)2 / COUNT(expr)) / COUNT(expr)
    SAMPLE:下例计算1998年每月销售的累积总体和样本变量(本例在SH用户下运行)
    SELECT t.calendar_month_desc,
    VAR_POP(SUM(s.amount_sold))
    OVER (ORDER BY t.calendar_month_desc) "Var_Pop",
    VAR_SAMP(SUM(s.amount_sold))
    OVER (ORDER BY t.calendar_month_desc) "Var_Samp"
    FROM sales s, times t
    WHERE s.time_id = t.time_id AND t.calendar_year = 1998
    GROUP BY t.calendar_month_desc;
    CALENDAR Var_Pop Var_Samp
    -------- ---------- ----------
    1998-01 0
    1998-02 6.1321E+11 1.2264E+12
    1998-03 4.7058E+11 7.0587E+11
    1998-04 4.6929E+11 6.2572E+11
    1998-05 1.5524E+12 1.9405E+12
    1998-06 2.3711E+12 2.8453E+12
    1998-07 3.7464E+12 4.3708E+12
    1998-08 3.7852E+12 4.3260E+12
    1998-09 3.5753E+12 4.0222E+12
    1998-10 3.4343E+12 3.8159E+12
    1998-11 3.4245E+12 3.7669E+12
    1998-12 4.8937E+12 5.3386E+12
    109。VAR_SAMP
    功能描述:(Variance Sample)该函数返回非空集合的样本变量(忽略null),VAR_POP进行如下计算:
    (SUM(expr*expr)-SUM(expr)*SUM(expr)/COUNT(expr))/(COUNT(expr)-1)
    SAMPLE:下例计算1998年每月销售的累积总体和样本变量
    SELECT t.calendar_month_desc,
    VAR_POP(SUM(s.amount_sold))
    OVER (ORDER BY t.calendar_month_desc) "Var_Pop",
    VAR_SAMP(SUM(s.amount_sold))
    OVER (ORDER BY t.calendar_month_desc) "Var_Samp"
    FROM sales s, times t
    WHERE s.time_id = t.time_id AND t.calendar_year = 1998
    GROUP BY t.calendar_month_desc;
    CALENDAR Var_Pop Var_Samp
    -------- ---------- ----------
    1998-01 0
    1998-02 6.1321E+11 1.2264E+12
    1998-03 4.7058E+11 7.0587E+11
    1998-04 4.6929E+11 6.2572E+11
    1998-05 1.5524E+12 1.9405E+12
    1998-06 2.3711E+12 2.8453E+12
    1998-07 3.7464E+12 4.3708E+12
    1998-08 3.7852E+12 4.3260E+12
    1998-09 3.5753E+12 4.0222E+12
    1998-10 3.4343E+12 3.8159E+12
    1998-11 3.4245E+12 3.7669E+12
    1998-12 4.8937E+12 5.3386E+12
    110。VARIANCE
    功能描述:该函数返回表达式的变量,Oracle计算该变量如下:
    如果表达式中行数为1,则返回0
    如果表达式中行数大于1,则返回VAR_SAMP
    SAMPLE:下例返回部门30按雇佣日期排序的薪水值的累积变化
    SELECT last_name, salary, VARIANCE(salary)
    OVER (ORDER BY hire_date) "Variance"
    FROM employees
    WHERE department_id = 30;
    LAST_NAME SALARY Variance
    ------------------------- ---------- ----------
    Raphaely 11000 0
    Khoo 3100 31205000
    Tobias 2800 21623333.3
    Baida 2900 16283333.3
    Himuro 2600 13317000
    Colmenares 2500 11307000

  • 笑一笑,十年少~超级搞笑的几个小笑话

    有一次坐公交拿了IC卡排队上车,前面一个人是扔硬币的,我大脑短路跟着把IC卡扔进去了……
      ●早上要戴隐形眼镜,结果把盖打开直接把眼镜倒马桶里,然后镇定地倒入新的护理液,准备摘眼镜,半天摘不下来。
      ●邻居忘了带钥匙,从我家阳台翻过去,在屋里找到钥匙后,又翻回来,再打开自家房门。更令人叫绝的是,我自始至终在阳台接应着,未觉有不妥之处。唉,我俩的脑袋肯定被同一个门缝挤过。
      ●某日发现手机不见了,翻遍包包以及屋中各个角落,未果。遂郁闷地跌坐地上,从口袋掏出手机,给大家群发短信:我手机丢了
      ●一次大家打麻将停电了,就点根蜡烛继续打,后来有人嫌热,嚷嚷“喂~把电扇打开”大家忙劝“不行不行,蜡烛会被吹灭。
      ●自从宿舍里装上电话,我们就变成了"君子",君子动口不动手,当然更懒得动腿,有什么事宁可花点电话费,也不愿出门走动走动。我们屋有个小伙儿叫李 雷,暑假找了份工作,在一家网站做程序员。昨天他上班去了,有人打电话找他,我接的。我说李雷不在,对方问他回老家了吗?我说没有,对方说:"那你告诉 他,我是他同学,你让他回来给我打个电话吧,电话号码是××××。"我拿笔记了下来(后来我才知道,其实那是斜对过宿舍的电话,跟我们不太熟)。
      晚上李雷回来,我跟他说了电话的事,他说大概是高中同学打来的吧,于是就按那个电话回了过去。李雷是陕西人,电话一通他就问:"请问你们这儿有陕西的吗? " 接电话的人说:"我们这儿没有,我们对门倒是有一个,你等会儿啊,我给你喊......"
      马上,就听到楼道里大喊:"李雷,过来接电话,你老乡!"
      李雷愣了一下,跟我们屋老三说,我过去接个电话,这儿你帮我盯着,如果通了,就说我一会儿就回来。李雷过去了,老三拿起电话。没过几秒钟,里面就传 出" 喂,喂"的声音,老三马上说:"他出去了,你等一下啊!"然后推开门就喊:"李雷,这个电话通了,赶快回来。"李雷在那边等了会儿,见没反应就挂了,回屋 从老三手里接过电话,只能听到挂断后的"嘟嘟"声。"奇怪!"他郁闷地说:"怎么都没人接呢?"
      然后他拿起记号码的纸条,再次拨通那个号码:"你们这儿有陕西的吗......"
      ●高中时候,班里一哥们,1981年生,不大,就是特老相.....
      以下是他坐公交时发生的一点事情:
      高二时候,这哥们坐公交去学校,因为路途长,百无聊赖的时候,邻座的一个35岁左右的男人跟他搭话,那人张嘴就来句:“大哥,去哪里?”
      这哥们也许是平常遭遇这样的待遇多了,也并不万分惊奇,颇平静的回答:“三中”。
      那男人第二句话:“噢,去看孩子吧?孩子上学挺苦的.....”
      那哥们脸部抽搐了一下,没吭声。
      第三句话:“大哥,你孩子上几年级了?”那哥们是真烦了,也不解释,顺口来了句:”高一”
      这个时候,经典出现了。那男人异常惊奇地瞪大眼睛看着那哥们,看了足足十秒钟,来了句:“大哥,那您结婚可是挺晚的啊!”
      ●我记得我上高中时,见一要好的哥们在校门外买大饼吃,你们也知道嘛,高中时期用脑过度经常会饿,我就马上跑上去先是捶了他一下,然后就夺下他的大饼 就啃了一口,还骂骂咧咧的说,真不够意气,买饼也不带我买一个,结果一口饼还没咽下去,抬眼一看才发现认错人了,这也就算了,我后来居然边说对不起还边把 我咬了一口的
      那个大饼往那男的手里一塞就跑了,整个过程一气呵成!!!
      记得当时跑回学校大门往回看时,那男的还站在摊子前手拿那个缺了个口的大饼发愣呢。我到现在有时候想起这事还忍不住捶自己两下!!!!
      ●一道题目要求把以下四句话用关联词连接:
      1、张海迪姐姐瘫痪了;
      2、张海迪姐姐顽强地学习;
      3、张海迪姐姐学会了多门外语;
      4、张海迪姐姐学会了针灸。
      正确答案应该是:"张海迪姐姐虽然瘫痪了,但顽强地学习,不仅学会了多门外语,而且还学会了针灸。
      结果有一个孩子写:虽然张海迪姐姐顽强地学会了针灸和多门外语,可她还是瘫痪了。
      又发现一个更猛的孩子写道:张海迪姐姐不但学会了外语,还学会了针灸,她那么顽强地学习,终于瘫痪了!
      ●我是云南大学的,2000级,就是马家爵那一级的。小马哥出事,但还没被抓到的时候,通缉令上都说协助公安机关抓获小马哥可以有多少万的奖励。大家 都很眼红,很想得到那大笔钱,上街都很注意路人的长相。有一天,出门坐在公共汽车上,人不多,只有一个人站着,忽然大家都盯着那个人看,我仔细一看,很像 通缉令上小马哥的样子,可能大家都看出来了,都是一副又紧张又激动的模样。气氛紧张到了极点,那人被大家看得都惊慌起来,愤怒地大叫一声:“我不是马家 爵!公共汽车司机很负责,果断地说:谁都不能下车,我把车开到派出所。大家摩拳擦掌,马上把所有车窗都关上。那人就一副很无奈的表情。到了派出所,司机神 气地对警察说:我车上有人很像马家爵,我马上把车开来了。那人委屈地对警察说:警官,还是我,今天我已经第二次被抓到你们这了。
      ●同桌感冒流鼻涕,但他忘记带手帕了,就不断把鼻涕用力吸入鼻子里。在黑板上写字的语文老师突然转过身来大嚷:“够了!给我停止!吵死了!”全班一片安静。老师又说:“到底是谁上课时偷吃面条还这么大声?”
      ●大一,一次去食堂打包子,谁知划卡机出了点毛病,一下划下去25块3,卖包子的哥哥鼓捣了半天也加不回去,于是可怜兮兮地说:“没事,我记得你,以后常来,直到把多划的钱用完。”我只好同意了。
      可怜我上顿包子下顿包子地吃了一学期,包子哥哥还欠我2块3……最可气的是大学四年我竟然没找到一个女朋友!!
      直到毕业,有一天我走在校园林荫路上,就听后面一帮女生指指点点小声道:“没错,就是他!!以后可别找这样男朋友,天天去二食堂吃包子不给钱!!”
      ●本人姓朱,管理单位机房。有次有人打我手机:“鸡科长,你在猪房吗?”当时狂骂那家伙一顿
      ●中午做饭,妈妈给我一盆胡萝卜:“去,把胡萝卜切成肉丁!”
      ●记得有一次去买一种叫伊丽莎白的水果,我张口就说:老板,莎士比亚多少钱?老板当场就呆了
      ●和领导等众人喝酒,举起酒杯大声道:"让我们同归于尽吧!"当时脑子太热了
      ......
      ●一次去市场买菜,准备聚餐,一个韩国朋友买了生菜,要2块4,他把身上所有的零钱都给了小贩,还缺一毛钱,所以他对小贩说--
      “我的毛,都给你了,所以没有毛了。”
      小贩哑然,半天,回答--
      “你的毛我不要了。”
      ●一次在食堂吃饭边吃边聊,突然发现自己把一块饭掉在了外面,暗自觉得浪费粮食对不起农民伯伯,就捡起来吃了。可是后来发现那饭,好像不是我的……
      ●掐着一只大公鸡的脖子却不敢下刀,踌躇良久,那只鸡竟然被俺掐死了
      ●新浪一新闻 新闻标题:重庆铁路公安特警在列车上演练反恐
      一位河北的网友评论:请问,你们能挤上中国的火车吗?还tmd反恐呢!
      ●一天晚上和几个朋友喝酒,几个人都喝多了.一个到在路边睡着了,我们也抬不动他,就商量给他找些东西盖上,别着凉了.几天后见到他,他说第二天醒来发现身上放着三辆自行车.
    Posted Apr 28 2009, 11:08 PM by Coolboy with no comments
    Filed under:
  • 高性能网页开发新20条规则详解

    转载自CSDN

    因需要登陆和发送资料才给看,所以转在这里

    太多了,不知道怎样转..

    http://developer.yahoo.com/performance/rules.html

    http://blog.csdn.net/zlb789/archive/2008/12/21/3568187.aspx

    1. Use a Content Delivery Network
    2. Add an Expires or a Cache-Control Header
    3. Gzip Components
    4. Put Stylesheets at the Top
    5. Put Scripts at the Bottom
    6. Avoid CSS Expressions
    7. Make JavaScript and CSS External
    8. Reduce DNS Lookups
    9. Minify JavaScript and CSS
    10. Avoid Redirects
    11. Remove Duplicate Scripts
    12. Configure ETags
    13. Make Ajax Cacheable
    14. Flush the Buffer Early
    15. Use GET for AJAX Requests
    16. Post-load Components
    17. Preload Components
    18. Reduce the Number of DOM Elements
    19. Split Components Across Domains
    20. Minimize the Number of iframes
    21. No 404s
    22. Reduce Cookie Size
    23. Use Cookie-free Domains for Components
    24. Minimize DOM Access
    25. Develop Smart Event Handlers
    26. Choose <link> over @import
    27. Avoid Filters
    28. Optimize Images
    29. Optimize CSS Sprites
    30. Don't Scale Images in HTML
    31. Make favicon.ico Small and Cacheable
    32. Keep Components under 25K
    33. Pack Components into a Multipart Document

     

    Minimize HTTP Requests

    tag: content

    80% of the end-user response time is spent on the front-end. Most of this time is tied up in downloading all the components in the page: images, stylesheets, scripts, Flash, etc. Reducing the number of components in turn reduces the number of HTTP requests required to render the page. This is the key to faster pages.

    One way to reduce the number of components in the page is to simplify the page's design. But is there a way to build pages with richer content while also achieving fast response times? Here are some techniques for reducing the number of HTTP requests, while still supporting rich page designs.

    Combined files are a way to reduce the number of HTTP requests by combining all scripts into a single script, and similarly combining all CSS into a single stylesheet. Combining files is more challenging when the scripts and stylesheets vary from page to page, but making this part of your release process improves response times.

    CSS Sprites are the preferred method for reducing the number of image requests. Combine your background images into a single image and use the CSS background-image and background-position properties to display the desired image segment.

    Image maps combine multiple images into a single image. The overall size is about the same, but reducing the number of HTTP requests speeds up the page. Image maps only work if the images are contiguous in the page, such as a navigation bar. Defining the coordinates of image maps can be tedious and error prone. Using image maps for navigation is not accessible too, so it's not recommended.

    Inline images use the data: URL scheme to embed the image data in the actual page. This can increase the size of your HTML document. Combining inline images into your (cached) stylesheets is a way to reduce HTTP requests and avoid increasing the size of your pages. Inline images are not yet supported across all major browsers.

    Reducing the number of HTTP requests in your page is the place to start. This is the most important guideline for improving performance for first time visitors. As described in Tenni Theurer's blog post Browser Cache Usage - Exposed!, 40-60% of daily visitors to your site come in with an empty cache. Making your page fast for these first time visitors is key to a better user experience.

    top | discuss this rule

    Use a Content Delivery Network

    tag: server

    The user's proximity to your web server has an impact on response times. Deploying your content across multiple, geographically dispersed servers will make your pages load faster from the user's perspective. But where should you start?

    As a first step to implementing geographically dispersed content, don't attempt to redesign your web application to work in a distributed architecture. Depending on the application, changing the architecture could include daunting tasks such as synchronizing session state and replicating database transactions across server locations. Attempts to reduce the distance between users and your content could be delayed by, or never pass, this application architecture step.

    Remember that 80-90% of the end-user response time is spent downloading all the components in the page: images, stylesheets, scripts, Flash, etc. This is the Performance Golden Rule. Rather than starting with the difficult task of redesigning your application architecture, it's better to first disperse your static content. This not only achieves a bigger reduction in response times, but it's easier thanks to content delivery networks.

    A content delivery network (CDN) is a collection of web servers distributed across multiple locations to deliver content more efficiently to users. The server selected for delivering content to a specific user is typically based on a measure of network proximity. For example, the server with the fewest network hops or the server with the quickest response time is chosen.

    Some large Internet companies own their own CDN, but it's cost-effective to use a CDN service provider, such as Akamai Technologies, Mirror Image Internet, or Limelight Networks. For start-up companies and private web sites, the cost of a CDN service can be prohibitive, but as your target audience grows larger and becomes more global, a CDN is necessary to achieve fast response times. At Yahoo!, properties that moved static content off their application web servers to a CDN improved end-user response times by 20% or more. Switching to a CDN is a relatively easy code change that will dramatically improve the speed of your web site.

    top | discuss this rule

    Add an Expires or a Cache-Control Header

    tag: server

    There are two things in this rule:

    • For static components: implement "Never expire" policy by setting far future Expires header
    • For dynamic components: use an appropriate Cache-Control header to help the browser with conditional requests

    Web page designs are getting richer and richer, which means more scripts, stylesheets, images, and Flash in the page. A first-time visitor to your page may have to make several HTTP requests, but by using the Expires header you make those components cacheable. This avoids unnecessary HTTP requests on subsequent page views. Expires headers are most often used with images, but they should be used on all components including scripts, stylesheets, and Flash components.

    Browsers (and proxies) use a cache to reduce the number and size of HTTP requests, making web pages load faster. A web server uses the Expires header in the HTTP response to tell the client how long a component can be cached. This is a far future Expires header, telling the browser that this response won't be stale until April 15, 2010.

          Expires: Thu, 15 Apr 2010 20:00:00 GMT

     

    If your server is Apache, use the ExpiresDefault directive to set an expiration date relative to the current date. This example of the ExpiresDefault directive sets the Expires date 10 years out from the time of the request.

          ExpiresDefault "access plus 10 years"

     

    Keep in mind, if you use a far future Expires header you have to change the component's filename whenever the component changes. At Yahoo! we often make this step part of the build process: a version number is embedded in the component's filename, for example, yahoo_2.0.6.js.

    Using a far future Expires header affects page views only after a user has already visited your site. It has no effect on the number of HTTP requests when a user visits your site for the first time and the browser's cache is empty. Therefore the impact of this performance improvement depends on how often users hit your pages with a primed cache. (A "primed cache" already contains all of the components in the page.) We measured this at Yahoo! and found the number of page views with a primed cache is 75-85%. By using a far future Expires header, you increase the number of components that are cached by the browser and re-used on subsequent page views without sending a single byte over the user's Internet connection.

    top | discuss this rule

    Gzip Components

    tag: server

    The time it takes to transfer an HTTP request and response across the network can be significantly reduced by decisions made by front-end engineers. It's true that the end-user's bandwidth speed, Internet service provider, proximity to peering exchange points, etc. are beyond the control of the development team. But there are other variables that affect response times. Compression reduces response times by reducing the size of the HTTP response.

    Starting with HTTP/1.1, web clients indicate support for compression with the Accept-Encoding header in the HTTP request.

          Accept-Encoding: gzip, deflate

    If the web server sees this header in the request, it may compress the response using one of the methods listed by the client. The web server notifies the web client of this via the Content-Encoding header in the response.

          Content-Encoding: gzip

    Gzip is the most popular and effective compression method at this time. It was developed by the GNU project and standardized by RFC 1952. The only other compression format you're likely to see is deflate, but it's less effective and less popular.

    Gzipping generally reduces the response size by about 70%. Approximately 90% of today's Internet traffic travels through browsers that claim to support gzip. If you use Apache, the module configuring gzip depends on your version: Apache 1.3 uses mod_gzip while Apache 2.x uses mod_deflate.

    There are known issues with browsers and proxies that may cause a mismatch in what the browser expects and what it receives with regard to compressed content. Fortunately, these edge cases are dwindling as the use of older browsers drops off. The Apache modules help out by adding appropriate Vary response headers automatically.

    Servers choose what to gzip based on file type, but are typically too limited in what they decide to compress. Most web sites gzip their HTML documents. It's also worthwhile to gzip your scripts and stylesheets, but many web sites miss this opportunity. In fact, it's worthwhile to compress any text response including XML and JSON. Image and PDF files should not be gzipped because they are already compressed. Trying to gzip them not only wastes CPU but can potentially increase file sizes.

    Gzipping as many file types as possible is an easy way to reduce page weight and accelerate the user experience.

    top | discuss this rule

    Put Stylesheets at the Top

    tag: css

    While researching performance at Yahoo!, we discovered that moving stylesheets to the document HEAD makes pages appear to be loading faster. This is because putting stylesheets in the HEAD allows the page to render progressively.

    Front-end engineers that care about performance want a page to load progressively; that is, we want the browser to display whatever content it has as soon as possible. This is especially important for pages with a lot of content and for users on slower Internet connections. The importance of giving users visual feedback, such as progress indicators, has been well researched and documented. In our case the HTML page is the progress indicator! When the browser loads the page progressively the header, the navigation bar, the logo at the top, etc. all serve as visual feedback for the user who is waiting for the page. This improves the overall user experience.

    The problem with putting stylesheets near the bottom of the document is that it prohibits progressive rendering in many browsers, including Internet Explorer. These browsers block rendering to avoid having to redraw elements of the page if their styles change. The user is stuck viewing a blank white page.

    The HTML specification clearly states that stylesheets are to be included in the HEAD of the page: "Unlike A, [LINK] may only appear in the HEAD section of a document, although it may appear any number of times." Neither of the alternatives, the blank white screen or flash of unstyled content, are worth the risk. The optimal solution is to follow the HTML specification and load your stylesheets in the document HEAD.

    top | discuss this rule

    Put Scripts at the Bottom

    tag: javascript

    The problem caused by scripts is that they block parallel downloads. The HTTP/1.1 specification suggests that browsers download no more than two components in parallel per hostname. If you serve your images from multiple hostnames, you can get more than two downloads to occur in parallel. While a script is downloading, however, the browser won't start any other downloads, even on different hostnames.

    In some situations it's not easy to move scripts to the bottom. If, for example, the script uses document.write to insert part of the page's content, it can't be moved lower in the page. There might also be scoping issues. In many cases, there are ways to workaround these situations.

    An alternative suggestion that often comes up is to use deferred scripts. The DEFER attribute indicates that the script does not contain document.write, and is a clue to browsers that they can continue rendering. Unfortunately, Firefox doesn't support the DEFER attribute. In Internet Explorer, the script may be deferred, but not as much as desired. If a script can be deferred, it can also be moved to the bottom of the page. That will make your web pages load faster.

    top | discuss this rule

    Avoid CSS Expressions

    tag: css

    CSS expressions are a powerful (and dangerous) way to set CSS properties dynamically. They're supported in Internet Explorer, starting with version 5. As an example, the background color could be set to alternate every hour using CSS expressions.

          background-color: expression( (new Date()).getHours()%2 ? "#B8D4FF" : "#F08A00" );

     

    As shown here, the expression method accepts a JavaScript expression. The CSS property is set to the result of evaluating the JavaScript expression. The expression method is ignored by other browsers, so it is useful for setting properties in Internet Explorer needed to create a consistent experience across browsers.

    The problem with expressions is that they are evaluated more frequently than most people expect. Not only are they evaluated when the page is rendered and resized, but also when the page is scrolled and even when the user moves the mouse over the page. Adding a counter to the CSS expression allows us to keep track of when and how often a CSS expression is evaluated. Moving the mouse around the page can easily generate more than 10,000 evaluations.

    One way to reduce the number of times your CSS expression is evaluated is to use one-time expressions, where the first time the expression is evaluated it sets the style property to an explicit value, which replaces the CSS expression. If the style property must be set dynamically throughout the life of the page, using event handlers instead of CSS expressions is an alternative approach. If you must use CSS expressions, remember that they may be evaluated thousands of times and could affect the performance of your page.

    top | discuss this rule

    Make JavaScript and CSS External

    tag: javascript, css

    Many of these performance rules deal with how external components are managed. However, before these considerations arise you should ask a more basic question: Should JavaScript and CSS be contained in external files, or inlined in the page itself?

    Using external files in the real world generally produces faster pages because the JavaScript and CSS files are cached by the browser. JavaScript and CSS that are inlined in HTML documents get downloaded every time the HTML document is requested. This reduces the number of HTTP requests that are needed, but increases the size of the HTML document. On the other hand, if the JavaScript and CSS are in external files cached by the browser, the size of the HTML document is reduced without increasing the number of HTTP requests.

    The key factor, then, is the frequency with which external JavaScript and CSS components are cached relative to the number of HTML documents requested. This factor, although difficult to quantify, can be gauged using various metrics. If users on your site have multiple page views per session and many of your pages re-use the same scripts and stylesheets, there is a greater potential benefit from cached external files.

    Many web sites fall in the middle of these metrics. For these sites, the best solution generally is to deploy the JavaScript and CSS as external files. The only exception where inlining is preferable is with home pages, such as Yahoo!'s front page and My Yahoo!. Home pages that have few (perhaps only one) page view per session may find that inlining JavaScript and CSS results in faster end-user response times.

    For front pages that are typically the first of many page views, there are techniques that leverage the reduction of HTTP requests that inlining provides, as well as the caching benefits achieved through using external files. One such technique is to inline JavaScript and CSS in the front page, but dynamically download the external files after the page has finished loading. Subsequent pages would reference the external files that should already be in the browser's cache.

    top | discuss this rule

    Reduce DNS Lookups

    tag: content

    The Domain Name System (DNS) maps hostnames to IP addresses, just as phonebooks map people's names to their phone numbers. When you type www.yahoo.com into your browser, a DNS resolver contacted by the browser returns that server's IP address. DNS has a cost. It typically takes 20-120 milliseconds for DNS to lookup the IP address for a given hostname. The browser can't download anything from this hostname until the DNS lookup is completed.

    DNS lookups are cached for better performance. This caching can occur on a special caching server, maintained by the user's ISP or local area network, but there is also caching that occurs on the individual user's computer. The DNS information remains in the operating system's DNS cache (the "DNS Client service" on Microsoft Windows). Most browsers have their own caches, separate from the operating system's cache. As long as the browser keeps a DNS record in its own cache, it doesn't bother the operating system with a request for the record.

    Internet Explorer caches DNS lookups for 30 minutes by default, as specified by the DnsCacheTimeout registry setting. Firefox caches DNS lookups for 1 minute, controlled by the network.dnsCacheExpiration configuration setting. (Fasterfox changes this to 1 hour.)

    When the client's DNS cache is empty (for both the browser and the operating system), the number of DNS lookups is equal to the number of unique hostnames in the web page. This includes the hostnames used in the page's URL, images, script files, stylesheets, Flash objects, etc. Reducing the number of unique hostnames reduces the number of DNS lookups.

    Reducing the number of unique hostnames has the potential to reduce the amount of parallel downloading that takes place in the page. Avoiding DNS lookups cuts response times, but reducing parallel downloads may increase response times. My guideline is to split these components across at least two but no more than four hostnames. This results in a good compromise between reducing DNS lookups and allowing a high degree of parallel downloads.

    top | discuss this rule

    Minify JavaScript and CSS

    tag: javascript, css

    Minification is the practice of removing unnecessary characters from code to reduce its size thereby improving load times. When code is minified all comments are removed, as well as unneeded white space characters (space, newline, and tab). In the case of JavaScript, this improves response time performance because the size of the downloaded file is reduced. Two popular tools for minifying JavaScript code are JSMin and YUI Compressor. The YUI compressor can also minify CSS.

    Obfuscation is an alternative optimization that can be applied to source code. It's more complex than minification and thus more likely to generate bugs as a result of the obfuscation step itself. In a survey of ten top U.S. web sites, minification achieved a 21% size reduction versus 25% for obfuscation. Although obfuscation has a higher size reduction, minifying JavaScript is less risky.

    In addition to minifying external scripts and styles, inlined <script> and <style> blocks can and should also be minified. Even if you gzip your scripts and styles, minifying them will still reduce the size by 5% or more. As the use and size of JavaScript and CSS increases, so will the savings gained by minifying your code.

    top | discuss this rule

    Avoid Redirects

    tag: content

    Redirects are accomplished using the 301 and 302 status codes. Here's an example of the HTTP headers in a 301 response:

          HTTP/1.1 301 Moved Permanently
          Location: http://example.com/newuri
          Content-Type: text/html

     

    The browser automatically takes the user to the URL specified in the Location field. All the information necessary for a redirect is in the headers. The body of the response is typically empty. Despite their names, neither a 301 nor a 302 response is cached in practice unless additional headers, such as Expires or Cache-Control, indicate it should be. The meta refresh tag and JavaScript are other ways to direct users to a different URL, but if you must do a redirect, the preferred technique is to use the standard 3xx HTTP status codes, primarily to ensure the back button works correctly.

    The main thing to remember is that redirects slow down the user experience. Inserting a redirect between the user and the HTML document delays everything in the page since nothing in the page can be rendered and no components can start being downloaded until the HTML document has arrived.

    One of the most wasteful redirects happens frequently and web developers are generally not aware of it. It occurs when a trailing slash (/) is missing from a URL that should otherwise have one. For example, going to http://astrology.yahoo.com/astrology results in a 301 response containing a redirect to http://astrology.yahoo.com/astrology/ (notice the added trailing slash). This is fixed in Apache by using Alias or mod_rewrite, or the DirectorySlash directive if you're using Apache handlers.

    Connecting an old web site to a new one is another common use for redirects. Others include connecting different parts of a website and directing the user based on certain conditions (type of browser, type of user account, etc.). Using a redirect to connect two web sites is simple and requires little additional coding. Although using redirects in these situations reduces the complexity for developers, it degrades the user experience. Alternatives for this use of redirects include using Alias and mod_rewrite if the two code paths are hosted on the same server. If a domain name change is the cause of using redirects, an alternative is to create a CNAME (a DNS record that creates an alias pointing from one domain name to another) in combination with Alias or mod_rewrite.

    top | discuss this rule

    Remove Duplicate Scripts

    tag: javascript

    It hurts performance to include the same JavaScript file twice in one page. This isn't as unusual as you might think. A review of the ten top U.S. web sites shows that two of them contain a duplicated script. Two main factors increase the odds of a script being duplicated in a single web page: team size and number of scripts. When it does happen, duplicate scripts hurt performance by creating unnecessary HTTP requests and wasted JavaScript execution.

    Unnecessary HTTP requests happen in Internet Explorer, but not in Firefox. In Internet Explorer, if an external script is included twice and is not cacheable, it generates two HTTP requests during page loading. Even if the script is cacheable, extra HTTP requests occur when the user reloads the page.

    In addition to generating wasteful HTTP requests, time is wasted evaluating the script multiple times. This redundant JavaScript execution happens in both Firefox and Internet Explorer, regardless of whether the script is cacheable.

    One way to avoid accidentally including the same script twice is to implement a script management module in your templating system. The typical way to include a script is to use the SCRIPT tag in your HTML page.

          <script type="text/javascript" src="menu_1.0.17.js"></script>

    An alternative in PHP would be to create a function called insertScript.

          <?php insertScript("menu.js") ?>

    In addition to preventing the same script from being inserted multiple times, this function could handle other issues with scripts, such as dependency checking and adding version numbers to script filenames to support far future Expires headers.

    top | discuss this rule

    Configure ETags

    tag: server

    Entity tags (ETags) are a mechanism that web servers and browsers use to determine whether the component in the browser's cache matches the one on the origin server. (An "entity" is another word a "component": images, scripts, stylesheets, etc.) ETags were added to provide a mechanism for validating entities that is more flexible than the last-modified date. An ETag is a string that uniquely identifies a specific version of a component. The only format constraints are that the string be quoted. The origin server specifies the component's ETag using the ETag response header.

          HTTP/1.1 200 OK
          Last-Modified: Tue, 12 Dec 2006 03:03:59 GMT
          ETag: "10c24bc-4ab-457e1c1f"
          Content-Length: 12195

     

    Later, if the browser has to validate a component, it uses the If-None-Match header to pass the ETag back to the origin server. If the ETags match, a 304 status code is returned reducing the response by 12195 bytes for this example.

          GET /i/yahoo.gif HTTP/1.1
          Host: us.yimg.com
          If-Modified-Since: Tue, 12 Dec 2006 03:03:59 GMT
          If-None-Match: "10c24bc-4ab-457e1c1f"
          HTTP/1.1 304 Not Modified

     

    The problem with ETags is that they typically are constructed using attributes that make them unique to a specific server hosting a site. ETags won't match when a browser gets the original component from one server and later tries to validate that component on a different server, a situation that is all too common on Web sites that use a cluster of servers to handle requests. By default, both Apache and IIS embed data in the ETag that dramatically reduces the odds of the validity test succeeding on web sites with multiple servers.

    The ETag format for Apache 1.3 and 2.x is inode-size-timestamp. Although a given file may reside in the same directory across multiple servers, and have the same file size, permissions, timestamp, etc., its inode is different from one server to the next.

    IIS 5.0 and 6.0 have a similar issue with ETags. The format for ETags on IIS is Filetimestamp:ChangeNumber. A ChangeNumber is a counter used to track configuration changes to IIS. It's unlikely that the ChangeNumber is the same across all IIS servers behind a web site.

    The end result is ETags generated by Apache and IIS for the exact same component won't match from one server to another. If the ETags don't match, the user doesn't receive the small, fast 304 response that ETags were designed for; instead, they'll get a normal 200 response along with all the data for the component. If you host your web site on just one server, this isn't a problem. But if you have multiple servers hosting your web site, and you're using Apache or IIS with the default ETag configuration, your users are getting slower pages, your servers have a higher load, you're consuming greater bandwidth, and proxies aren't caching your content efficiently. Even if your components have a far future Expires header, a conditional GET request is still made whenever the user hits Reload or Refresh.

    If you're not taking advantage of the flexible validation model that ETags provide, it's better to just remove the ETag altogether. The Last-Modified header validates based on the component's timestamp. And removing the ETag reduces the size of the HTTP headers in both the response and subsequent requests. This Microsoft Support article describes how to remove ETags. In Apache, this is done by simply adding the following line to your Apache configuration file:

          FileETag none

    top | discuss this rule

    Make Ajax Cacheable

    tag: content

    One of the cited benefits of Ajax is that it provides instantaneous feedback to the user because it requests information asynchronously from the backend web server. However, using Ajax is no guarantee that the user won't be twiddling his thumbs waiting for those asynchronous JavaScript and XML responses to return. In many applications, whether or not the user is kept waiting depends on how Ajax is used. For example, in a web-based email client the user will be kept waiting for the results of an Ajax request to find all the email messages that match their search criteria. It's important to remember that "asynchronous" does not imply "instantaneous".

    To improve performance, it's important to optimize these Ajax responses. The most important way to improve the performance of Ajax is to make the responses cacheable, as discussed in Add an Expires or a Cache-Control Header. Some of the other rules also apply to Ajax:

     

    Let's look at an example. A Web 2.0 email client might use Ajax to download the user's address book for autocompletion. If the user hasn't modified her address book since the last time she used the email web app, the previous address book response could be read from cache if that Ajax response was made cacheable with a future Expires or Cache-Control header. The browser must be informed when to use a previously cached address book response versus requesting a new one. This could be done by adding a timestamp to the address book Ajax URL indicating the last time the user modified her address book, for example, &t=1190241612. If the address book hasn't been modified since the last download, the timestamp will be the same and the address book will be read from the browser's cache eliminating an extra HTTP roundtrip. If the user has modified her address book, the timestamp ensures the new URL doesn't match the cached response, and the browser will request the updated address book entries.

    Even though your Ajax responses are created dynamically, and might only be applicable to a single user, they can still be cached. Doing so will make your Web 2.0 apps faster.

    top | discuss this rule

    Flush the Buffer Early

    tag: server

    When users request a page, it can take anywhere from 200 to 500ms for the backend server to stitch together the HTML page. During this time, the browser is idle as it waits for the data to arrive. In PHP you have the function flush(). It allows you to send your partially ready HTML response to the browser so that the browser can start fetching components while your backend is busy with the rest of the HTML page. The benefit is mainly seen on busy backends or light frontends.

    A good place to consider flushing is right after the HEAD because the HTML for the head is usually easier to produce and it allows you to include any CSS and JavaScript files for the browser to start fetching in parallel while the backend is still processing.

    Example:

          ... <!-- css, js -->
        </head>
        <?php flush(); ?>
        <body>
          ... <!-- content -->
    

    Yahoo! search pioneered research and real user testing to prove the benefits of using this technique.

    top

    Use GET for AJAX Requests

    tag: server

    The Yahoo! Mail team found that when using XMLHttpRequest, POST is implemented in the browsers as a two-step process: sending the headers first, then sending data. So it's best to use GET, which only takes one TCP packet to send (unless you have a lot of cookies). The maximum URL length in IE is 2K, so if you send more than 2K data you might not be able to use GET.

    An interesting side affect is that POST without actually posting any data behaves like GET. Based on the HTTP specs, GET is meant for retrieving information, so it makes sense (semantically) to use GET when you're only requesting data, as opposed to sending data to be stored server-side.

     

    top

    Post-load Components

    tag: content

    You can take a closer look at your page and ask yourself: "What's absolutely required in order to render the page initially?". The rest of the content and components can wait.

    JavaScript is an ideal candidate for splitting before and after the onload event. For example if you have JavaScript code and libraries that do drag and drop and animations, those can wait, because dragging elements on the page comes after the initial rendering. Other places to look for candidates for post-loading include hidden content (content that appears after a user action) and images below the fold.

    Tools to help you out in your effort: YUI Image Loader allows you to delay images below the fold and the YUI Get utility is an easy way to include JS and CSS on the fly. For an example in the wild take a look at Yahoo! Home Page with Firebug's Net Panel turned on.

    It's good when the performance goals are inline with other web development best practices. In this case, the idea of progressive enhancement tells us that JavaScript, when supported, can improve the user experience but you have to make sure the page works even without JavaScript. So after you've made sure the page works fine, you can enhance it with some post-loaded scripts that give you more bells and whistles such as drag and drop and animations.

    top

    Preload Components

    tag: content

    Preload may look like the opposite of post-load, but it actually has a different goal. By preloading components you can take advantage of the time the browser is idle and request components (like images, styles and scripts) you'll need in the future. This way when the user visits the next page, you could have most of the components already in the cache and your page will load much faster for the user.

    There are actually several types of preloading:

    • Unconditional preload - as soon as onload fires, you go ahead and fetch some extra components. Check google.com for an example of how a sprite image is requested onload. This sprite image is not needed on the google.com homepage, but it is needed on the consecutive search result page.
    • Conditional preload - based on a user action you make an educated guess where the user is headed next and preload accordingly. On search.yahoo.com you can see how some extra components are requested after you start typing in the input box.
    • Anticipated preload - preload in advance before launching a redesign. It often happens after a redesign that you hear: "The new site is cool, but it's slower than before". Part of the problem could be that the users were visiting your old site with a full cache, but the new one is always an empty cache experience. You can mitigate this side effect by preloading some components before you even launched the redesign. Your old site can use the time the browser is idle and request images and scripts that will be used by the new site

    top

    Reduce the Number of DOM Elements

    tag: content

    A complex page means more bytes to download and it also means slower DOM access in JavaScript. It makes a difference if you loop through 500 or 5000 DOM elements on the page when you want to add an event handler for example.

    A high number of DOM elements can be a symptom that there's something that should be improved with the markup of the page without necessarily removing content. Are you using nested tables for layout purposes? Are you throwing in more <div>s only to fix layout issues? Maybe there's a better and more semantically correct way to do your markup.

    A great help with layouts are the YUI CSS utilities: grids.css can help you with the overall layout, fonts.css and reset.css can help you strip away the browser's defaults formatting. This is a chance to start fresh and think about your markup, for example use <div>s only when it makes sense semantically, and not because it renders a new line.

    The number of DOM elements is easy to test, just type in Firebug's console:
    document.getElementsByTagName('*').length

    And how many DOM elements are too many? Check other similar pages that have good markup. For example the Yahoo! Home Page is a pretty busy page and still under 700 elements (HTML tags).

    top

    Split Components Across Domains

    tag: content

    Splitting components allows you to maximize parallel downloads. Make sure you're using not more than 2-4 domains because of the DNS lookup penalty. For example, you can host your HTML and dynamic content on www.example.org and split static components between static1.example.org and static2.example.org

    For more information check "Maximizing Parallel Downloads in the Carpool Lane" by Tenni Theurer and Patty Chi.

    top

    Minimize the Number of iframes

    tag: content

    Iframes allow an HTML document to be inserted in the parent document. It's important to understand how iframes work so they can be used effectively.

    <iframe> pros:

    • Helps with slow third-party content like badges and ads
    • Security sandbox
    • Download scripts in parallel

    <iframe> cons:

    • Costly even if blank
    • Blocks page onload
    • Non-semantic

    top

    No 404s

    tag: content

    HTTP requests are expensive so making an HTTP request and getting a useless response (i.e. 404 Not Found) is totally unnecessary and will slow down the user experience without any benefit.

    Some sites have helpful 404s "Did you mean X?", which is great for the user experience but also wastes server resources (like database, etc). Particularly bad is when the link to an external JavaScript is wrong and the result is a 404. First, this download will block parallel downloads. Next the browser may try to parse the 404 response body as if it were JavaScript code, trying to find something usable in it.

    top

    tag: cookie

    HTTP cookies are used for a variety of reasons such as authentication and personalization. Information about cookies is exchanged in the HTTP headers between web servers and browsers. It's important to keep the size of cookies as low as possible to minimize the impact on the user's response time.

    For more information check "When the Cookie Crumbles" by Tenni Theurer and Patty Chi. The take-home of this research:

    • Eliminate unnecessary cookies
    • Keep cookie sizes as low as possible to minimize the impact on the user response time
    • Be mindful of setting cookies at the appropriate domain level so other sub-domains are not affected
    • Set an Expires date appropriately. An earlier Expires date or none removes the cookie sooner, improving the user response time

    top

    tag: cookie

    When the browser makes a request for a static image and sends cookies together with the request, the server doesn't have any use for those cookies. So they only create network traffic for no good reason. You should make sure static components are requested with cookie-free requests. Create a subdomain and host all your static components there.

    If your domain is www.example.org, you can host your static components on static.example.org. However, if you've already set cookies on the top-level domain example.org as opposed to www.example.org, then all the requests to static.example.org will include those cookies. In this case, you can buy a whole new domain, host your static components there, and keep this domain cookie-free. Yahoo! uses yimg.com, YouTube uses ytimg.com, Amazon uses images-amazon.com and so on.

    Another benefit of hosting static components on a cookie-free domain is that some proxies might refuse to cache the components that are requested with cookies. On a related note, if you wonder if you should use example.org or www.example.org for your home page, consider the cookie impact. Omitting www leaves you no choice but to write cookies to *.example.org, so for performance reasons it's best to use the www subdomain and write the cookies to that subdomain.

    top

    Minimize DOM Access

    tag: javascript

    Accessing DOM elements with JavaScript is slow so in order to have a more responsive page, you should:

    • Cache references to accessed elements
    • Update nodes "offline" and then add them to the tree
    • Avoid fixing layout with JavaScript

    For more information check the YUI theatre's "High Performance Ajax Applications" by Julien Lecomte.

    top

    Develop Smart Event Handlers

    tag: javascript

    Sometimes pages feel less responsive because of too many event handlers attached to different elements of the DOM tree which are then executed too often. That's why using event delegation is a good approach. If you have 10 buttons inside a div, attach only one event handler to the div wrapper, instead of one handler for each button. Events bubble up so you'll be able to catch the event and figure out which button it originated from.

    You also don't need to wait for the onload event in order to start doing something with the DOM tree. Often all you need is the element you want to access to be available in the tree. You don't have to wait for all images to be downloaded. DOMContentLoaded is the event you might consider using instead of onload, but until it's available in all browsers, you can use the YUI Event utility, which has an onAvailable method.

    For more information check the YUI theatre's "High Performance Ajax Applications" by Julien Lecomte.

    top

    tag: css

    One of the previous best practices states that CSS should be at the top in order to allow for progressive rendering.

    In IE @import behaves the same as using <link> at the bottom of the page, so it's best not to use it.

    top

    Avoid Filters

    tag: css

    The IE-proprietary AlphaImageLoader filter aims to fix a problem with semi-transparent true color PNGs in IE versions < 7. The problem with this filter is that it blocks rendering and freezes the browser while the image is being downloaded. It also increases memory consumption and is applied per element, not per image, so the problem is multiplied.

    The best approach is to avoid AlphaImageLoader completely and use gracefully degrading PNG8 instead, which are fine in IE. If you absolutely need AlphaImageLoader, use the underscore hack _filter as to not penalize your IE7+ users.

    top

    Optimize Images

    tag: images

    After a designer is done with creating the images for your web page, there are still some things you can try before you FTP those images to your web server.

    • You can check the GIFs and see if they are using a palette size corresponding to the number of colors in the image. Using imagemagick it's easy to check using
      identify -verbose image.gif
      When you see an image useing 4 colors and a 256 color "slots" in the palette, there is room for improvement.
    • Try converting GIFs to PNGs and see if there is a saving. More often than not, there is. Developers often hesitate to use PNGs due to the limited support in browsers, but this is now a thing of the past. The only real problem is alpha-transparency in true color PNGs, but then again, GIFs are not true color and don't support variable transparency either. So anything a GIF can do, a palette PNG (PNG8) can do too (except for animations). This simple imagemagick command results in totally safe-to-use PNGs:
      convert image.gif image.png
      "All we are saying is: Give PiNG a Chance!"
    • Run pngcrush (or any other PNG optimizer tool) on all your PNGs. Example:
      pngcrush image.png -rem alla -reduce -brute result.png
    • Run jpegtran on all your JPEGs. This tool does lossless JPEG operations such as rotation and can also be used to optimize and remove comments and other useless information (such as EXIF information) from your images.
      jpegtran -copy none -optimize -perfect src.jpg dest.jpg

    top

    Optimize CSS Sprites

    tag: images

    • Arranging the images in the sprite horizontally as opposed to vertically usually results in a smaller file size.
    • Combining similar colors in a sprite helps you keep the color count low, ideally under 256 colors so to fit in a PNG8.
    • "Be mobile-friendly" and don't leave big gaps between the images in a sprite. This doesn't affect the file size as much but requires less memory for the user agent to decompress the image into a pixel map. 100x100 image is 10 thousand pixels, where 1000x1000 is 1 million pixels

    top

    Don't Scale Images in HTML

    tag: images

    Don't use a bigger image than you need just because you can set the width and height in HTML. If you need
    <img width="100" height="100" src="mycat.jpg" alt="My Cat" />
    then your image (mycat.jpg) should be 100x100px rather than a scaled down 500x500px image.

    top

    Make favicon.ico Small and Cacheable

    tag: images

    The favicon.ico is an image that stays in the root of your server. It's a necessary evil because even if you don't care about it the browser will still request it, so it's better not to respond with a 404 Not Found. Also since it's on the same server, cookies are sent every time it's requested. This image also interferes with the download sequence, for example in IE when you request extra components in the onload, the favicon will be downloaded before these extra components.

    So to mitigate the drawbacks of having a favicon.ico make sure:

    • It's small, preferably under 1K.
    • Set Expires header with what you feel comfortable (since you cannot rename it if you decide to change it). You can probably safely set the Expires header a few months in the future. You can check the last modified date of your current favicon.ico to make an informed decision.

    Imagemagick can help you create small favicons

    top

    Keep Components under 25K

    tag: mobile

    This restriction is related to the fact that iPhone won't cache components bigger than 25K. Note that this is the uncompressed size. This is where minification is important because gzip alone may not be sufficient.

    For more information check "Performance Research, Part 5: iPhone Cacheability - Making it Stick" by Wayne Shea and Tenni Theurer.

    top

    Pack Components into a Multipart Document

    tag: mobile

    Packing components into a multipart document is like an email with attachments, it helps you fetch several components with one HTTP request (remember: HTTP requests are expensive). When you use this technique, first check if the user agent supports it (iPhone does not).

    top

     

     

     

    原文

    上个月,Yahoo!优异性能(Yahoo!'s Exceptional Performance)开发团队成员 Stoyan Stefanov 出席了蒙特利尔的2008魁北克PHP会议演讲。他提供了他们团队最新的研究成果和提高网页性能规则20条。在早先的高性能网页开发14条军规已经让大家耳熟能详,此次新增的20条更加全面,覆盖了服务器端、cookies、页面内容、JavaScript、CSS、图片、移动手机应用这七大类别。以下内容就是根据这二十条结合个人在实际开发中的理解所做的全面解读。希望对大家开发有所助益。

    阅读指导:

    1. 每条规则后会指明是针对上述所说的七大类别中哪个类别的优化。

    2. 文中提到的一些工具在文后附注中会提供简要说明。

    3. 文中经常提到“组件”这个词,这个词不同于我们程序开发中常提到的组件概念。本文中提到的“组件”特指嵌在HTML页面中图片、JavaScript脚本、CSS等静态文件。

    一、尽早清除缓冲区[服务器端]

        假如用户请求一个页面,而这个页面在后端服务器需要花200至500毫秒乃至更长时间才能生成最终HTML页面,这时候用户浏览器处于较长时间的、等待页面数据返回的空闲状态,用户体验不会很好。此时可以根据页面内容长短做适当分隔,将先生成的页面局部HTML缓冲内容提前发送到客户端,不必让服务器消耗内存缓冲完整个庞大的页面内容后再行输出。这种方法有益于处理后端负荷大而前端负荷轻的页面。

        在HTML页面的head标签位置后是清除缓冲的好位置,因为HTML的head标签可以包括 CSS 和 JavaScript 文件,对于浏览器而言获取页面显示与后端服务器处理并行的效果较好。在PHP中有一个函数 flush(),它可以发送请求页面的局部HTML代码给浏览器,以便浏览器能先取得页面已经生成的部分HTML,同时后端服务器继续忙于处理生成页面余下的HTML。以下以此函数做个示例:


     

    ... <!-- css, js -->

    </head>

    <!-- 注意此处flush()是放在了head标签位置后面 -->

    <?php flush(); ?>

    <body>

    ... <!-- content -->


     

        其他语言也有类似语法,如ASP.NET和ASP中的 Response.Flush()。

        注意:在实际Web开发中,尽量减少HTTP请求次数是优化的重要方面,这条基本原则是早先14条和新增20条中很多规则的制订基础,实际上它也是14条规则中第一条也是非常重要的一条规则,但是使用尽早清除缓冲语句会增加一个页面的HTTP请求次数,这无疑是一个矛盾,因此请注意本条规则的适用范围,不要滥用它。

    二、使用GET方法的AJAX请求[服务器端]

        这个容易理解一些。AJAX经常要用XMLHttpRequest,但是它的POST方法在浏览器中完成需要执行两步:首先发送信息头,然后才是发送数据;而GET方法只用一个TCP数据包传递(cookies信息例外)即可,减少了一个步骤,速度会快些。

        另外根据HTTP规范,GET方法就是为获取信息而生的。因此仅在请求数据而不是发送数据给服务器端存储时,使用GET方法很有意义。

        要注意的是,IE中URL允许最大允许长度是2K,用GET方法发送数据时注意2K的这个限制。

    三、后加载组件[页面内容]

        使用该方法的意义在于:如果某个页面内容丰富多彩的话,在浏览器加载显示它时速度就不会很快。使用后加载组件的方法可以通过延迟加载一些隐藏内容来保证浏览器优先显示初始页面。

        要做到这一点必须仔细观察自己的页面并且问自己:“解释生成一个完整页面,什么部分内容是开始加载时绝对必须显示的?”清楚了这个问题,那么那些余下内容和组件就可以采用后加载方法延迟生成。这样会大大加快页面显示速度。

        这个技巧通常是JavaScript通过处理页面加载时的onload事件完成。例如,使用JavaScript代码和库去执行拖放动态效果操作时,这些操作可以延迟,因为拖动页面上元素的操作只能等初始页面生成完后才能发生。页面中的隐藏内容也适合用后加载方式,因为只有页面加载完毕用户才能操作决定是否显示该内容。

        Yahoo!网站的首页内容繁多,观察处于隐藏状态下的内容,这些内容通常在一些选项卡一样的标签页当中,只有点击后才会加载。

        只要明白该规则的优化要点后相信大家可以通过JavaScript做出自己的具体实现。Yahoo!提供了两个用于实现后加载方法的工具:

    ◆ YUI Image Loader:可以延迟图片显示

    ◆ YUI Get utility:它可以在页面加载完成后把JavaScript和CSS资源绑定到DOM上去。

        以上的工具是Yahoo!的YUI库提供。

    四、预加载组件[页面内容]

        从文字上看预加载组件与后加载组件似乎作用相反,但实际上二者目标是完全不同的。通过预先加载组件可以充分利用浏览器的空闲时间,并且可以请求未来页面需要的组件。在这种情况下,当用户访问下一个页面时,你已经提前让大多数组件保存在缓存中,用户加载这个页面就会非常快。

        预加载类型有下列三种:


     

    1. 无条件预加载

        onload事件一触发,就要马上取回一些指定的组件。可以检查google.com首页中onload事件中请求Sprite图片的例子(注:什么是Sprite图片,请参看第十六条规则)。在这个例子可以看出这个sprite图片www.google.com/images/nav_logo3.png在google.com首页本身并不需要, 但它会在随后用户搜索生成的结果页面中需要。


     



    2. 条件预加载

        根据用户操作预测用户下一步操作的方向,并据此做预加载。例如,search.yahoo.com中,在输入框中刚键入几个字符后,就会看到页面对你键入的词做出合理推测,推出几个可能要搜索的实际关键词。此方法目前谷歌(google.cn)也在使用。

     

    3. 提前预加载

        在将重新设计的网站页面发布前用此法较好。页面重新设计后常会有这样的反馈:“新站点太酷了,就是比以前慢”。原因在于用户访问旧站点是全缓存的,但新站点还没有缓存过。这时可以在发布新设计前就预加载一些新站点组件,这可以减少没有缓存的副作用。可以利用用户访问旧站点时浏览器空闲的时间请求新站点要使用的图片、脚本等。

    五、减少 DOM 元素数量[页面内容]

        一个复杂的页面意味着要请求下载的字节数更多,也意味着用JavaScript访问DOM速度更慢。

        如何尽量减少已有页面的 DOM 元素数量呢?一个重要的思路就是不要滥用表格table和div 。很多人习惯用一些网页编辑软件去设计页面,这样会导致大量嵌套的表格或在使用语义不合法的标记。使用div要仅当它在语义上有意义时才使用它,有些开发者使用它仅仅是因为它可以被浏览器解释生成一个新行。

        Yahoo! 提供了一个避免这些问题的方法——使用YUI CSS工具。grids.css 有助于整体布局设计,fonts.css 和 reset.css 有且于清除浏览器的默认格式设置。这些工具可以在Yahoo!的YUI页面中去找。

        DOM元素的数量可在Firebug的Console上键入 document.getElementsByTagName('*').length 得到。

        DOM 元素不超过多少才适当呢?这可以通过检查一些有良好设计的页面来感觉比较。如Yahoo! 主页访问量相当大,它的数量在700个元素(HTML标签)以下。

    六、分隔组件到多个域中[页面内容]

        对终端用户响应时间影响最大的就是所请求页面所含组件数量。只要浏览器缓存为空,下载每个组件需要占用额外的HTTP请求,只有缓存满时才可能不占用。

        HTTP/1.1规范中建议浏览器对每一个主机名允许并发下载两个组件。默认状态下,Internet Explorer和Firefox都符合这个规范。注意:IE8.0默认允许6个并发请求。

        许多网页中所有组件都从同一主机名中下载,这时不仅响应时间受并发线程数限制,同时也受该服务器CPU和带宽限制。把页面组件分布在两个主机名中,整体响应时间就会快2倍,CPU和带宽消耗也会得以分担。

    七、尽量减少 HTML 标签 iframe 的使用数[页面内容]

        iframe允许在父文档内插入一个HTML文档。要想高效使用iframes,理解它的工作方式很重要。

        使用iframe有如下好处:

    ◆ 有助于减慢显示第三方标记和广告内容。

    ◆ 是个安全的 Sandbox。

    ◆ 能并发下载脚本。

    但同时也有弊端:

    ◆ 即使iframe 内的 HTML 文档内容为空,消耗也比较高。

    ◆ 会阻止页面的onload事件

    ◆ 非语义的

    八、避免404页面[页面内容]

        如果做了一个HTTP请求然后得到一个无用的响应页面,不仅完全不必要而且会降低用户体验。404页面就是在没有发现指定资源时返回的页面。

        一些站点提供了有益的404提示,对用户体验有好处,但这毕竟浪费了服务器资源。当链接一个外部JavaScript文件,而它又出了404错误,这尤其糟糕。首先,因为这个下载有问题会阻止并发下载;其次,即使有错浏览器仍然会尽力解析404返回的内容,看看有无JavaScript代码,尽力查找里面可用代码。

    Posted Dec 25 2008, 11:01 PM by Coolboy with no comments
    Filed under: ,
  • 很多抽筋的笑话,心情不好的孩子慢慢看。我看完了,笑的肚子疼!

    1.有一天小明手上打着石膏,
      老师问:你的手怎么了
      小明说:断掉了
      老师说:为什么?
      小明说:因为我太懒了
      老师说:太懒手会断?
      小明说:我走在路上,鞋子跑进一颗石头,
      可是我懒的用手弄,
      就抱着电线杆抖着脚让石头掉出来,
      路人看了以为我触电就用木棍打我的手
      所以.................
      老师:............


    2.在大陆做生意的台商,
      由于家眷都在台湾,
      所以每个晚上都喜欢跑声色场所。
      有一天他不幸被公安逮到,
      台胞证被盖了个“淫虫”两个大字。
      他很不高兴,
      于是透过关系花了一些钱,
      要把这着不雅的名词去除。
      
      过了一星期,
      朋友告诉他办好了。
      他想,在大陆只要有钱哪有办不到的事?
      他接到台胞证后兴冲冲打开一看,
      里面赫然盖了个三个大字:
      非淫虫。

    后来他透过更有力的人士想要把这
      非淫虫
      三个字弄掉,
      因为他觉得这三个字还是不雅,
      所以这次交代一定要把这件事解决。
      因为下个月他就要回台湾了....
      朋友也跟他再三保证,
      一定没问题,
      只是礼数绝不可少。
      
      又过了一星期,
      朋友来找他,对他说:这次真的办好了!
      他赶紧把台胞证接过来一看,
      上面写着:
      非洲淫火虫

    3.甲乙丙三人一起出游,甲感冒了……
      晚上,大家同睡一床,甲睡中间。
      
      半夜…甲打了一个大喷涕,
      乙丙整个脸上都是甲的结晶。
      乙丙:下次要通知我们……
      
      过了半个时辰,
      甲:注意了…
      乙丙闻言赶紧钻入棉被中,
      并确定与外界没有连通…
      结果,甲放了个屁。


    4. 我有一次和几个同学
      去高中老师家看他,
      那是一个老头,临走,
      我们留下一些水果送给老师,
      可是老师紧紧拉住班长的笔记本电脑包说:
      “看看,来看我还带什么东西呀……
      放在门口就好了.”


    5.陪朋友打的去见一个网友,
      快到的时候,
      朋友指着不远处一个奇丑无比的女孩对司机说:
      “看到那个女的了吗?”
        
      “看到了,在那儿停?”
      “不,撞死她!!!”


    6.一天在东方广场约网友MM见面,
      不想显的太土,约在星巴克。
      等MM时觉得不买点东西不合适,
      
      就到柜台点咖啡。
      服务员问:“您要点什么?”。
      当天没带眼镜,
      咖啡厅灯光昏暗,
      我使劲看价牌,还是看不见……
      就说了一句:“看不清楚!”。
      
      服务员:“好的,卡布奇诺!”
      于是我就喝到了在星巴克的第一杯Cappuccino……


    7.某公司经理叫秘书转呈公文给老板:
      “报告老板,下个月欧洲有一批订单,
      我觉得公司需要带人去和他们开会。”
      老板在公文后面短短签下:“ Go a head”。
      经理收到之后,马上指示下属买机,
      拟行程,自己则是整理行李。
      临出发那天,被秘书挡下来。
      秘书:“你要干什么?”
      经理:“去欧洲开会啊!”
      秘书:“老板有同意吗?”
      经理:“老板不是对我说Go a head吗?”
      秘书:“来公司那么久,
      难道你还不知道老板的英文程度吗?
      老板的意思是:去个头!”


    8.某兄喜欢吃鱼。
      沃尔玛的鲈鱼9块一斤,
      要是死了放冰上的就7块两条,
      一样新鲜。某兄下班,
      就赶紧跑去买,还是经常被人买走了,
      某兄就站鱼缸前等啊,
      有时候好半天都不死一条。
      某兄就用网进去捞,用把手敲鱼的头。
      服务员实在看不下去了,
      过来跟该兄说:
      “先生,昏过去的不算……”


    9.偶MM班任是个50多岁的老女人。
      一日到男生宿舍探访,
      正好一男生什么也没穿在地下乱窜~
      被班任看到了
      立刻大叫一声跳到床上,
      盖住被子~
      班任留下一句话就走了:
      我这么大岁数了什么没见过,
      你叫什么叫~
      该同学巨寒- -!!!


    10.盗版光碟:

    -Are you serious?(你是认真的吗?)
    -No,I'm kidding.(不,我开玩笑的.)
        
       电影上的翻译:
        -你是席拉瑞丝吗?
        -不,我是凯丁..

    11.大一的时候,
      偶寝室一哥们
      一天早上起来
      发现枕头上有半只大黑蛾子,
      感觉倍儿郁闷。
      
      提起来正要扔,
      赫然发现蛾子翅膀上的齿印。。。。。。
        
      
      全寝室暴寒一学期!!!


    12.一对男女偷情,丈夫突然回家,男的没顾穿衣服就跳窗逃跑,走在大街上路上围观,男的装着若无其事看天:啊,这就是地球呀。路人说:cao,装鸡毛外星人。


    13.我们寝室对面有一小面馆。
      寝室一室友,
      特爱耍酷,
      某日正待在窗边洗头,
      待洗完,
      头发一甩作明星状,
      手指向面馆,
      大喊一声:对面吃小面的朋友们,你们好吗!


    14.一日同学去中关村转悠,
      一小贩凑过去问,
      “要硬盘不?便宜”
      
      同学拿过来看看 说:“有多硬”

    15.以前大学的时候,
      晚上睡觉前大家都要闲扯一会.
      
      一次说道如果晚上有歹徒翻进寝室怎么办?
      (当时正报道有个女生寝室被人强奸了)
      一姐妹说:看见他翻上阳台,大家一起上!
      “然后呢?”众人问,
      
      
      她顿口气接着说:
      “拖进来轮奸他,
      搞到他精尽人亡,
      让他以后路过我们这栋楼,都得绕道走!”


    16.大学的宿舍里有个哥们爱说梦话,
        
      有天晚上我正起来喝口水,
      谁知他突然大吼了一声:“喂!”
       吓得我把杯子打烂了……
      
      
      某天晚上,又继续说梦话,
      喃喃地说:
      “其实……其实……我……怀孕了……(略带哭腔)”


    17.有一次夏天在外面吃宵夜,
      旁边桌子上坐了一个光膀子的胖子。
      巨胖,上身的肉都是吊起的。
      吃了一半,
      传呼机响了(9几年的时候)我们一看都不是我们的。
      
      结果看到那个胖子把腰上面的肉翻起来,
      看了下传呼算后又把肉放下来,接到起吃。
      当时我们一桌的美女就喷饭了。


    18.百度知道

    急求论文:浅析中国艺术的意境美
    悬赏分:0 - 解决时间:2007-6-22 18:24
    急求论文:浅析中国艺术的意境美
    2500字~3000字
    大家有的帮帮忙,先谢谢列!

    浅析中国艺术的意境美
    悬赏分:0 - 解决时间:2007-6-24 14:12
    湖师文理的同学们 我是教你们美术概论的曹老师!关于本次浅析中国艺术的意境美的论文 为了防止你们抄袭!我已经把百度搜索到的关于浅析中国艺术的意境美的前40页的所有网页全浏览过!目前还在继续浏览其他的!请你们注意了!要自己动脑!!

    19.一个同学,他的电脑每天早上会自动开机(估计是因为宿舍里早上来电的时候一瞬间冲开的)。

    结果他老人家拿了一个符贴在了电脑上。。。

    20.某日,A君在厕所里面拉屎,
      估计拉不出来,
      就在厕所里面狂吠。
      
      此时,外面的B君听到,
      于是高声唱到:
      “拉不出来一声吼啊!”
      更绝的是,
      C君马上接着唱到:
      “再拉不出来就用手抠啊!”
        
      
      此后,此歌成为我们寝室的室歌

    21.照科目三考试,早晨5点就让集合,自然考的时候迷迷糊糊。
    轮到我上车,起步,走,稳妥的开,考官不说话,坐在旁边。
    突然,考官对我说,加油,同学。
    顿时,我受宠若惊,心里一股暖流,心想,多好的考官啊,知道我紧张,还鼓励我。
    于是,我微笑着对考官说,谢谢考官。
    考官一愣,显得有点无奈。就这么开,转弯过了,考官又来了一句,加油!
    我又温暖了一把,感动了一把,还是微笑着说,谢谢考官!
    考官好像更无语了,强忍着面部表情,摇了摇头。
    快到终点了,考官第3遍不耐烦的说,加油!加油!同学。
    还没等我谢字说出口,考官挺着身子指着我踩油门的右脚说:
    我是让你踩油门的脚加油,不是给你加油!你以为这是奥运会,我来看你比赛的啊!


    22.夜,四人寝室一人睡着了,
      还有三人在讨论追女孩子第1次怎么表白,
      讨论得正热闹,
      那个睡着的醒了:
      啥也别说了,咱们睡觉吧.....


    23.北大的研究生和本科生校区是分开的,
      研究生在一个名叫万柳的校区。
      
      在本科生校区,
      也就是北大本部小西门那个地方有一个自行车停车场,
      专门为研究生准备的,
      墙上写着“万柳同学停车处”。
      
      有一次和一朋友从那过,
      见他欲言又止,
      最后挣扎了半天终于疑惑地问我:
      你说这万柳同学是谁呀,真牛X,这么多自行车!”


    24.刚开学,
      来了个新的英语老师,
      
      他要求以后我们回答问题必需都英语回答.
      
      然后他开始点名:NO.1.
      他喊.
      我们班1号就站了起来,
      喊了声:到!那个老师说:
      Please in English!(请用英语回答)
      我那同学挠了挠头,
      憋了半天答了句:
      导~~~(发第二音)
        
    25.我们宿舍哥们暴强,
      一日他发现蚊帐里有只蚊子,
      忙活抓了半天没抓到,
      哥们叹了一口气说:
      “妈的,饿死你!”
      然后迅速把蚊帐收了起来,
      忍了好几天没挂蚊帐,
      最后终于把蚊子给饿死了,
      我们那个汗呀~~~~~
        
      
      还是蚊帐的事:
      一日他又发现蚊帐里竟然飞进一只苍蝇,
      跟我们说:“我非弄死他”,
      我们说:“苍蝇可是耐饿呀,看来你是靠不过他的”。
      “你们看吧”,
      这人抄起一本小说钻进蚊帐,
      封口。
      边看小说边不停的挥动扇子,
      就是不让苍蝇落地,
      结果两个小时后,
      苍蝇终于飞不动了。
      
      他凑过去捅了捅苍蝇说:
      “飞呀小样,爷书还没看够呢”


    26.一考入北京某大学的学生与校友的对话:
        你是云南的?
        "YES"
        "哇..好远啊...."
        ..........
         "云南解放没有?"
        "没有,我们上课的时候都带着枪"
         "你原来会说汉语~!"
        "来的时候在火车上刚学的" .
       “你们住窑洞吗?”
        “不,我们住树上”
        “云南是不是在昆明?”
         "恩,云南是昆明的省会。"
        "你的很多小辫子呢?"
        "为了上大学只好剪掉了!"
        “你们还吃生肉吗?”
        “我们老大发明了燧木取火,我们吃烧烤,”


    "你是云南人啊?"
        "是啊。"
        "那太好了,下次我去拉萨旅游,就住你家了啊。"
        "……没问题,不过我家离拉萨稍有点远。"
        "那你们怎么来上学?"
        "骑驴到北京后坐飞机。"
        "那一定很久才到吧?
        "习惯了,提前半年出发就行!"
        "………………!
        怎么不骑马呢?
        "在云南,骑马的都是穷人干的事情,像我们考出来的,
        都是骑骆驼和驴的。
       然后云南没有高考,考试都是比赛射箭,
        一公里以外摆个牌子,
       写上"清华"旁边放一个"北大"然后一个人有三次机会,
        我第一次射清华,第二射北大,都失败了,最后为了保险,
        射了最近的一块牌子,就是这个学校.


    27.我大学时,
      宿舍的厕所堵了,
      一哥们自告奋勇,
      说他去通之,
      用一跟两米长的棍子在厕所洞里用力捅,
      三下之后果然通了,
      还冲了几次水,
      效果很好,
      
      
      我刚要夸他就发现那个洞里的居然有很强的光,
      仔细一看原来下水道被捅穿了,
      楼下还有人在大号,
      我们在楼下那位冲上来之前都闪了。。。。


    28.我中专的室友,
      有一次放假前一块喝酒,
      后来喝多了,
      上到3楼楼梯口看到走廊上有水,
      
      突然摆脱扶他的两个兄弟,
      说了一句:
      “我要游到我们宿舍去”
      
      然后就一个前扑动作,
      扑到走廊上做起蛙泳的动作,
      周围人倒!!!
      这样游了四五米后,终于被人拉了起来


    29.我们宿舍
      晚上有去通宵要么就是出去和老婆打野战的,
      很晚回来,
      喊我们开门,
      然后我们就让他们对口号,
      
      天王盖地虎,
      宝塔镇河妖,
      么哈么哈,
      脸怎么黄了?
      他们要是不说是吃屎吃黄的绝对不开门。
      
      有一次冬天晚上下鱼,
      风又挺大,
      
      一哥们冻的不行了,
      回来就敲门,
      也不对暗号了,
      直接就在那喊,
      我脸是吃屎吃黄的,
      赶紧开门吧。
      
      声音之洪亮,我们住1楼,3楼的都听见了。。。。


    30.我上铺痛经很严重,
      每次到周期都要卧床休息。
      
      我们这些室友就坐在她床边一边照顾她一边聊天。
      一次她痛得受不了,
      说要做手术把子宫切除了,
      反正她也不想要孩子。
      
      我们就在罗列子宫切除后的好处。
      除了再也不用痛经,
      A说还可以节省卫生巾的钱,
      B说可以节省买套套的钱,
      C说更不用花大钱做人流了……
      轮到最后一个,
      她想了半天,
      说,
      
      
      
      
      切下来的子宫我们可以炒着吃,应该挺补的……

    31.从左岸到中关大道上有很多卖毛片的人
      见你走过去
      就问
      哥们 要片儿吗?
      我们起初很反感后来习惯了
      
      有一个寝室一哥们
      和女友去中关村配电脑
      回来特别郁闷
      说被卖片儿的骚扰
      大家说没什么
      
      
      
      这哥们说:
      问题是那SB
      过来问我"哥们 毛片儿拍吗?"


    32.还有一个,是听别人说的。
      话说月底最穷的时候,
      一寝室人都没钱了,
      又不敢问家里要,集体节食。
      为了节约体能,大家都翘课了。
      
      中午辅导员来寝室,
      见一个个都有气无力地在床上躺着,
      很是诧异。
      还没开口,就听寝室老大慢悠悠地说了声“午饭时间到”,
      大家晃晃悠悠地从床上下来,到水房喝一通自来水,回来继续睡……


    33.大学有一个女同学,
      北京人,
      冷幽默的那种。
      她说起她高考后查分的事情。
        
      
      打电话到查分台查分。
      查到数学分数的时候,
      电话里报:
      “您的数学分数是6——”
      听到这,
      她心里一阵窃喜:
      “嘿,数学让我蒙到60多分了?”
      “——分!”电话里面接着报。


    34.大一,石家庄,
      冬天,一日天寒地冻,
      正好是上午下课吃饭时间,
      路上全是朝食堂走的人群,
      我们班几个走到图书馆前,
      这里有口大水塘,结了薄薄一层冰,
      
      我们几个南方的就讨论
      这冰面能不能承受一个人的重量,
      这时来自陕西的老大现身说法地跳上了冰面,
      说:没问题,看还能走人呢,
      不仅能走还能大跳呢。
      
      言毕,
      只见老大以慢动作从冰面慢慢沉入池底,
      手还保持着向我们挥动的姿势,
      全校大部分同学均目瞪口呆地了这个精彩的瞬间。
        
      老大反应身手了得,
      几个扑腾到了岸边,
      然后迅雷不及掩耳爬起来就跑,
      等我们回到寝室只见其拥被于床说:
      不用说了,以后谁再提,我灭谁。


    35.一次逛街时突然觉得肚子很痛
          于是走进街角的199吃到饱的火锅店
          想说借个厕所用用
          偏偏找遍了一楼就是找不到
          于是我跑到二楼去
          二楼是还在装修空荡荡的没有任何东西
          但是却发现有一间厕所贴著“故障待修,请勿使用“
          我实在是忍不住了
          管他三七二十一,反正四下无人
          脱了裤子就朝马桶蹲下去
          霹雳啪啦……好爽! !
          
          结束后
          我走下楼去却发现空无一人
          奇怪了,正值晚餐时间 刚才楼下还高朋满座
          怎么一下子就人去楼空呢?连服务生和接待都不见了……
           於是我走近吧台,
          并且问到:有人在吗?怎么都没人了?
          此时,只见一个男服务生从吧台下钻出来,
          并且开口说:
          我操!……刚才大便从天花板掉下来
       打到电风扇的时候你不在吗?算你运气好......


    36.熄灯后,
      男生宿舍集体高呼“来电!来电!”,
      结果5分钟后真的来电;
      接着,
      男生宿舍集体高喊
      “晚点熄灯!晚点熄灯!”
      然后真的11:50才熄灯;
      最后,
      男生宿舍集体高叫“女人!女人!……”


    37.高中时讲排列组合,分组做题。
      老师叫起磊:“你们组多少人?”
      磊:“十二个。”
        
        
      老师:
      “好,那你算一下,
      十二个人排队,
      你不能站在排头和排尾,
      则有多少种排法?”
        
        
      磊埋头算:
      “啊,有十二个人,
      我不能在排头…是…不能在排尾……”
        
      一会儿,
      终于糊涂,做错。
      老师怒,罚磊站。
        
        
      又叫起波:“你们组多少人?”。
      波惧,
      半晌,
      答:“三个……”


    38.前两天,
      公司的山东客户老张打来电话,
      向我询问一些工作上的问题。
      
      我们在电话里聊了好半天,
      最后为了便于网上交流,
      我让他留下电子邮箱地址。
      
       老张说:
      “你记一下,
      我的地址是……
      老张的汉语拼音全拼……
      然后是……
      后头没有.com.”
      
      “后头没有.com?”
      我一边记录一边琢磨着,
      邮箱后缀中没有.cn是正常的,
      但是如果没有.com,那还是邮箱吗?
      
       于是,我忙问他:“@后边是什么啊?
      也就是说,
      你邮箱是在哪个网站上建立的?”
      
      老张说:“不是告诉你后头没有.com了吗?! ”
      见我还不明白,
      老张有点不耐烦了
      ,说:“干脆我把地址发到你手机上好了,省得你听不懂。”
       挂了电话,几分钟后,
      我的手机响了。
      我打开一看,
      顿时恍然大悟。
      
      
      
      原来,他的邮箱是laozhang@hotmail.com


    39.A:I'm sorry!
    B:I'm sorry,too.
    A:I'm sorry three.
    B:What are you sorry for?
    A:I'm sorry five.


    40.拨通800-820-3800

    用户:你好,请问这里是微软吗?
    微软:是的,请问您有什么事吗?
    用户:前几天看到你们发布公告,不是说好了要黑屏的吗?我都等一天了,怎么还不黑啊。。。。
    微软:#%$^&@
    用户:你们到底黑不黑了?
    微软:…….
    用户:说啊,你们黑不黑?


    微软:黑… 盗版的才黑,你是盗版吗?
    用户:是啊,100%盗版,绝对盗版.
    微软:那不应该啊,对了,你打开自动更新了吗?
    用户:打开了啊,早早的就打开了,就等着看黑屏呢!
    微软;##$%^&%$#@$%…
    用户:怎么了?不需要打开啊?
    微软:需要,需要!
    用户:那咋还不黑呢?
    微软:你的自动更新有提示你下载补丁吗?
    用户:这倒没有,我等老半天了,最后等不了了,自己去你们网站上下了一个,结果还是不黑,你说这玩意整的!
    微软:….
    微软:对不起,先生,我们暂时无法解决你的问题,呆会找技术人员跟你联系,谢谢!

    挂机…………

     

    41.小平和毛主席散步。
      
      小平:租西,四介桑最同库地是洒子四琴喽?
      主席:桑班!
      小平:莫友比择更库地了?!
      主席深吸了一口烟,凝视前方:田田桑班.....
      小平继续问:“有崽同库地吗”
      主席二目一瞪,把烟袋一摔:“甲板!”
      小平又问:“那崽崽同库滴哩?”
      主席急了,说:“白甲板!”


    42.——昨天坐公车的时候,
      公车司机一直盯着我看,
      就象我没买票似的。
            
      ——那你怎么办?
            
      ——很简单,
      我也一直盯着他看,
      就象我买了票似的


    43.夏天的某次下课,
      我趴在课桌上闭着眼睛迷糊,
      迷糊中感觉有人的手臂碰到我的手指了,
      我以为是同桌,
      
      就用指甲抠了他一下,
      发现没反应,
      我又加重力量抠了他一下,
      还是没动,郁闷了,
      这不符合我的同桌的作风呀,
      难道抠轻了?
      
      所以我就一顿猛折腾,
      又是抓,又是扭的,
      折腾了一会,自己都感觉不对劲了,
      稍稍睁开眼,呀,
      发现是老师坐在我同桌的位置,
      正不可思议看着我,
      那手上那块皮肤都红了


    44.我们撮合公司里一对儿暧昧的男女,
      
      但女的喜欢男的,
      男的不喜欢女的,
      一次,
      四个人坐到一起,
      
      我说:
      你小子对我们毫米有感觉就别装了,
      赶紧表白,
      
      谁想,
      这家伙懒洋洋的坐在椅子上,
      用手摸了一下自己裤裆:
      有个P感觉啊,
      你们看,连硬都不硬,平平的。
      
      
      那女孩赶紧关切的说:
      是么,我摸摸…

    45.英国《每日电讯报》4日报道,
      一南威尔士人看到一个“明亮、静止”的不明飞行物,
      于是拨打“999”向警方紧急报告自己的发现。
      英国警方4日公布了这段通话记录,
      内容如下:
          
      警:“这里是南威尔士警察,你遇到什么紧急事件?”
      民:“其实也不怎么紧急。我只是需要告诉你们,
      山那头有一个明亮、静止的物体。”
      警:“好。”
          
      民:“如果你们有几分钟空闲,也许你们能来看看它是什么?
      它在那停留至少半小时,而且现在还在那里。”
      警:“它在那停留半小时。好。它是在山上还是在天上?”
      民:“它在天上。”
      警:“我会派人到那查清楚。”
      民:“OK。”
          
      通话记录包括警员赶赴现场后与总部的通话内容。
          
        
      总部:“(代号)阿尔法—祖鲁20,
      天上那个物体,有人查看它没有?”
      在场警员:
      “是的。
      它是月亮。
      完毕。”

    46.800壮士为什么只剩下300人了?
      
      
      
      
      
      
      
      
      
      
      
      
      因为伍佰去唱歌了
      
      
      
      
      于是这300壮士又吸纳了100人
      于是他们变成了什么?
      
      
      
      
      
      
      
      
      
      
      
      蜘蛛侠(四百的MAN)


    47.一天下午,我同学在建设银行十分无聊的上班,一个穿得很糟糕的女士(神经病患者)来到他窗口,给了他一张纸条要提款。
      纸条上赫然写着
      
      "兹派XX同志于贵银行处提取人民币".
      
      然后是l后面N多个零元。
      
      落款是***C.P中央办公厅***。
      我同学本来想报警,可看该神经病患者女子很认真的样子,想想还是打发给保安算鸟.(~估计保安也是很闲).
      果然,保安对该女子说:"你这张条子想要提款,必须先到对面派出所,找所长盖一个章,他盖完章,你再来取钱就没问题啦。"
        该女子想都没想,直接就向派出所走去了。(这保安还真不一般,平时有点小看他了).
        大概十多分钟,排队的顾客慢慢多起来的时候,那个女子兴高采烈的回来了,举着那个条子,说:"人家说啦,办公程序简化了,不用所长批条直接就可以取钱啦。"
        我这个同学一听到这就不住的感叹:pol.ice队伍里真有高人,一句"高调"就给打发回来了。
        我这个同学和保安当时就有点傻了,营业大厅有很多人都在,怕她精神病发作起来影响正常的秩序,只好把值班主管找来了。
      主管和女患者在一边聊了几句,问你取钱做什么用呀,女患者说:"取钱卖面包,蛋糕,吃的,卖穿的"主管指了指不远处的地方,该女子就又高高兴兴地走了。
      保安去请教"高招",主管当时是这样对女患者说的: "我们这里是建行,只有建房子才能到这里取钱。你取钱买吃的,那肯定是粮食了,要去农行,买穿的等东西,取钱要到工商银行才行!"
        我同学打心眼里佩服呀,到底是当主管的啊!!!!
        …………
        …………
        过了一会儿,该女士又回来了.而且带来了工行的回答:"农行的人说了,这里是农行,只有农民能取钱,我是城市人口,工行的人说了,我们这里是公行,只能公的来取,母的不行!!!!,说我是贱人,要到建行取钱"


    48.大家在聊火车上的见闻的话题。
      一兄说他有次坐火车坐的软卧,
      结果过了一会列车员过来叫他换节车厢,
      他问列车员怎么回事,
      列车员告诉他说这节车厢过会有政府官员上来,
      这节车厢被包了。
      
      大家个个义愤填膺,大骂政府腐败。
        
      
      一兄语出惊人:
      “这些王八蛋,
      连火车都不放过,
      不但包二奶,
      还他妈的包火车!”


    49.大学有一哥们从来口无遮拦,
      但是常被我们驳倒,
      每次被驳倒之后,
      他总气急败坏地说“我诅咒你女朋友不是处女!”
      这招还真灵,大家都拿他没办法。
        
        
      有一天,他又故技重演,
      还变本加厉地骂道:
      “我诅咒你们宿舍所有人的女朋友都不是处女!!!”
        
        
       这时,
      宿舍里很少言语的一GG
      在大家都沉默地时候来一句:
      
      
      
      
      “我们真诚祝福你的女朋友永远都是处女……”


    50.有个老头在北京专吃烤鸭,
      据说地道的烤鸭很难吃到,
      有次带了一票人去吃地道的北平烤鸭。
        
      “老板!给份烤鸭,要道地的!”
      只见小妹端了一份烤鸭上桌。
        “烤鸭到!”
        
      老头先止住大伙的口食,
      摸摸烤鸭的屁股,
      气呼呼叫小妹来说:
      “你这不是北平烤鸭,
      是南京板鸭,换一份!”
        
      小妹见状赶紧端回去换了一份。
        “烤鸭到!”
        
      同样地
      老头摸摸鸭屁股又气呼呼道:
      “小妹!这是天津盐鸭,换!”
        
      小妹端回去告诉厨师,又端了一盘上桌。
        “烤鸭到!”
        
      老头重复动作终于说:
      “可以吃了!
      这是地道北平烤鸭!”
        
      
      此时突然从厨房跑出一位厨师,
      跪在老头的前面道:
      “我从小就是孤儿,
      不知生在何处,
      能否摸摸我
      告诉我是哪儿人!”


    51.有一个黑人到台北的某餐厅,
      这个黑人既不懂中文也不会说。
      
      正不知所措时,
      赫然发现对面的白人
      指着服务生的裤裆,
      于是服务生露出会心一笑,
      立刻端上两颗水煮蛋,
      
      
      那个黑人看得真是垂涎三尺,
      马上如法炮制。
      服务生也是会心一笑,
      端上来
      
      
      
      
      
      
      
      
      
      
      两颗皮蛋……


    52.一位男士走进一家情趣用品店,
      然后用超级害羞,发抖的声调说:
      请…请…问…你们
      ……有有…有…没……有有…
      卖卖…按按…摩…器器…?
              
      店员:有啊!
              
      男士:那…那…种种…
      黑黑…黑色…
      可可…以……
      旋…旋旋…转转转…的?
              
      店员:对啊,干嘛?
              
      
      男士:那…
      那……
      请……请问
      要…要要…
      怎怎…么么…么…
      把把…
      把
      
      
      
      它…它…关…关关…掉?


    53.一对同是67岁的伴侣到性诊所求诊。
        医生问:“有什么问题吗?”
        男士回答道:“你愿意观看我们做爱吗?”
        医生虽然觉得有点困惑,仍然答应了。
      
      完事后,医生说道你们做的很好啊,
      没有什么问题,
      收了他们$32美金的诊疗费。
      
      尔后数星期
      这对又陆陆续续来看诊了好几次,
      他们都先预约,来到诊所请医生看他们做爱,
      医生也每次宣布没问题,
      并收$32美金的诊疗费。
      
      这天医生按耐不住了,
      问道:“你们到底想找出什么问题?”
        
      
      老先生回答道:
      “没有啦,
      他是已婚我们不能去他家,
      我也已婚也不能去我家,
      而假期大饭店要收费$60,
      希尔顿饭店收费$78,
      在你这里只要花$32,
      并且我还可用医疗保险扣抵$28美金。。。。。”

    我有一次和几个同学
      去高中老师家看他,
      那是一个老头,临走,
      我们留下一些水果送给老师,
      可是老师紧紧拉住班长的笔记本电脑包说:
      “看看,来看我还带什么东西呀……
      放在门口就好了.”


    54.为配合伟哥药丸在中国的全面销售,
      某药品销售公司
      特邀一群广告界精英人士撰写广告词。
      
      其中一人在绞尽脑汁苦思冥想后,
      仍一无所获,
      自感有愧于主人的盛情款待,
      交卷时面有惭色,
      递上白纸曰:
      对不起,我想不出来。
      
      次日,最佳广告语揭晓,
      众人皆大惊,
      伟哥中国地区广告语乃是:
      我想
      
      
      
      
      
      不出来


    55.小1说:你给我戴绿帽子!
      
      小0说:对!
      今天给你戴绿帽子,
      明天给你穿绿衣服,
      后天给你买辆自行车,
      叫你去做邮递员!


    56.四鸟吹牛,
      麻雀说:我是老鹰里吸毒的。
      乌鸦说:我是孔雀里烧锅炉的。
      鹦鹉说:我可是燕子里坐台的。
      盘里的烤鸭喊道:
      你们算个屁,老子是OO功自焚的


    57.乌龟受伤.让蜗牛去买药。过了2个小时.蜗牛还没回来。乌龟急了骂道:他妈的再不回来老子就死了!这时门外传来了蜗牛的声音:你他妈再说老子不去了

    58.语文测验,
      有一道填空题。
      要求分别填写《背影》和《春》的作者。
      某生一概不知。
        
        
      填第一个空时,
      他悄悄问同桌,
      答日:"朱自清。"
      填第二个空时他又问,
      答曰:"还是他。"
      
      于是,
      他在考卷上填上
      "还是他"。

    59.一次英语考试中,
      A君正不知所措,
      忽见B君已填得满满的,
      忙扔纸条过去求救。
        
        
      不一会儿,B君扔来一个纸团。
      A君大喜,忙拆开。
      只见纸内包着一块橡皮,
      橡皮四面画着A、B、C、D四个字母,
      在纸上还有几个字:自己掷。


    60.


     同学聚会上,
      一兄弟说:
      “奥运年不太平,
      现在北京的安保程度非常高!
      
      
      就说我们学校在中南海附近,
      上礼拜我在操场上踢球,
      不小心把球踢过了墙,
      结果没想到
      
      
      
      
      
      
      球还没落地就被狙爆了……”


    61.

     剧场里,演出正在进行。
      
      
      一位观众站起来沿着一排座位走进了休息室。
      
      
      几分钟后,他回来了。并向座在这排的第一位的观众问道:请问,我刚才是踩到您的脚了吗?
      
      
      对。不过没关系,现在已经不疼了。那位观众答道。
      
      
      不。我不是这个意思,我只是想证实一下我是不是座在这一排

    62.一高官到一个农场参观,
      问农夫:
      我怎么发现农场里
      有一只牛没有长角啊。
      
      农夫回答:
      牛没有角的原因很多,
      可能是遗传,
      生下来就没有,
      还有可能是后来有病脱落了,
      而它没有角的原因是,
      
      
      
      它是一匹马。


    63.小时候吃面条,
      吃着吃着,
      我从喉咙里拖出一根:
      “哈哈,会动的面条!”
      这时,
      爸爸在旁边严肃地说:
      “蛔虫有什么好玩的,
      赶快吃饭!”


    64.庙会上,
      剃头的和卖胡辣汤的吵了起来。
      
      剃头的师傅边剃头边骂到:
      你卖个JB胡辣汤,牛B嘛啊?!
      
      卖胡辣汤的不服,
      回骂道:你剃个JB头,
      你牛B嘛啊?!
      
      于是,
      正在理发的顾客腾地站了起来,
      一脚把卖胡辣汤的锅给踢了!


    65.中国留学生在国外的高速公路出车祸了,
      连人带车翻下悬崖,
      交警赶到后向下喊话道:
        
      “How are you?”
        
      留学生答:
      “I’m fine,thank you!”
      然后交警走了,留学生就死了


    66.有一栋楼有四层,
      每一层都住了个怪人,
      
      第一层的喜欢吃小黄瓜,
      第二层的喜欢把房间染成绿色,
      第三层的喜欢在阳台小便,
      第四层的喜欢耍大刀。
      
      有一天四楼的耍大刀不小心刀掉下去了,
      刚好三楼的要小便,结果切断了,
      掉到二层,被染成绿色,
      掉到一楼,
      最后被当成小黄瓜吃掉了。

    67.有一天 小明来到他未来的丈母娘家作客,
      丈母娘:你随便坐坐喔!菜马上就好!
      
      然后就进厨房忙了,
      这时客厅里只剩下紧张的小明和
      丈母娘养的狗小白
      
      突然间,小明发现自己的肚子剧痛了起来,
      他心想:不行!我一定要忍住!
      可是他实在忍不住了~~
      噗~~
      他放了一个无敌臭的响屁,
      
      他心想:这下死定了~~一定会被赶出去的
      没想到丈母娘只是大喊了一声:小白~~!
      
      小明于是放心的想:幸好有小白当我的替死鬼,
      然后他又忍不住放了第2个屁,
      丈母娘依旧大喊小白~~
      
      当他放第三个屁时,
      就看到丈母娘冲出来大骂说 :
      小白!你是要等到被臭死才会跑是不是

    Posted Dec 15 2008, 12:39 AM by Coolboy with 3 comment(s)
    Filed under:
  • 把ViewState存在服务器端

    using System;
    using System.IO;
    using System.Web.UI;

    public class XVPage : Page
    {
       
    static private DirectoryInfo _Dir;

       
    private DirectoryInfo Dir
        {
           
    get
            {
               
    if (_Dir == null)
                {
                      var _Dir = new DirectoryInfo(Path.Combine(AppDomain.CurrentDomain.BaseDirectory, "App_Data"));

                   
    if (!_Dir.Exists)
                        _Dir.Create();
                    _Dir
    = new DirectoryInfo(Path.Combine(_Dir.FullName, "ViewState"));
                   
    if (!_Dir.Exists)
                        _Dir.Create();
                }
               
    return _Dir;
            }
        }

       
    protected override object LoadPageStateFromPersistenceMedium()
        {
            PageStatePersister ps
    = this.PageStatePersister;
            ps.Load();
           
    if (ps.ControlState != null)
                ps.ControlState
    = 反序列化对象((string)ps.ControlState);
           
    if (ps.ViewState != null)
                ps.ViewState
    = 反序列化对象((string)ps.ViewState);
           
    return new Pair(ps.ControlState, ps.ViewState);
        }

       
    protected override void SavePageStateToPersistenceMedium(object state)
        {
            PageStatePersister ps
    = this.PageStatePersister;
           
    if (state is Pair)
            {
                Pair pair
    = (Pair)state;
                ps.ControlState
    = pair.First;
                ps.ViewState
    = pair.Second;
            }
           
    else
            {
                ps.ViewState
    = state;
            }
           
    if (ps.ControlState != null)
                ps.ControlState
    = 序列化对象(ps.ControlState);
           
    if (ps.ViewState != null)
                ps.ViewState
    = 序列化对象(ps.ViewState);
            ps.Save();
        }

       
    private object 反序列化对象(string stateID)
        {
           
    string stateStr = (string)Cache[stateID];
           
    string file = Path.Combine(Dir.FullName, stateID);
           
    if (stateStr == null)
                stateStr
    = File.ReadAllText(file);
           
    else
                Cache.Remove(stateID);
           
    return new ObjectStateFormatter().Deserialize(stateStr);
        }

       
    private string 序列化对象(object obj)
        {
           
    string value = new ObjectStateFormatter().Serialize(obj);
           
    string stateID = (DateTime.Now.Ticks + (long)value.GetHashCode()).ToString(); //产生离散的id号码  
            File.WriteAllText(Path.Combine(Dir.FullName, stateID), value);
            Cache.Insert(stateID, value);
           
    return stateID;
        }

       
    protected override void OnUnload(EventArgs e)
        {
           
    base.OnUnload(e);
            DateTime dt
    = DateTime.Now.AddMinutes(-20);
           
    foreach (FileInfo fl in Dir.GetFiles())
               
    if (fl.LastAccessTime < dt)
                   
    try
                    {
                        fl.Delete();
                    }
                   
    catch
                    {
                    }
        }
    }

    Posted Dec 10 2008, 08:31 AM by Coolboy with no comments
    Filed under:
  • 性能测试常见误区

    请看下面一个性能测试小案例:

    某公司OA产品的新版本即将发布。为了看看系统的性能,决定安排测试工程师A君执行性能测试任务。A君做法如下:1.       找到一台PC机,CPU主频1G,内存512M,……;2.       在找到的PC机上搭建了测试环境:安装了Oracle9i、Weblogic等系统软件3.       在自己的工作机上安装了LoadRunner7.8;4.       然后录制了登陆、发布公告等功能5.       开始设置30、50、100、500不同的并发用户数目进行并发6.       最后得出结论:系统只能运行80个左右的并发用户……

    无疑上面的做法存在很多不合理的地方,例如测试内容太少、测试服务器配置太低等。现实工作中,尽管性能测试以其在测试中独特的地位越来越为软件测试人员、开发人员和用户所重视,但是不管是测试人员还是开发人员,仍然在认识上存在这样或者那样的误区。

    误区1:提高一下硬件配置就可以提高性能了,因此性能测试不重要。这是以前系统规模不大时期留下来的认识。DOS时代以及后来Windows操作系统流行的初期,软件规模一般较小,而硬件的更新却是日新月异,软件性能一般不是突出问题,因为只要升级一下硬件,很容易就解决了性能问题。现在随着软件规模的扩大,提高硬件配置只是解决性能问题的一个基本手段。因为如果软件自身存在性能问题,再多的资源可能也不够用,例如内存泄漏问题,随着时间的增加,内存终究会被耗尽,最后导致系统崩溃。因此,如果用户对软件的性能要求较高,这将意味着不但要从硬件方面来提供性能,还要从数据库、WebServer、操作系统配置等方面入手来提高性能,同时开发的软件系统本身也要进行优化,以便全面提高性能。误区2:性能测试在所有其它测试完成后,测试一下看看就可以了。这是目前特别普遍的一种现象,例如前面的A君,这种现象主要是没有意识到性能测试的重要性。这种做法最严重的后果是如果性能问题是由软件系统本身产生的,可能会无法根治性能问题。例如架构设计方面的失误,可能意味着软件系统将被废掉。当然这并不意味所有的性能测试都要尽早进行,性能测试的启动时间要由软件特点来决定。性能测试策略的制定问题可以参考《程序员》20051011期的《治疗软件亚健康》。误区3:性能测试独立于功能测试。功能测试可以发现性能问题,性能测试也能发现功能问题。性能测试和功能测试是紧密联系在一起的,原因之一是由于很多性能问题是由软件自身功能缺陷引起的。如果应用系统功能不完善或者代码运行效率低下,通常会带来一些性能问题。功能测试通常要先于性能测试执行或者同步进行,软件功能完善可以保证性能测试进行得更加顺利。误区4:性能测试就是用户并发测试。仍然有很多人(尤其是开发人员和部分项目实施人员)一提到性能测试,就会联想到并发用户测试,进而认为性能测试就是“测试一下多用户的并发情况”。严格地讲,性能测试是以用户并发测试为主的测试。实际性能测试还包含强度测试、大数据量测试等许多内容。误区5:在开发环境下进行一下性能测试就可以了。很多时候,在软件开发完成后会进行性能测试,看一看软件的性能。实际上大多数的开发环境因为硬件条件比较差,所以反映不了过多的性能问题。因此性能测试要尽量在高配置的用户投产环境下进行。但是有两种可以例外的情况:一种是为了发现某些功能方面的问题,例如为了发现并发算法的一些缺陷;另外一种就是有非常好的硬件资源或者实验室作为开发环境。

    误区6:系统存在瓶颈,不可以使用。

    系统发现了瓶颈,的确是很让人担心的一件事情。不过不要紧,很多的瓶颈可以不必去理会。发现瓶颈的目的主要是为了掌握系统特性,为改善和扩展系统提供依据。因此在性能方面给系统留有30%左右的扩展空间就可以了。

    例如,1000个用户并发时发现了系统瓶颈,而客户的最大并发用户数量在500左右,这样的性能问题完全没有必要处理,要是550或者600个并发用户出现性能问题就应该认真地调整系统性能了。

    误区7:不切实际的性能指标。

    这种现象主要归结于对软件应用需求的不了解。很多时候,尤其是用户会提出很多不切实际的性能指标,例如,针对500个用户使用的OA系统,可能有的用户负责人会提出要满足100个甚至500个用户并发的性能目标,而实际并发数量不会高于50。这种情况只有和用户进行沟通才可以解决。

    上面列举的都是日常性能测试工作中相关人员常犯的错误,这些观点只在极其特殊的情况下才正确。希望读者了解这些常见的性能测试误区后,能在以后的工作中避免类似的情况。

  • 一个世界上最懒惰的程序员写的Cache也能让你的复杂计算程序(数据库程序)大大提高速

    仔细模拟一下你的数据库程序,你有没有发现在计算时(特别是多用户计算时)经常重复读取数据库数据?!这是数据库处理程序的性能的最主要的杀手。

    有些人说在写程序之前应该把算法想好,使得数据记录成批地、一次性地读取。但是这实际上往往不可能,因为复杂的程序贴近逻辑流程才清晰可维护。更何况这也不能解决多用户访问的情况。最好,我们根本不用在写程序时去考虑数据是否会被重复读取从而改变程序流程,但是又能自然而然地防止重复读取数据库。当对计算过程进行优化,而又不想破坏逻辑清晰性的时候,当然就是要依靠简单的Cache —— 对象只要能够缓存几秒钟就好。

    下面我这里写一个世界上最懒惰的程序员使用.net写的一个最简单的Cache,但是它往往可以让复杂的计算程序大大提高计算速度。

    using System;
    using System.Collections.Generic;

    namespace DomainBase
    {
       
    public class ObjectCache
        {
           
    //Dictionary<K,T> 会自动维护一个空链表来保存不用的单元。
           
    //这里,使用被缓存对象的“弱引用”,允许这些对象被垃圾回收。

           
    private Dictionary<string, WeakReference> Buffer = new Dictionary<string, WeakReference>();

           
    public object this[string key]
            {
               
    get
                {
                    WeakReference ret;
                   
    if (Buffer.TryGetValue(key, out ret) && ret.IsAlive)
                       
    return ret.Target;
                   
    else
                       
    return null;
                }
               
    set
                {
                    WeakReference ret;
                   
    if (Buffer.TryGetValue(key, out ret))
                        ret.Target
    = value;
                   
    else
                        Buffer.Add(key,
    new WeakReference(value));
                }
            }

           
    public void Remove(string key)
            {
                Buffer.Remove(key);
            }
        }
    }

    这就是最简单的Cache。例如:

    public Class User
    {
        static ObjectCache Buffer=new ObjectCache();

        public static GetUser(string id)
        {
          User ret=Buffer[id];
          if(ret==null)
          {
                ret=读取数据库产生User对象(id);
                Buffer[id]=ret;
          }
          return ret;
        }
    .....

    这里,在一个Dictionary <K,T>结构字典中保存了对象的key以及对象的“弱引用”。这样,当内存不足时GC会照样去释放被缓存的对象。当我们需要将对象在几秒钟内进行缓存时,使用这个最简单的Cache很有用。

    .net framework中有非常多非常多的东西需要程序员去了解,不要仅仅抱着那些空洞、不实惠的“放之四海而皆准”的大部头的著作,有时间要多读一些实际地分析 .net framework 系统本身的方面的资料。在每一个技术中都可以找对一两个细节,这个细节就像掌握DNA技术一样能够让你不但扩展原理而且通过动手能力得到巨大实惠。

    Posted Nov 25 2008, 12:16 AM by Coolboy with 1 comment(s)
    Filed under: ,
  • 2008北京奥运电视转播时间表

    Come on China.

  • Set Oralce processes

    alter system set processes=300 scope=spfile;

     

  • 软件测试

  • Asp.NET生成静态页面并分页

    因为公司的产品用asp开发, 前一段时间用asp写了一个生成静态页面并分页的程序,但缘于对.net的热爱,写了这个.net下的生成静态页面并分页的程序。

    主要的原理就是替换模板里的特殊字符。

    1、静态模板页面 template.html,主要是定义了一些特殊字符,用来被替换。

    <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN""http://www.w3.org/TR/html4/loose.dtd">
    <html>
    <head>
    <meta http-equiv="Content-Type" content="text/html; charset=gb2312">
    <title>Title </title>
    </head>
    <body>
    <div style="width: 417px; height: 54px" align="center">
    <br />
    Title </div>
    <div style="width: 417px; height: 8px">
    浏览 <font color="red"> <script src="http://localhost/.Net/NewsFiles/ClickCount.aspx?NewsId=NewsId"> </script> </font>次 Time </div>
    <div style="width: 417px; height: 100px">
    Content </div>
    <div style="width: 416px; height: 9px">
    Pager </div>
    <div style="width: 416px; height: 8px">
    <form id="form1" action="../AddComment.aspx" style="margin:0px">
    <input id="Text1" type="text" /> <Img id="Image1" src="http://www.dwww.cn/UserInfo/CheckCode.aspx"/> <br />
    <textarea id="CommentContent" cols="20" rows="2"> </textarea>
    <br />
    <input id="NewsId" type="hidden" value="NewsId"/>
    <input id="Button1" type="submit" value="button" />
    <a href="http://www.dwww.cn/News/Display.aspx?NewsId=NewsId">查看更多评论 </a> </form>
    </div>
    </body>
    </html>


    2、前态页面 NewsAdd.aspx,就是一个表单,用来填写新闻的标题和内容。

    <%@ Page Language="C#" AutoEventWireup="false" validateRequest="false" CodeFile="NewsAdd.aspx.cs" Inherits="NewsAdd.Admin_AdminPanel_NewsAdd" %>
    <%@ Register TagPrefix="FCKeditorV2" Namespace="FredCK.FCKeditorV2" Assembly="FredCK.FCKeditorV2" %>
    <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">

    <html xmlns="http://www.w3.org/1999/xhtml" >
    <head runat="server">
    <title>添加新闻 </title>
    </head>
    <body>
    <form id="form1" runat="server">
    <div>
    <asp:Label ID="Label2" runat="server" Text="标题"> </asp:Label>
    <asp:TextBox ID="Title" runat="server" Width="325px"> </asp:TextBox> <br />
    <asp:Label ID="Label1" runat="server" Text="内容"> </asp:Label>
    <FCKeditorV2:FCKeditor id="Content" basePath="~/FCKeditor/" runat="server" Height="400px" Width="70%"> </FCKeditorV2:FCKeditor>
    <asp:Button ID="Button1" runat="server" onClick="Button1_Click" Text="Button" />
    <asp:Label ID="Message" runat="server" > </asp:Label> </div>
    </form>
    </body>
    </html>


    3、后台页面 NewsAdd.aspx.cs

    using System;
    using System.Data;
    using System.Configuration;
    using System.Collections;
    using System.Web;
    using System.Web.Security;
    using System.Web.UI;
    using System.Web.UI.WebControls;
    using System.Web.UI.WebControls.WebParts;
    using System.Web.UI.HtmlControls;
    using Mysqlserver;
    using System.IO;
    using System.Text;
    namespace NewsAdd
    {
    public partial class Admin_AdminPanel_NewsAdd : System.Web.UI.Page
    {
    protected void Page_Load(object sender, EventArgs e)
    {

    }
    protected void Button1_Click(object sender, EventArgs e)
    {
    string strDate = DateTime.Now.ToString("yyMMdd") + "\" + DateTime.Now.ToString("yyyymmddhhmmss");
    string strFileName = strDate + ".shtml";//存储到数据库中
    string strTitle=Request.Form["Title"].ToString().Trim();//接收传过来的标题
    string strContent=Request.Form["Content"].ToString().Trim();//接收传过来的内容
    string[] content = strContent.Split(new Char[] {' ¦'});//对内容进行拆分,并保存到数组
    int upbound = content.Length;//数组的上限
    SqlServerDataBase db = new SqlServerDataBase();
    bool success = db.Insert("insert into inNews(Title,Content,FilePath)values('" + strTitle + "','" + strContent + "','" + strFileName + "')", null);
    //if (success)
    // Message.Text = "添加成功!";
    /**////////////////////////////创建当前日期的文件夹开始
    string dir = Server.MapPath("../../"+"NewsFiles/"+DateTime.Now.ToString("yyMMdd"));//用来生成文件夹
    if (!Directory.Exists(dir))
    {
    Directory.CreateDirectory(dir);
    }
    /**////////////////////////////创建当前日期的文件夹结束
    try
    {
    for (int i = 0; i < content.Length; i++)
    {
    //string[] newContent = new string[4];//定义和html标记数目一致的数组
    StringBuilder strhtml = new StringBuilder();

    //创建StreamReader对象
    using (StreamReader sr = new StreamReader(Server.MapPath("../../" + "NewsFiles/") + "\template.html",Encoding.GetEncoding("gb2312")))
    {
    String oneline;
    //读取指定的HTML文件模板
    while ((oneline = sr.ReadLine()) != null)
    {
    strhtml.Append(oneline);
    }
    sr.Close();
    }

    //为标记数组赋值
    //SqlServerDataBase db = new SqlServerDataBase();
    DataSet ds = db.Select("select top 1 NewsId from inNews order by NewsId desc", null);//获取id
    string strTable = " <table> <tr> <td>upUrl </td> <td>Number </td> <td>downUrl </td> </tr> </table>";//上下页表格,注意此处的upUrl(上一页),Number(页码分页),downUrl(下一页)
    //这三个是用来替换的。

    string FilePath="";
    strhtml = strhtml.Replace("Title", strTitle);
    strhtml = strhtml.Replace("NewsId", ds.Tables[0].Rows[0]["NewsId"].ToString());
    strhtml = strhtml.Replace("Time", DateTime.Now.ToString("yyyy/MM/dd"));
    strhtml = strhtml.Replace("Content", contentIdea);
    string strNumber = "";//数字分页1,2,3……
    for (int m = 1; m <=upbound; m++)
    {
    if (m == 1)//如果是第一页就显示成这个样子:20070524.shtml而不是20070524_1.shtml
    strNumber = strNumber + " ["+" <a href=" + "../" + strDate + ".shtml" + ">" + m + " </a>"+"] ";
    else
    {
    int n = m - 1;//第三页的连接应该是20070524_2.shtml,以此类推
    strNumber = strNumber + " [" +" <a href=" + "../" + strDate + "_" + n + ".shtml" + ">" + m + " </a>"+"] ";
    }
    }
    if (upbound == 0)//如果没有分页,就直接按日期时间保存
    {
    FilePath = Server.MapPath("../../") + "NewsFiles" + "//" + strDate + ".shtml";
    strhtml = strhtml.Replace("Pager", "");
    }
    else//否则按20070524.shtml、20070524_1.shtml 这种效果保存
    {
    if (i == 0)
    FilePath = Server.MapPath("../../") + "NewsFiles" + "//" + strDate + ".shtml";
    else
    FilePath = Server.MapPath("../../") + "NewsFiles" + "//" + strDate + "_" + i + ".shtml";

    if (i == 0)//第一页不显示上一页
    strTable = strTable.Replace("upUrl", "");

    if (i <= 1)//上一页分页
    strTable = strTable.Replace("upUrl", " <a href=" + "../" + strDate + ".shtml" + ">上一页 </a>");
    else
    {
    int p = i - 1;
    strTable = strTable.Replace("upUrl", " <a href=" + "../" + strDate + "_" + p + ".shtml" + ">上一页 </a>");
    }

    if(upbound==1)//如果只有一页,则不显示页码
    //strNumber="";
    strTable = strTable.Replace("Number", "");
    else
    strTable = strTable.Replace("Number", strNumber);//页码替换
    /**/////////////////////////
    if(i==upbound-1)//最后一页不显示下一页
    strTable = strTable.Replace("downUrl", "");

    if (i != upbound - 1)//下一页分页
    {
    int q = i + 1;
    strTable = strTable.Replace("downUrl", " <a href=" + "../" + strDate + "_" + q + ".shtml" + ">下一页 </a>");
    }
    else
    {
    int j = upbound - 1;
    strTable = strTable.Replace("downUrl", " <a href=" + "../" + strDate + "_" + j + ".shtml" + ">下一页 </a>");
    }

    strhtml = strhtml.Replace("Pager", strTable);
    }
    //创建文件信息对象--------------------------------------------
    FileInfo finfo = new FileInfo(FilePath);
    //以打开或者写入的形式创建文件流
    using (FileStream fs = finfo.OpenWrite())
    {
    //根据上面创建的文件流创建写数据流
    StreamWriter sw = new StreamWriter(fs, System.Text.Encoding.Default);
    //把新的内容写到创建的HTML页面中
    sw.WriteLine(strhtml);
    sw.Flush();
    sw.Close();
    }
    }
    }
    catch (Exception err)
    {
    //输出异常信息
    Response.Write(err.ToString());
    }
    }
    }
    }


    请不要直接拷贝使用,里面的路径需要更改,但程序绝对没问题,在我本地已经测试通过。

    另外在使用时,比如我要把新闻的内容分成4页,就应该这样写:111 ¦222 ¦333 ¦444。

  • 再遇ORA-12516

    記得以前有過一次,今天用戶再次反應又連不上數據庫了,遇到問題總要先查找原因,後尋找解決辦法,這個過程困難,也給心裡造成壓力。

    避免後續再次出現同樣的問題,能夠最快時間順利輕鬆解決,今天就記錄之,平衡心理壓力呵...

    問題描述:

    [oracle@test dbs]$ oerr ora 12516
    12516, 00000, "TNS:listener could not find available handler with matching protocol stack"
    // *Cause: None of the known and available service handlers for the given
    // SERVICE_NAME support the client's protocol stack: transport, session,
    // and presentation protocols.
    // *Action: Check to make sure that the service handlers (e.g. dispatchers)
    // for the given SERVICE_NAME are registered with the listener, are accepting
    // connections, and that they are properly configured to support the desired
    // protocols.

    診斷過程:

    [oracle@test dbs]$ lsnrctl status

    LSNRCTL for Linux: Version 10.2.0.1.0 - Production on 23-MAY-2008 13:59:30

    Copyright (c) 1991, 2005, Oracle.  All rights reserved.

    Connecting to (DESCRIPTION=(ADDRESS=(PROTOCOL=IPC)(KEY=EXTPROC1)))
    STATUS of the LISTENER
    ------------------------
    Alias                     LISTENER
    Version                   TNSLSNR for Linux: Version 10.2.0.1.0 - Production
    Start Date                23-MAY-2008 13:20:03
    Uptime                    0 days 0 hr. 39 min. 27 sec
    Trace Level               off
    Security                  ON: Local OS Authentication
    SNMP                      OFF
    Listener Parameter File   /u01/app/oracle/oracle/product/10.2.0/db_1/network/admin/listener.ora
    Listener Log File         /u01/app/oracle/oracle/product/10.2.0/db_1/network/log/listener.log
    Listening Endpoints Summary...
      (DESCRIPTION=(ADDRESS=(PROTOCOL=ipc)(KEY=EXTPROC1)))
      (DESCRIPTION=(ADDRESS=(PROTOCOL=tcp)(HOST=10.182.4.65)(PORT=1521)))
    Services Summary...
    Service "PLSExtProc" has 1 instance(s).
      Instance "PLSExtProc", status UNKNOWN, has 1 handler(s) for this service...
    Service "infuse01" has 1 instance(s).
      Instance "infuse01", status UNKNOWN, has 1 handler(s) for this service...
    Service "infuse02" has 1 instance(s).
      Instance "infuse02", status UNKNOWN, has 1 handler(s) for this service...
    Service "sgwmsdb" has 1 instance(s).
      Instance "sgwmsdb", status READY, has 1 handler(s) for this service...
    Service "sgwmsdbXDB" has 1 instance(s).
      Instance "sgwmsdb", status READY, has 1 handler(s) for this service...
    Service "sgwmsdb_XPT" has 1 instance(s).
      Instance "sgwmsdb", status READY, has 1 handler(s) for this service...
    Service "test" has 1 instance(s).
      Instance "test", status READY, has 1 handler(s) for this service...
    Service "testXDB" has 1 instance(s).
      Instance "test", status READY, has 1 handler(s) for this service...
    Service "test_XPT" has 1 instance(s).
      Instance "test", status READY, has 1 handler(s) for this service...
    The command completed successfully

    [oracle@test dbs]$ ps -ef|grep ora_

    oracle    5018     1  0 Mar07 ?        00:00:41 ora_pmon_test
    oracle    5020     1  0 Mar07 ?        00:01:45 ora_psp0_test
    oracle    5022     1  0 Mar07 ?        00:00:01 ora_mman_test
    oracle    5024     1  0 Mar07 ?        00:02:50 ora_dbw0_test
    oracle    5026     1  0 Mar07 ?        00:07:52 ora_lgwr_test
    oracle    5028     1  0 Mar07 ?        00:03:21 ora_ckpt_test
    oracle    5030     1  0 Mar07 ?        00:04:53 ora_smon_test
    oracle    5032     1  0 Mar07 ?        00:00:00 ora_reco_test
    oracle    5034     1  0 Mar07 ?        00:01:46 ora_cjq0_test
    oracle    5036     1  0 Mar07 ?        00:05:06 ora_mmon_test
    oracle    5038     1  0 Mar07 ?        00:02:11 ora_mmnl_test
    oracle    5040     1  0 Mar07 ?        00:00:00 ora_d000_test
    oracle    5042     1  0 Mar07 ?        00:00:00 ora_s000_test
    oracle    5052     1  0 Mar07 ?        00:01:12 ora_arc0_test
    oracle    5054     1  0 Mar07 ?        00:01:11 ora_arc1_test
    oracle    5058     1  0 Mar07 ?        00:00:00 ora_qmnc_test
    oracle    5075     1  0 Mar07 ?        00:00:00 ora_q000_test

    發現缺少job進程ora_j000_test

    [oracle@test dbs]$ sqlplus / as sysdba

    SQL*Plus: Release 10.2.0.1.0 - Production on Fri May 23 13:23:22 2008

    Copyright (c) 1982, 2005, Oracle.  All rights reserved.

    Connected.
    SQL> select name from v$database;
    select name from v$database
    *
    ERROR at line 1:
    ORA-01012: not logged on


    SQL> exit

    [oracle@test dbs]$ ps -ef|grep oracle|wc -l
    172

    而spfile文件中processes = 150,從而判斷,這個值太小導致新用戶無法再連入DB.

    數據庫處於not log on 狀態,無法直接修改相應參數,於是就先把相關oracle進程kill掉後,可以正常登錄數據庫.

    [oracle@test dbs]$ sqlplus / as sysdba

    SQL*Plus: Release 10.2.0.1.0 - Production on Fri May 23 14:08:52 2008

    Copyright (c) 1982, 2005, Oracle.  All rights reserved.


    Connected to:
    Oracle Database 10g Enterprise Edition Release 10.2.0.1.0 - Production
    With the Partitioning, OLAP and Data Mining options

    SQL> alter system set processes=300 scope=spfile;

    SQL> shutdown immediate;

    SQL> startup;

    以上,用戶正常使用.

    Posted Jul 01 2008, 02:16 PM by Coolboy with 1 comment(s)
    Filed under:
  • iis6.0故障

    IIS6.0服务器架站无法访问解决方案总结
    阅读: 时间:2004-10-4 5:07:25 来源:黑客基地 编辑:黑客基地 
     虽然这些都是些简单的东西,但在IIS里很多网友经常问到,所以就总结了一下。

    --------------------------------------------------------------
    **************************************
    附:解决与“HTTP 500 - Internal Server Error”(HTTP 500 – 内部服务器错误)错误信息有关的问题
    http://support.microsoft.com/?kbid=311766&ln=zh-cn

    **************************************
    ---------------------------------------------------------------------
      很多朋友在用IIS6架网站的时候遇到不少问题,而这些问题有些在过去的IIS5里面就遇到过,有些是新出来的,俺忙活了一下午,做了很多次试验,结合以前的排错经验,做出了这个总结,希望能给大家帮上忙

      如果你的服务器是2003的,它默认只支持.net,不支持asp所以须进行以下操作:

    打开iis6.0里面的本地计算机->web服务扩展
    把active server pages 允许就行了

    问题1:未启用父路径

    症状举例:

    Server.MapPath() 错误 'ASP 0175 : 80004005'
    不允许的 Path 字符
    /0709/dqyllhsub/news/OpenDatabase.asp,行 4
    在 MapPath 的 Path 参数中不允许字符 '..'。

    原因分析:

      许多Web页面里要用到诸如../格式的语句(即回到上一层的页面,也就是父路径),而IIS6.0出于安全考虑,这一选项默认是关闭的。

    解决方法:

    在IIS中 属性->主目录->配置->选项中。把”启用父路径“前面打上勾。确认刷新。

    问题2:ASP的Web扩展配置不当(同样适用于ASP.NET、CGI)

    症状举例:

    HTTP 错误 404 - 文件或目录未找到。

    原因分析:

      在IIS6.0中新增了web程序扩展这一选项,你可以在其中对ASP、ASP.NET、CGI、IDC等程序进行允许或禁止,默认情况下ASP等程序是禁止的。

    解决方法:

      在IIS中的Web服务扩展中选中Active Server Pages,点击“允许”。

    问题3:身份认证配置不当

    症状举例:

    HTTP 错误 401.2 - 未经授权:访问由于服务器配置被拒绝。

    原因分析:IIS 支持以下几种 Web 身份验证方法:

    匿名身份验证

      IIS 创建 IUSR_计算机名称 帐户(其中 计算机名称 是正在运行 IIS 的服务器的名称),用来在匿名用户请求 Web 内容时对他们进行身份验证。此帐户授予用户本地登录权限。你可以将匿名用户访问重置为使用任何有效的 Windows 帐户。

    基本身份验证

      使用基本身份验证可限制对 NTFS 格式 Web 服务器上的文件的访问。使用基本身份验证,用户必须输入凭据,而且访问是基于用户 ID 的。用户 ID 和密码都以明文形式在网络间进行发送。

    Windows 集成身份验证

      Windows 集成身份验证比基本身份验证安全,而且在用户具有 Windows 域帐户的内部网环境中能很好地发挥作用。在集成的 Windows 身份验证中,浏览器尝试使用当前用户在域登录过程中使用的凭据,如果尝试失败,就会提示该用户输入用户名和密码。如果你使用集成的 Windows 身份验证,则用户的密码将不传送到服务器。如果该用户作为域用户登录到本地计算机,则他在访问此域中的网络计算机时不必再次进行身份验证。

    摘要身份验证

      摘要身份验证克服了基本身份验证的许多缺点。在使用摘要身份验证时,密码不是以明文形式发送的。另外,你可以通过代理服务器使用摘要身份验证。摘要身份验证使用一种挑战/响应机制(集成 Windows 身份验证使用的机制),其中的密码是以加密形式发送的。

    .NET Passport 身份验证

      Microsoft .NET Passport 是一项用户身份验证服务,它允许单一签入安全性,可使用户在访问启用了 .NET Passport 的 Web 站点和服务时更加安全。启用了 .NET Passport 的站点会依靠 .NET Passport 中央服务器来对用户进行身份验证。但是,该中心服务器不会授权或拒绝特定用户访问各个启用了 .NET Passport 的站点。

    解决方法:

      根据需要配置不同的身份认证(一般为匿名身份认证,这是大多数站点使用的认证方法)。认证选项在IIS的属性->安全性->身份验证和访问控制下配置。

    问题4:IP限制配置不当

    症状举例:

    HTTP 错误 403.6 - 禁止访问:客户端的 IP 地址被拒绝。

    原因分析:

      IIS提供了IP限制的机制,你可以通过配置来限制某些IP不能访问站点,或者限制仅仅只有某些IP可以访问站点,而如果客户端在被你阻止的IP范围内,或者不在你允许的范围内,则会出现错误提示。

    解决方法:

      进入IIS的属性->安全性->IP地址和域名限制。如果要限制某些IP地址的访问,需要选择授权访问,点添加选择不允许的IP地址。反之则可以只允许某些IP地址的访问。

    问题5:IUSR账号被禁用

    症状举例:

    HTTP 错误 401.1 - 未经授权:访问由于凭据无效被拒绝。

    原因分析:

      由于用户匿名访问使用的账号是IUSR_机器名,因此如果此账号被禁用,将造成用户无法访问。

    解决办法:

      控制面板->管理工具->计算机管理->本地用户和组,将IUSR_机器名账号启用。


    问题6:NTFS权限设置不当

    症状举例:

    HTTP 错误 401.3 - 未经授权:访问由于 ACL 对所请求资源的设置被拒绝。

    原因分析:

      Web客户端的用户隶属于user组,因此,如果该文件的NTFS权限不足(例如没有读权限),则会导致页面无法访问。

    解决办法:

      进入该文件夹的安全选项卡,配置user的权限,至少要给读权限。关于NTFS权限设置这里不再馈述。

    问题7:IWAM账号不同步

    症状举例:

    HTTP 500 - 内部服务器错误

    原因分析:

      IWAM账号是安装IIS时系统自动建立的一个内置账号。IWAM账号建立后被Active Directory、IIS metabase数据库和COM+应用程序三方共同使用,账号密码被三方分别保存,并由操作系统负责这三方保存的IWAM密码的同步工作。系统对IWAM账号的密码同步工作有时会失效,导致IWAM账号所用密码不统一。

    解决办法:

      如果存在AD,选择开始->程序->管理工具->Active Directory用户和计算机。为IWAM账号设置密码。

    运行c:\Inetpub\AdminScripts>adsutil SET w3svc/WAMUserPass +密码 同步IIS metabase数据库密码
    运行cscript c:\inetpub\adminscripts\synciwam.vbs -v 同步IWAM账号在COM+应用程序中的密码

    问题8:MIME设置问题导致某些类型文件无法下载(以ISO为例)

    症状举例:

    HTTP 错误 404 - 文件或目录未找到。

    原因分析:

      IIS6.0取消了对某些MIME类型的支持,例如ISO,致使客户端下载出错。

    解决方法:

      在IIS中 属性->HTTP头->MIME类型->新建。在随后的对话框中,扩展名填入.ISO,MIME类型是application。

      另外,防火墙阻止,ODBC配置错误,Web服务器性能限制,线程限制等因素也是造成IIS服务器无法访问的可能原因,这里就不再一一馈述了。希望此帖能解决大家的大部分问题

  • 很多年不玩IIS了 ,装了6.0运行一些老的ASP 居然404错误

    很多年不玩IIS了 ,装了6.0运行一些老的ASP 居然404错误,搞了老半天 ,发现居然是IIS默认不支持ASP了 得的WEB扩展服务里面启用ASP

    Posted Jun 20 2008, 03:12 PM by Coolboy with no comments
    Filed under: , ,
More Posts Next page »
Copyright SDT, 2006-2009. All rights reserved.