<rt id="bn8ez"></rt>
<label id="bn8ez"></label>

  • <span id="bn8ez"></span>

    <label id="bn8ez"><meter id="bn8ez"></meter></label>

    莊周夢蝶

    生活、程序、未來
       :: 首頁 ::  ::  :: 聚合  :: 管理

    一、什么時候數組和指針是相同的
    1、表達式中的數組名(與聲明不同)被編譯器當作一個指向該數組第一個元素的指針
    因此如a[i]這樣的訪問都被編譯器改寫或解釋為*(a+i)的形式,同樣取下標操作符的操作數是可交換的,所以a[3]可以寫成3[a],不過通常你不會這樣做。

    2、下標總是與指針的偏移量相同,下標*sizeof(元素類型)就是偏移數組起始地址的實際字節數。

    3、“作為函數參數的數組名”等同于指針,任何傳遞給函數的數組參數都會被轉換成指針,這是基于效率考慮,避免了數組的拷貝。在函數內部,數組參數都將被轉換成一個指針,要牢記這一點,因此如:
    void test(char a[10])
    {
       printf(
    "%d\n",sizeof(a));
    }

    顯然應該打印指針大小4,而非數組大小。另外,注意數組參數的地址跟數組參數第一個元素的地址并不相等,在表達式中兩者一致,但是在函數調用中,由于數組參數指針也是臨時變量,因此兩者的地址是不一樣的。
    可以通過下列程序觀察:

    #include <stdio.h>
    #include 
    <stdlib.h>
    void test1(char a[])
    {
        printf(
    "&a=%x,&(a[0])=%x,&(a[1])=%x\n",&a,&(a[0]),&(a[1]));
    }
    void test2(char *b)
    {
        printf(
    "&b=%x,&(b[0])=%x,&(b[1])=%x\n",&b,&(b[0]),&(b[1])); 
    }
    int main(int argc, char *argv[])
    {
      
    char ga[]="hello";
      printf(
    "&ga=%x,&(ga[0])=%x,&(ga[1])=%x\n",&ga,&(ga[0]),&(ga[1])); 
      test1(ga);
      test2(ga);
      system(
    "pause");
      
    return 0;
    }


    二、指針跟數組什么時候不同
    1、如果定義了一個數組,在其他文件對它進行聲明也必須聲明為數組,定義和聲明必須匹配,指針也是如此。
    2、指針始終是指針,它絕不可以寫成數組。可以用下標形式訪問指針的時候,一般都是指針作為函數參數時,并且你知道傳遞給函數的實際是一個數組。
    3、數組名是不可改變的左值,因此如
    int array[100],array2[100];
    array
    =array2;
    array++;
    array--;
     
    都將出錯,但是在函數內部:

    int array2[100];
    void fun(int array[])
    {
      array
    =array2;
    }

    卻可以,因為在函數內部array雖然被聲明為數組實際上卻是指針。






    posted @ 2009-02-17 00:05 dennis 閱讀(1979) | 評論 (4)編輯 收藏

       最近的心情可以用一首歌來形容,阿岳的《無路用的人》,唱到心坎里了。無路用是閩南語,是指一個人沒啥出息,沒做出什么事情。在廈門一個多月了,有點不堅定,有點彷徨,有點郁悶,無以形容。

    每天我醒來在床上就在發呆
    我的腦袋跟天花板一樣空白
    昨天在干嘛 明天要干嘛
    我的靈魂 似乎不在我的身上
    唉呀 未接電話那么多
    我想 狗屁事也非常多
    好希望 這是一場夢
    可以讓我 輕輕松松忘掉很多
    哇勒干 怎么可能會是一場夢呢
    我很自由 可是沒有工作
    是一種痛苦的自由
    我在驚什么 我在怕什么
    也許 自由 是我逃避的借口
    誰能夠告訴我 我哪里出了錯
    反省 是多么重要的事情
    可是我到最近才慢慢了解
    笨蛋 這兩個字我常常罵別人
    現在 我只會罵我自己
    我了解自己嗎 不知道
    都已經幾歲了 還不知道
    這幾年 用盡所有力氣
    試圖證明我跟別人不一樣 懶覺啦
    我的白癡自信和白癡驕傲 害了我
    我很欠罵 我是傻瓜 我好辛苦 失去方向
    我在懷疑 我在忍耐 我在等待 我在干嘛
    我很欠罵 我是傻瓜 我好辛苦 失去方向
    我在懷疑 我在忍耐 我在等待 我在干嘛
    我很欠罵 我是傻瓜 我好辛苦 失去方向
    我在懷疑 我在忍耐 我在等待 我在干嘛
    我很欠罵 我是傻瓜 我好辛苦 來 跟我一起唱
    一起唱 一起唱 一起唱
    一起唱 一起唱 一起唱
    度日如年哪 支離破碎的生活
    我就象是沒靈魂 在街上晃呀晃
    象一灘死水 一種絕望的感覺
    沒有多余的眼淚來可憐自己
    沒有人陪我 寂寞的街上
    霓虹燈閃耀 它似乎在笑我
    哈哈哈 無路用的人
    一起唱 一起唱 一起唱
    度日如年哪 支離破碎的生活
    我就象是沒靈魂 在街上晃呀晃
    象一灘死水 一種絕望的感覺
    沒有多余的眼淚來可憐自己
    沒有人陪我 寂寞的街上
    霓虹燈閃耀 它似乎在笑我
    哈哈哈 無路用的人
    一起唱 一起唱 一起唱
    度日如年哪 支離破碎的生活
    我就象是沒靈魂 在街上晃呀晃
    象一灘死水 一種絕望的感覺
    沒有多余的眼淚來可憐自己
    沒有人陪我 寂寞的街上
    霓虹燈閃耀 它似乎在笑我
    哈哈哈 無路用的人
    一起唱 一起唱 一起唱
    啦...啦...啦...啦...
    無路用的人



    posted @ 2009-02-16 22:36 dennis 閱讀(513) | 評論 (2)編輯 收藏

        俺的山寨nio框架yanf4j發布0.50-alpha版本,下載地址在這里,更新了wiki。本測試版本主要修改如下:
    1、Controller接口引入了兩個新方法

    a)接受InetSocketAddress類型參數的系列open方法,用以在多宿主機上綁定到不同網絡接口
         
        
    public void open(InetSocketAddress inetSocketAddress, boolean reuseAddr,
                Handler handler, CodecFactory codecFactory) 
    throws IOException;
        
    public void open(InetSocketAddress inetSocketAddress, boolean reuseAddr,
                Handler handler) 
    throws IOException;
        
    public void open(InetSocketAddress inetSocketAddress, Handler handler)
                
    throws IOException;
        
    public void open(InetSocketAddress inetSocketAddress, Handler handler,
                CodecFactory codecFactory) 
    throws IOException;

    b)wakeup()方法,用以喚醒阻塞在select調用上的reactor,此方法的重載版本可以傳入session和 EventType指定觸發


        
    public void wakeup();
        
    public void wakeup(Session session, EventType eventType);

    通常來說,你并不需要用到此方法。

    2、TCPController添加了backlog的getter和setter方法,用以設置backlog隊列大小

       
    public int getBacklog();
      
    public void setBacklog(int backlog);

    3、reuseAddress默認修改為false,防止服務器悄無聲息地啟動出錯,除非你明確指定。

    4、修復數個bug,如session啟動未注冊到controller、關閉session在異常情況下Controller沒有移除session可能造成內存泄露等問題

    5、一些優化手段,依照ACE建議調整事件派發順序等

    6、一些重構,因為早期AbstractController并不龐大,因而將Reactor作為它的內部類實現,現在隨著代碼的添加,AbstractController變的復雜難懂,因而將Reactor從AbstractController抽離成獨立的類,引入新的接口如SessionEventManager、ControllerLifeCycle、ControllerWrapper以及SelectionKeyHandler等。

    7、可以在jdk5.0下使用yanf4j了,原來僅支持1.6以上,不過你需要自己編譯,二進制包仍然僅提供jdk6.0編譯版本。

    posted @ 2009-02-04 19:28 dennis 閱讀(1938) | 評論 (0)編輯 收藏

        ACE_Reactor在windows上默認不是使用ACE_Select_Reactor,而是ACE_WFMO_Reactor(封裝了WaitForMultipleObjects和WSAEventSelect)。如果想選擇ACE_Select_Reactor,如:

    ACE_Select_Reactor select_reactor;
    ACE_Reactor reactor (
    &select_reactor);

        那么VC需要啟用/GR編譯選項,具體做法就是在項目屬性c/c++的語言一欄中啟用RTTI信息即可。在選擇了ACE_Select_Reactor之后,啟動進程后在ProcessExplorer果然可以看到進程的TCP屬性中建立了兩個互連的TCP連接,用以notify的實現。





    posted @ 2009-02-03 15:40 dennis 閱讀(921) | 評論 (0)編輯 收藏

    相對完整的修改版本

      1 /************************************************************************ 
      2 * @file: echo.cpp                                                    
      3 * @author: dennis
      4 * @revise: dennis <killme2008@gmail.com> http://www.tkk7.com/killme2008
      5 *          相對完整的echo server,可以接受多個客戶端連接,并且可以通過鍵入quit正常關閉
      6 
      7 ************************************************************************/
      8 
      9 #ifdef _DEBUG
     10 #pragma comment (lib,"aced.lib")
     11 #else
     12 #pragma comment (lib,"ace.lib")
     13 #endif
     14 
     15 #include "ace/Reactor.h"
     16 #include "ace/SOCK_Acceptor.h"
     17 #include "ace/os.h"
     18 #include "ace/Log_Msg.h"
     19 #include "ace/inet_addr.h"
     20 #include "ace/Thread_Manager.h"
     21 #include<iostream>
     22 #include<string>
     23 
     24 #define PORT_NO 8080
     25 typedef ACE_SOCK_Acceptor Acceptor;
     26 //forward declaration
     27 class Echo_Handler;
     28 
     29 class Echo_Handler:public ACE_Event_Handler
     30 {
     31 public:
     32     //construcor
     33     Echo_Handler()
     34     {
     35     }
     36     virtual ~Echo_Handler()
     37     {
     38     }
     39     //Called back to handle any input received
     40     int handle_input(ACE_HANDLE)
     41     {
     42         //receive the data
     43         ssize_t recvBytes = peer().recv(data,12);
     44         if(recvBytes <= 0)
     45         {
     46             ACE_DEBUG((LM_DEBUG,"%s\n","客戶端斷開連接"));
     47             return -1;
     48         }
     49         data[recvBytes] = 0;
     50 
     51         ACE_DEBUG((LM_DEBUG,"%s\n",data));
     52 
     53 
     54         if(ACE_OS::strcmp(data,"q"== 0)
     55         {
     56             ACE_DEBUG((LM_DEBUG,"%s\n","客戶端退出"));
     57             peer().close();
     58             return -1;
     59         }
     60         peer().send_n(data,recvBytes);
     61         // do something with the input received.
     62         // 
     63         // keep yourself registerd with the reator
     64         return 0;
     65     }
     66 
     67     int handle_close(ACE_HANDLE h,ACE_Reactor_Mask m)
     68     {
     69         delete this;
     70         return  0;
     71     }
     72 
     73     //Used by the reactor to determine the underlying handle
     74     ACE_HANDLE get_handle()  const 
     75     {
     76         return this->peer_.get_handle();
     77     }
     78 
     79     //Returns a reference to the underlying stream.
     80     ACE_SOCK_Stream& peer()
     81     {
     82         return this->peer_;
     83     }
     84 
     85 private:
     86     ACE_SOCK_Stream peer_;
     87     char data [12];
     88 };
     89 
     90 class Echo_Accept_Handler:public ACE_Event_Handler
     91 {
     92 public:
     93     //Constructor
     94     Echo_Accept_Handler(ACE_Addr &addr)
     95     {
     96         this->open(addr);
     97     }
     98     virtual ~Echo_Accept_Handler(){}
     99     //Open the peer_acceptor so it starts to "listen"
    100     //for incoming clients
    101     int open(ACE_Addr &addr)
    102     {
    103         if(peer_acceptor.open(addr)==-1)
    104             ACE_ERROR_RETURN((LM_ERROR,"啟動服務器錯誤\n"),1);
    105         return 0;
    106     }
    107 
    108     //Overload the handle input method
    109     int handle_input(ACE_HANDLE handle)
    110     {
    111         //Client has requested connection to server.
    112         //Create a handler to handle the connection
    113         Echo_Handler *eh;
    114         ACE_NEW_RETURN(eh,Echo_Handler,-1);
    115         ACE_INET_Addr cliaddr;
    116         //Accept the connection "into" the Event Handler
    117         if(this->peer_acceptor.accept(eh->peer(),//stream
    118             &cliaddr,//remote address
    119             0,//timeout
    120             1== -1)//restart if interrupted
    121             ACE_DEBUG((LM_ERROR,"Error in connection \n"));
    122 
    123         ACE_DEBUG((LM_DEBUG,"連接已經建立,來自%s\n",cliaddr.get_host_addr()));
    124 
    125         //Register the input event handler for reading 
    126         ACE_Reactor::instance()->register_handler(eh,ACE_Event_Handler::READ_MASK);
    127         const char* msg = "按q鍵使服務安全退出\r\n";
    128         eh->peer().send_n(msg,strlen(msg)+1);
    129         return 0;
    130     }
    131 
    132     //Used by the reactor to determine the underlying handle
    133     ACE_HANDLE get_handle(voidconst
    134     {
    135         return this->peer_acceptor.get_handle();
    136     }
    137     int handle_close(ACE_HANDLE h,ACE_Reactor_Mask m){
    138         peer_acceptor.close();
    139         delete this;
    140         return 0;
    141     }
    142 
    143 private:
    144     Acceptor peer_acceptor;
    145 };
    146 class Quit_Handler:public ACE_Event_Handler
    147 {
    148 public:
    149     Quit_Handler(ACE_Reactor* r):ACE_Event_Handler(r){}
    150     virtual int handle_exception(ACE_HANDLE)
    151     {
    152         ACE_DEBUG((LM_DEBUG,"停止服務器中\n"));
    153         reactor()->end_reactor_event_loop();
    154         return -1;
    155     }
    156     int handle_close(ACE_HANDLE h,ACE_Reactor_Mask m)
    157     {
    158         delete this;
    159         return 0;
    160     }
    161     virtual ~Quit_Handler(){}
    162 };
    163 static ACE_THR_FUNC_RETURN run_events (void *arg);
    164 static ACE_THR_FUNC_RETURN controller (void *arg);
    165 int ACE_TMAIN(int argc,char *argv[])
    166 {
    167 
    168     ACE_Reactor* reactor=ACE_Reactor::instance();
    169     if(ACE_Thread_Manager::instance()->spawn(run_events,reactor,THR_DETACHED | THR_SCOPE_SYSTEM)==-1)
    170         return 1;
    171     if(ACE_Thread_Manager::instance()->spawn(controller,reactor,THR_DETACHED | THR_SCOPE_SYSTEM)==-1)
    172         return 1;
    173     return ACE_Thread_Manager::instance()->wait();
    174 }
    175 
    176 static ACE_THR_FUNC_RETURN run_events (void *arg)
    177 {
    178     ACE_Reactor* reactor=ACE_static_cast(ACE_Reactor*,arg);
    179     ACE_INET_Addr addr(PORT_NO);
    180 
    181     Echo_Accept_Handler *eh=0;
    182     ACE_NEW_RETURN(eh,Echo_Accept_Handler(addr),1);
    183 
    184     ACE_Reactor::instance()->owner(ACE_OS::thr_self());
    185     reactor->register_handler(eh,ACE_Event_Handler::ACCEPT_MASK);
    186     ACE_Reactor::instance()->run_reactor_event_loop();
    187     return 0;
    188 }
    189 static ACE_THR_FUNC_RETURN controller (void *arg)
    190 {
    191     ACE_Reactor* reactor=ACE_static_cast(ACE_Reactor*,arg);
    192     Quit_Handler *quit_handler=0;
    193     ACE_NEW_RETURN(quit_handler,Quit_Handler(reactor),1);
    194     for(;;)
    195     {
    196         std::string line;
    197         std::getline(std::cin,line,'\n');
    198         if(line=="quit"){
    199             ACE_DEBUG((LM_DEBUG,"請求停止服務器\n"));
    200             reactor->notify(quit_handler);
    201             break;
    202         }
    203     }
    204     return 0;  
    205 }
    206 


    posted @ 2009-02-03 11:59 dennis 閱讀(1693) | 評論 (1)編輯 收藏

        過去推薦過兩篇blog《Java NIO類庫Selector機制解析》(),感嘆java為了跨平臺似乎“很傻很天真”。最近學習使用ACE,才知道這個解決辦法倒不是java開創的,ACE也是這樣搞的。java nio中Selector的wakeup方法,類似于ACE_Select_Reactor的notify機制,可以從非select調用的線程去喚醒阻塞在select調用上的select線程,當然ACE_Select_Reactor的notify強大多了,可以實現event handler的無限擴容。ACE_Select_Reactor的notify的實現是通過ACE_Pipe,在ACE_Pipe中可以清晰地看到針對win32平臺是采用了TCP連接:

    #if defined (ACE_LACKS_SOCKETPAIR) || defined (__Lynx__)
      ACE_INET_Addr my_addr;
      ACE_SOCK_Acceptor acceptor;
      ACE_SOCK_Connector connector;
      ACE_SOCK_Stream reader;
      ACE_SOCK_Stream writer;
      
    int result = 0;
    if defined (ACE_WIN32)
      ACE_INET_Addr local_any  (static_cast
    <u_short> (0), ACE_LOCALHOST);
    else
      ACE_Addr local_any 
    = ACE_Addr::sap_any;
    # endif 
    /* ACE_WIN32 */

      
    // Bind listener to any port and then find out what the port was.
      if (acceptor.open (local_any) == -1
          
    || acceptor.get_local_addr (my_addr) == -1)
        result 
    = -1;
      
    else
        {
          ACE_INET_Addr sv_addr (my_addr.get_port_number (),
                                 ACE_LOCALHOST);

          
    // Establish a connection within the same process.
          if (connector.connect (writer, sv_addr) == -1)
            result 
    = -1;
          
    else if (acceptor.accept (reader) == -1)
            {
              writer.close ();
              result 
    = -1;
            }
        }

      
    // Close down the acceptor endpoint since we don't need it anymore.
      acceptor.close ();

        在類unix平臺是采用STREAMS管道,在一些遺留的unix平臺上是socketpair()。為什么在win32上采用TCP連接的方式呢?原因不是什么性能、資源問題,也不是因為windows管道消耗的資源比tcp多,而是由于winsock的select函數(java nio的select在win32下是使用select實現的)是無法監測管道事件的,也就是說無法將windows管道加入到fd_set中,為了做到可移植,才在win32上采用了TCP連接的方式來實現。這一點在blog上篇的新回復中已經有人提到。

    posted @ 2009-02-01 11:15 dennis 閱讀(3372) | 評論 (0)編輯 收藏

        這幾天沒事做的時候都會上projecteuler.net上面去做題,其中14題是這樣的:
    he following iterative sequence is defined for the set of positive integers:

    n → n/2 (n is even)
    n → 3n + 1 (n is odd)

    Using the rule above and starting with 13, we generate the following sequence:

    13 → 40 → 20 → 10 → 5 → 16 → 8 → 4 → 2 → 1

    It can be seen that this sequence (starting at 13 and finishing at 1) contains 10 terms. Although it has not been proved yet (Collatz Problem), it is thought that all starting numbers finish at 1.

    Which starting number, under one million, produces the longest chain?


        題目并不難理解,這個據說是著名的角谷猜想,現在要找到100萬以下的數字中展開這個鏈最長的數字是多少。如果我一開始就直接按照題意來解答,這個題目花不了幾分鐘,直接暴力法。然而我卻想的太多了,我猜想在計算這個鏈條長度的過程中會不會有很多數字會重復計算,如果加上緩存以前計算的結果是否能節約比較多的時間?那么第一次解答如下:

    #include<iostream>
    #include
    <map>
    #include
    <windows.h>
    using namespace std;
    unsigned 
    long produce_term(unsigned long n)
    {
        
    if(n&1)
            
    return 3*n+1;
        
    else
            
    return n>>1;
    }
    int main()
    {
        map
    <unsigned long,int> counters;
        
    int max_i=0;
        
    int max_count=0;
        DWORD tick1,tickPassed;
        tick1 
    = GetTickCount(); 
        
    for(int i=1;i<1000000;i++)
        {
            
    int sum=2;
            unsigned 
    long term=i;
            
    while((term=produce_term(term))!=1)
            {
                
    if(counters[term]){
                    sum
    +=counters[term];
                    
    break;
                }
    else
                    sum
    +=1;
            }

            
    if(sum>max_count)
            {
                max_i
    =i;
                max_count
    =sum;
                counters[i]
    =sum;
            }

        }
        tickPassed 
    = GetTickCount()-tick1; 
        cout
    <<tickPassed<<endl;
        cout
    <<max_i<<endl<<max_count<<endl;
        
    return 0;
    }
      
        遺憾的是,這個版本跑了快13分鐘,太讓人難以接受了。那么是否能優化下?怎么優化?我的機器是雙核的,跑這個單進程單線程的程序只利用了一半的CPU,那么能不能搞成兩個線程來計算?緩存需要在兩個線程之間做同步,顯然讀的多,寫的少,應該采用讀寫鎖。OK,第二個版本利用ACE的線程封裝實現如下:
    #include<iostream>
    #include
    <map>
    #include 
    "ace/Thread_mutex.h"
    #include 
    "ace/Synch.h"
    #include 
    "ace/Thread_Manager.h"
    using namespace std;
    class ThreadSafeMap
    {
    public:
        ThreadSafeMap()
        {
        }
        
    int get(unsigned long n)
        {
            ACE_READ_GUARD_RETURN(ACE_RW_Thread_Mutex,guard,mutex_,
    0);
            
    return counters_[n];
        }
        
    int put(unsigned long key,int value)
        {
            ACE_WRITE_GUARD_RETURN(ACE_RW_Thread_Mutex,guard,mutex_,
    -1);
            counters_[key]
    =value;
            
    return 0;
        }

    private:
        map
    <unsigned long,int> counters_;
        ACE_RW_Thread_Mutex mutex_;
    };
    unsigned 
    long produce_term(unsigned long n)
    {
        
    if(n&1)
            
    return 3*n+1;
        
    else
            
    return n>>1;
    }
    static ThreadSafeMap counters;
    ACE_THR_FUNC_RETURN run_svc (
    void *arg)
    {
        
    int max_i=0;
        
    int max_count=0;
        
    for(int i=500001;i<1000000;i++)
        {
            
    int sum=2;
            unsigned 
    long term=i;
            
    while((term=produce_term(term))!=1)
            {
                
    if(counters.get(term)){
                    sum
    +=counters.get(term);
                    
    break;
                }
    else
                    sum
    +=1;
            }

            
    if(sum>max_count)
            {
                max_i
    =i;
                max_count
    =sum;
                counters.put(i,sum);
            }

        }
        cout
    <<max_i<<endl<<max_count<<endl;
        
    return 0;
    }
    int main(int ac,char* argv[])
    {
        
    if (ACE_Thread_Manager::instance ()->spawn (
            
    // Pointer to function entry point.
            run_svc,
            
    // <run_svc> parameter.
            NULL,
            THR_DETACHED 
    | THR_SCOPE_SYSTEM) == -1)
            
    return -1;
        
    int max_i=0;
        
    int max_count=0;

        
    for(int i=1;i<500000;i++)
        {
            
    int sum=2;
            unsigned 
    long term=i;
            
    while((term=produce_term(term))!=1)
            {
                
    if(counters.get(term)){
                    sum
    +=counters.get(term);
                    
    break;
                }
    else
                    sum
    +=1;
            }

            
    if(sum>max_count)
            {
                max_i
    =i;
                max_count
    =sum;
                counters.put(i,sum);
            }

        }
        cout
    <<max_i<<endl<<max_count<<endl;
        
    return ACE_Thread_Manager::instance ()->wait ();
    }
       
        將數據分成了兩半,利用兩個線程來計算,果然快了一點,快了多少呢?從13分鐘減少到9分鐘,CPU利用率也到了100%,內存占用也降低了一半,似乎成績不錯呀。正在沾沾自喜之際,突然想起,能不能簡單地暴力破解,咱不搞緩存,不搞多線程,看看效果怎么樣。那么第三個版本簡單實現如下:
    #include<iostream>
    using namespace std;
    unsigned 
    long produce_term(unsigned long n)
    {
        
    if(n&1)
            
    return 3*n+1;
        
    else
            
    return n>>1;
    }
    int main()
    {
      
    int max_i;
      
    int max_count=0;
      
    for(int i=1;i<1000000;i++)
      {
         
    int count=2;
         unsigned 
    long term=i;
         
    while((term=produce_term(term))>1)
             count
    +=1;
         
    if(count>max_count){
               max_i
    =i;
               max_count
    =count;
         }
      }
      cout
    <<max_i<<endl<<max_count<<endl;
      system(
    "pause");
      
    return 0;
    }

        程序執行的結果讓我驚掉了下巴,竟然只執行了1秒多,換成java也是一樣。什么緩存、多線程,全拋到了九霄云外。

         總結教訓,想當然的性能估計是愚不可及的,想當然的優化是愚不可及的,簡單直接才是美!

    posted @ 2009-01-23 00:08 dennis 閱讀(616) | 評論 (3)編輯 收藏

    項目名稱:yanf4j (yet another nio framework for java)
    項目網址:http://code.google.com/p/yanf4j/
    下載網址:http://code.google.com/p/yanf4j/downloads/list

    0.41 beta版的主要修改:

    1、引入流量控制,通過Controller的setReceivePacketRate方法設置接收消息頻率(單位 個/秒),當超過設定值時,yanf4j將放緩接收數據直到實時統計的接收頻率降低。此功能默認未開啟。
    2、改善了數據統計,數據統計不再是從服務器啟動時間點到當前的時間段內的平均統計,而是以一定時間間隔做統計,每隔這個時間段就重新開始數據統計。因此可以反映出不同時間段的流量。默認這個統計區間間隔是5分鐘,可設置。
    3、重構部分代碼,引入Controller接口,修改部分命名不當的API等。

    posted @ 2009-01-20 14:01 dennis 閱讀(1817) | 評論 (0)編輯 收藏

        在cpp中為了可移植性,string的長度是string::size_type,突然就想知道java允許的最大字符串長度為多少。看String的源碼:
    public final class String
      
    110       implements java.io.Serializable, Comparable<String>, CharSequence
      
    111   {
      
    112       /** The value is used for character storage. */
      
    113       private final char value[];
      
    114   
      
    115       /** The offset is the first index of the storage that is used. */
      
    116       private final int offset;
      
    117   
      
    118       /** The count is the number of characters in the String. */
      
    119       private final int count;
       String內部是以char數組的形式存儲,數組的長度是int類型,那么String允許的最大長度就是Integer.MAX_VALUE了。又由于java中的字符是以16位存儲的,因此大概需要4GB的內存才能存儲最大長度的字符串。不過這僅僅是對字符串變量而言,如果是字符串字面量(string literals),如“abc"、"1a2b"之類寫在代碼中的字符串literals,那么允許的最大長度取決于字符串在常量池中的存儲大小,也就是字符串在class格式文件中的存儲格式:
    CONSTANT_Utf8_info {
            u1 tag;
            u2 length;
            u1 bytes[length];
    }

        u2是無符號的16位整數,因此理論上允許的string literal的最大長度是2^16-1=65535。然而實際測試表明,允許的最大長度僅為65534,超過就編譯錯誤了,有興趣可以寫段代碼試試,估計是length還不能為0。

    posted @ 2009-01-15 01:37 dennis 閱讀(62515) | 評論 (7)編輯 收藏

        昨天晚上6點多,從惠安老家到泉州去做到廣州的長途汽車。中途汽車輪胎破了,坐這么久汽車還是第一次遇到,耽擱了一段時間,最后沒趕上7點多的車,只好等待8點半的班車了。晚上的候車室冷冷清清,找了個沒人的座位坐下,一轉頭,才發現旁邊放著一個藍色的大旅行包,包的主人沒看見,下意識地趕緊找個離的遠點的座位坐下。時常聽他人講,看見錢包之類的東西不要揀,因為很可能是騙局,何況這么大一旅行包,萬一丟了什么東西賴我身上可怎么辦。坐下來喝了點水,吃點面包的時候才想起,我什么時候也變的這么小心翼翼了?
        候車室大燈都關了,只有停車場的汽車燈光照進來隱約可見,天氣還是很冷,慶幸前天買了件外套,不然得凍死掉。老家就是風大,畢竟離海邊近,涼颼颼的從門口吹進來。藍色旅行包的主人回來了,看情況是去上廁所,我還暗想他怎么能這么不小心呢,不知道現在拎包黨很猖獗嗎?那人看起來看挺年輕,不過可能比我大,深色夾克,腳上的尖頭皮鞋也搽的挺亮,短發,讓人看起來精神不錯。打量兩眼,我還是玩我的手機游戲打發時間,離上車時間還有半個多小時。
        我正玩的不亦樂乎,突然聽到似乎有人在對我說話。轉頭一看,是那位大哥沖我說著什么。我們隔了4,5個座位,我沒聽清,請他再說了一遍,才知道是問我說這附近有沒有工廠。泉州過去一點就是晉江石獅,那邊工廠是很多的,泉州跟晉江也就隔著一條江,過了大橋就是晉江。我就如此這般跟他說了下。然后他又問這候車室會不會關門,我說我也不清楚了這個情況了,問他怎么問這個。他說他問保安能不能睡在馬路上,保安說隨便,怕治安不好,所以進來這里,又擔心這里晚點會關門。我有點明白怎么回事了,敢情這大哥沒地方睡覺才來這里的啊。我就說泉州治安還是不錯的,這里關門不關門我是不知道的,我不是泉州市內的。然后這大哥主動跟我介紹說是重慶來的,剛到泉州,手頭上只剩4塊,這邊旅館都至少要20,30塊的,住不起了。我有點無言以對,這是在要錢嗎?看樣子也不是那意思,我就跟他聊了聊。原來他是家里老六,兄弟姐妹都成婚了,一個人出來跑,聽他一個回重慶的老鄉介紹說到廈門出海很賺錢,就跑過來了,到廈門勞務市場一問,要到打漁公司需要辦一張450塊錢的漁民證才讓應聘,他沒錢,就聽說泉州這邊工廠多,剩下一點錢就坐車到這里來了,想先找在工廠找份工作做,然后再打算。我是聽我同學說過,出海是挺賺錢的,不過很辛苦,一次出海打漁都要幾個月在海上漂,回來能賺上萬甚至幾萬塊錢,具體的情況就不清楚了,工廠泉州是很多,不過最近常聽到的就是工廠倒閉很多,招不招工也不清楚了,不過找到工作的機會還是比較大的,去年還聽說我們這邊鬧民工荒。我將這情況跟他說一下,建議他去晉江看看那邊的工廠招人不,不好意思幫不上什么忙。突然想起他說只剩4塊錢,晚飯應該還沒吃,我帶了一些糖果和面包準備到廣州去的,想想就分了些粽子、面包給他,猶豫了下也給了20塊錢。他連說謝謝,說沒遇到過我這樣年輕的好心人。我很慚愧,我能做的也只有這樣了,我的廉價的同情也僅僅能幫助他度過一個晚上罷了。我說我也是打工的,我明白一個人出來跑的感覺。
        我問他重慶不是挺好的,為什么跑這么遠出來。他說趁年輕想出來跑跑,再說家里兄弟姐妹都成婚了,自己也要努力下。我說我也是出去打工的,到廣州混飯吃,這次回來結婚,他很高興地恭喜我。我看看時間差不多了,就收拾下東西準備上車了,臨走前祝福他找到好工作。我在想如果他沒有找到工作,到了絕境他會怎么辦,我不敢也不忍去想。不過我還是相信天無絕人之路,以此日志,僅做記錄。
       
       

    posted @ 2008-12-09 17:03 dennis 閱讀(684) | 評論 (8)編輯 收藏

    僅列出標題
    共56頁: First 上一頁 19 20 21 22 23 24 25 26 27 下一頁 Last 
    主站蜘蛛池模板: 亚洲精品乱码久久久久久| 99久久精品日本一区二区免费| 精品成人一区二区三区免费视频| 亚洲综合一区二区三区四区五区| 亚洲人成电影在线观看青青| 亚洲国产精品日韩在线观看| 亚洲小视频在线播放| 亚洲成av人片在线看片| 亚洲国产午夜精品理论片| 亚洲一本之道高清乱码| 亚洲AV无码无限在线观看不卡 | 国产成人精品免费视频网页大全| 人妻无码一区二区三区免费| 日韩精品久久久久久免费| 亚洲免费闲人蜜桃| av免费不卡国产观看| 丁香花在线观看免费观看| 成全视频免费高清| 国产成人免费一区二区三区| 免费在线观看亚洲| 亚洲伊人久久综合影院| 国产亚洲精品国产| 亚洲高清无在码在线无弹窗| 亚洲人成网站在线观看播放青青| 国产精品亚洲午夜一区二区三区| 亚洲色最新高清av网站| 自拍偷自拍亚洲精品播放| 一区二区三区免费视频网站| 成人性生交大片免费看好| 久9这里精品免费视频| 18禁免费无码无遮挡不卡网站 | 久久精品免费一区二区三区| 最近免费字幕中文大全视频| 欧美好看的免费电影在线观看| 国产无遮挡裸体免费视频| 日日噜噜噜噜夜夜爽亚洲精品| 亚洲国产精品免费视频| 亚洲天堂2016| 日韩精品无码免费视频| 午夜不卡久久精品无码免费 | 国产高潮久久免费观看|