隨筆 - 8, 文章 - 0, 評(píng)論 - 6, 引用 - 0
          數(shù)據(jù)加載中……

          2007年7月18日

          實(shí)現(xiàn)一個(gè)棧,使其push,pop,min(取得棧中的最小元素)均為O(1)

          實(shí)現(xiàn)一個(gè)棧,使其push,pop,min(取得棧中的最小元素)均為O(1)

          我的解
          interface IntStack
          {
              
          int pop();
              
          void push(int i);
              
          int get();
          }


          class MinStack
          {
              
          //store all the element
              private IntStack elemStack = new IntStack();
              
              
          //store current and historical smallest element
              private IntStack minStack = new IntStack();
              
              
          public void push(int i)
              
          {
                  elemStack.push(i);
                  
                  
          int currentMin = minStack.get();
                  
          if(i <= currentMin) minStack.push(i);
              }

              
              
          public int pop()
              
          {
                  
          int result = elemStack.pop();
                  
          if(result == minStack.get()) minStack.pop();
                  
          return result;
              }

              
              
          public int getMinElem()
              
          {
                  
          return minStack.get();
              }

          }

          posted @ 2007-07-18 20:57 Job Hu 閱讀(902) | 評(píng)論 (0)編輯 收藏

          二叉排序樹變?yōu)殡p向鏈表

          把一個(gè)二叉排序樹(也許不叫這個(gè))變?yōu)檫f增的雙向鏈表,不能夠生成額外的結(jié)點(diǎn).
          eg 6
                 / \
                4   8
               / \ / \
              3  5 7  9

          3=4=5=6=7=8=9

          我的解:

          class Node
          {
              
          public Node left;
              
          public Node right;
              
              
          private static Node getLinkListTail(Node head)
              
          {
                  Node result 
          = head;
                  
          if(result==nullreturn null;
                  
          while(result.right!=null)
                  
          {
                      result 
          = result.right;
                  }

                  
          return result;
              }

              
              
          public static Node flatten(Node root)
              
          {
                  
          if(root==nullreturn null;
                  
                  Node result 
          = root;
                  
                  
          // A leaf node
                  if(root.left==null&&root.right==nullreturn root;
                  
                  
          //divide-and-conquer
                  Node leftSubTreeLinkListHead = flatten(root.left);
                  Node rightSubTreeLinkListHead 
          = flatten(root.right);
                  
                  
          //merge
                  Node leftSubTreeLinkListTail = getLinkListTail(leftSubTreeLinkListHead);
                  root.left 
          = leftSubTreeLinkListTail;
                  root.right 
          = rightSubTreeLinkListHead;
                  
          if(leftSubTreeLinkListHead!=null
                  
          {
                      result 
          = leftSubTreeLinkListHead;
                      leftSubTreeLinkListTail.right 
          = root;
                  }

                  
          if(rightSubTreeLinkListHead!=null) rightSubTreeLinkListHead.left = root;
                  
                  
          return result;
              }

          }


          posted @ 2007-07-18 20:37 Job Hu 閱讀(648) | 評(píng)論 (0)編輯 收藏

          2007年7月17日

          Byte in Java


          public class ByteTest
          {
              
          public static void main(String[] args)
              
          {
                  
          byte b;
                  
          byte c;
                  
          //b = 255; //Cannot convert from int to byte
                  
          //b = 0xFF; //Cannot convert from int to byte
                  b = 127;
                  c 
          = 0x7F;
                  
          if(b == c) System.out.println("b == c");
                  
          if(127 == 0x7F) System.out.println("127 == 0x7F");
                  
                  b 
          = -128;
                  
          //c = 0x80; //Cannot convert from int to byte
                  c = (byte)0x80;
                  
          if(b == c) System.out.println("b == c");
                  
          if(-128 == 0x80) System.out.println("-128 == 0x80");
                  
          if(128 == 0x80) System.out.println("128 == 0x80"); 
                  
                  c 
          = (byte)0x80;
                  
          if(128 == c) System.out.println("128 == c");
                  
          if(-128 == c) System.out.println("-128 == c");
                  
          if(128 == (c&0xFF)) System.out.println("128 == (c&0xFF)");
              }

          }

          輸出:
          b == c
          127 == 0x7F
          b == c
          128 == 0x80
          -128 == c
          128 == (c&0xFF)

          posted @ 2007-07-17 23:22 Job Hu 閱讀(293) | 評(píng)論 (0)編輯 收藏

          2007年7月9日

          Java Language Keywords

          Here's a list of keywords in the Java programming language. You cannot use any of the following as identifiers in your programs. The keywords const and goto are reserved, even though they are not currently used. true, false, and null might seem like keywords, but they are actually literals; you cannot use them as identifiers in your programs.
          abstract continue for new switch
          assert*** default goto* package synchronized
          boolean do if private this
          break double implements protected throw
          byte else import public throws
          case enum**** instanceof return transient
          catch extends int short try
          char final interface static void
          class finally long strictfp** volatile
          const* float native super while

          posted @ 2007-07-09 22:38 Job Hu 閱讀(201) | 評(píng)論 (1)編輯 收藏

          2007年5月30日

          Tomcat筆記(三)

          來(lái)看看ContainerBasestart方法:
           1public synchronized void start() throws LifecycleException {
           2
           3        //如果Container已經(jīng)處于start狀態(tài),直接返回
           4        if (started) {
           5            if(log.isInfoEnabled())
           6                log.info(sm.getString("containerBase.alreadyStarted", logName()));
           7            return;
           8        }

           9        
          10        // Notify our interested LifecycleListeners
          11        lifecycle.fireLifecycleEvent(BEFORE_START_EVENT, null);
          12
          13        started = true;
          14
          15        // Start our subordinate components, if any
          16        if ((loader != null&& (loader instanceof Lifecycle))
          17            ((Lifecycle) loader).start();
          18        logger = null;
          19        getLogger();
          20        if ((logger != null&& (logger instanceof Lifecycle))
          21            ((Lifecycle) logger).start();
          22    //用來(lái)管理session
          23        if ((manager != null&& (manager instanceof Lifecycle))
          24            ((Lifecycle) manager).start();
          25    //看名字就知道是干什么的,不過(guò)研究集群的優(yōu)先級(jí)很低
          26        if ((cluster != null&& (cluster instanceof Lifecycle))
          27            ((Lifecycle) cluster).start();
          28    //用來(lái)進(jìn)行訪問(wèn)控制,或者權(quán)限控制的
          29        if ((realm != null&& (realm instanceof Lifecycle))
          30            ((Lifecycle) realm).start();
          31    //和JNDI相關(guān)
          32        if ((resources != null&& (resources instanceof Lifecycle))
          33            ((Lifecycle) resources).start();
          34
          35        //啟動(dòng)所有子container
          36        Container children[] = findChildren();
          37        for (int i = 0; i < children.length; i++{
          38            if (children[i] instanceof Lifecycle)
          39                ((Lifecycle) children[i]).start();
          40        }

          41
          42        // 啟動(dòng)Container內(nèi)部持有的pipeline對(duì)象,Container對(duì)Pipeline接口的實(shí)現(xiàn)就是通過(guò)調(diào)用這個(gè)內(nèi)部持有的Pipeline對(duì)象
          43        if (pipeline instanceof Lifecycle)
          44            ((Lifecycle) pipeline).start();
          45
          46        // Notify our interested LifecycleListeners
          47        lifecycle.fireLifecycleEvent(START_EVENT, null);
          48
          49        // 注釋說(shuō)這個(gè)函數(shù)用來(lái)check session是否過(guò)期,但看的不是太懂
          50        threadStart();
          51
          52        // Notify our interested LifecycleListeners
          53        lifecycle.fireLifecycleEvent(AFTER_START_EVENT, null);
          54
          55}

          56
           

          所有和clusterrealm相關(guān)都放在最后來(lái)研究了,不管怎么樣先把tomcat如何處理request的整個(gè)過(guò)程串起來(lái)對(duì)現(xiàn)在的我來(lái)說(shuō)是最重要的。另外還有Tomcat中的很多部件都用到了JMX API,即SNMPJava實(shí)現(xiàn)來(lái)進(jìn)行性能檢測(cè)和管理,這個(gè)也會(huì)放在最后研究。

          ContainerBase就看這么多了,下面來(lái)看看StandardEngine這個(gè)類。除去和clusterrealm、JMX相關(guān)的方法后,StanderdEngine剩下的方法就很很少了。

          StandardEngine有一個(gè)Service類型的成員。Java doc中指出Service就是由很多共享同一個(gè)ContainerConnector組成。一個(gè)Service對(duì)應(yīng)于一個(gè)Container,來(lái)自這個(gè)Service的任何一個(gè)Connectorrequest都會(huì)由其對(duì)應(yīng)的Container進(jìn)行處理??吹浆F(xiàn)在的感覺(jué)就是Connector對(duì)Container提供request對(duì)象,并接受Container返回的response對(duì)象。在Tomcat中有很多類別都被用來(lái)體現(xiàn)現(xiàn)request或者response,例如org.apache.catalina.connector .Request就是Coyote request的一個(gè)wrapper類,Coyote這個(gè)framework幫助封裝了底層的網(wǎng)絡(luò)復(fù)雜性,向上提供一個(gè)統(tǒng)一的接口。我想tomcat既能夠成為一個(gè)standalonehttpjsp/Servlet服務(wù)器,也能夠同apache http server集成,很可能就是依賴于Coyote提供的統(tǒng)一接口。

          在構(gòu)造函數(shù)中會(huì)將StandardEngine這個(gè)Pipeline的最后一個(gè)Valve,即Basic設(shè)置為StandardEngineValve。來(lái)看看StandardEnginValueinvoke方法
           1public final void invoke(Request request, Response response)
           2        throws IOException, ServletException {
           3
           4        // Select the Host to be used for this Request
           5        Host host = request.getHost();
           6        if (host == null{
           7            response.sendError
           8                (HttpServletResponse.SC_BAD_REQUEST,
           9                 sm.getString("standardEngine.noHost"
          10                              request.getServerName()));
          11            return;
          12        }

          13
          14        // Ask this Host to process this request
          15        host.getPipeline().getFirst().invoke(request, response);
          16
          17    }

          18
           

          可以看出在處理到StandardEngine這個(gè)Pipeline的最后一個(gè)Valve時(shí),會(huì)根據(jù)當(dāng)前request所指定的Host,將當(dāng)前的requestresponse傳遞給該Host這個(gè)Pipeline的第一個(gè)Valve進(jìn)行處理。

          我想Tomcat中的Engine、HostContextWrapper處理request生成response的過(guò)程大概是這樣的:

          Engine在收到request后在其Pipeline中的每一個(gè)Valve對(duì)request進(jìn)行處理,也可能會(huì)生成response的某些部分,在最后一個(gè)Valve中將requestresponse傳給下一級(jí)ContainerHost的第一個(gè)ValveHost重復(fù)同樣過(guò)程,繼續(xù)傳遞給Context,Context再傳遞給Wrapper。由于Wrapper代表的是Servlet對(duì)象,因此在Wrapper處所有的處理都結(jié)束了,response對(duì)象生成完畢。當(dāng)然了,如果在某一級(jí)中無(wú)法找到request要求的下一級(jí)對(duì)象,則整個(gè)處理過(guò)程也會(huì)立即結(jié)束。

          posted @ 2007-05-30 22:58 Job Hu 閱讀(360) | 評(píng)論 (1)編輯 收藏

          2007年5月28日

          Tomcat筆記(二)

          ContainerBase對(duì)Pipeline接口的實(shí)現(xiàn)完全依賴于其內(nèi)部的一個(gè)Pipeline類型的成員pipeline(實(shí)現(xiàn)類為StandardPipeline)。
             
          Tomcatdoc中這樣介紹Pipeline接口:該接口的invoke()方法被調(diào)用時(shí),將會(huì)引發(fā)一系列Value對(duì)象的序列調(diào)用。要求一個(gè)Pipeline中的存在一個(gè)Value對(duì)象(多為最后一個(gè)Value對(duì)象)完成對(duì)request的處理,并生成相應(yīng)的response,而不能試圖將Request繼續(xù)傳遞給其它Value對(duì)象(這個(gè)Value對(duì)象被稱為Basic)。通常,每個(gè)Container對(duì)象都持有一個(gè)Pipline類型(實(shí)際上為StandardPipeline)的成員。在Pipelinedoc中,方法getBasic,getFirst兩個(gè)方法的Method Summary完全一樣,Apache的牛人們也不能免俗啊。

          StandardPipeline除實(shí)現(xiàn)Pipeline接口外,也實(shí)現(xiàn)了Lifecycle接口。這個(gè)類的startstop方法,首先檢查是否已經(jīng)被startstop,如果是則會(huì)拋出一個(gè)LifecycleException的異常,否則便fire和生命期改變的相關(guān)事件,并調(diào)用其內(nèi)部valve對(duì)象(如果該valve對(duì)象也實(shí)現(xiàn)了Lifecycle接口)的startstop方法。addValve方法用來(lái)向StandardPipeline中加入Valve對(duì)象,新加入的Value對(duì)象被放在一個(gè)叫做Basic的特殊Valve(就是一個(gè)Pipeline的最后一個(gè)Valve)的前面,如果在添加Valve的時(shí)候該StandardPipeline已經(jīng)處于start狀態(tài),則會(huì)進(jìn)行一些注冊(cè)(調(diào)用apache commons庫(kù)的一個(gè)類,完全沒(méi)有看懂這個(gè)地方是什么作用>_<

          posted @ 2007-05-28 07:39 Job Hu 閱讀(307) | 評(píng)論 (0)編輯 收藏

          2007年5月15日

          一個(gè)簡(jiǎn)化的java線程池示例

          //以前寫在blogger上的一篇老文了
          曾經(jīng)很好奇線程池是怎么實(shí)現(xiàn)的,.net中有現(xiàn)成的線程池可以使用,但是java中沒(méi)有。還有就是Servlet的service方法是怎么樣為每一個(gè) Request在不同的線程中獨(dú)立服務(wù)的,由于Servlet接口沒(méi)有繼承自Runnable接口,因此無(wú)法直接由一個(gè)Servlet對(duì)象生成多個(gè)線程。后來(lái)在網(wǎng)上找到了一個(gè)java版本的線程池的例子(http://www.informit.com/articles/article.asp?p= 30483&seqNum=1&rl=1)在該例子的基礎(chǔ)上簡(jiǎn)化得到了下面這個(gè)版本的java線程池,記錄在這里。
          *******************
          ThreadPool.java
          *******************

          package threadPool;

          import java.util.ArrayList;
          import java.util.Collection;

          public class ThreadPool
          {
              Thread[] threadArray;
              Collection
          <Runnable> jobs = new ArrayList<Runnable>();
           
              
          public ThreadPool(int threadNum)
              
          {
                  threadArray 
          = new WorkerThread[threadNum];
                  
          for (Thread thread : threadArray)
                  
          {
                      thread 
          = new WorkerThread();
                      thread.start();
                  }

              }

           
              
          public synchronized void addJob(Runnable job)
              
          {
                  jobs.add(job);
                  notify();
              }

           
              
          private synchronized Runnable getJob()
              
          {
                  
          while(jobs.isEmpty())
                  
          {
                      
          try
                      
          {
                          wait();
                      }
           catch (InterruptedException e)
                      
          {
                          e.printStackTrace();
                      }

                  }

                  Runnable job 
          =  jobs.iterator().next();
                  jobs.remove(job);
                  
          return job;
              }

              
              
          private class WorkerThread extends Thread
              
          {
                  
          public void run()
                  
          {
                      Runnable job 
          = null;
                      
          while(job == null)
                      
          {
                          job 
          = getJob();
                          
          if(job != null)
                          
          {
                              job.run();
                          }

                          job 
          = null;
                      }

                 }

              }

          }


           

          *******************
          ThreadPoolTest.java
          *******************

          package threadPool;

          public class ThreadTest
          {
              
          private static class PrintClass implements Runnable
              
          {
                  
          private int threadNo;
            
                  
          public PrintClass(int threadNo)
                  
          {
                      
          this.threadNo = threadNo;
                  }

                  
                  
          public void run()
                  
          {
                      
          for(int i = 0; i < 10; i++)
                      
          {
                          
          synchronized (System.out)
                          
          {
                              System.out.println(
          "Thread "+threadNo+""+i);
                          }

                          
          try
                          
          {
                              Thread.sleep(
          1000);
                          }
           catch (InterruptedException e)
                          
          {
                              e.printStackTrace();
                          }

                      }

                  }
           
              }

           
              
          public static void main(String[] args)
              
          {
                  ThreadPool tp 
          = new ThreadPool(3);
                  
          for(int i=0; i <10; i++)
                  
          {
                      tp.addJob(
          new PrintClass(i));
                  }

                  
          synchronized (System.out)
                  
          {
                      System.out.println(
          "Job adding finished");
                  }

              }

          }

          posted @ 2007-05-15 12:53 Job Hu 閱讀(906) | 評(píng)論 (3)編輯 收藏

          2007年4月25日

          Tomcat筆記(一)

          包org.apache.catalina主要由接口組成。我們可以把這些接口分為幾個(gè)大類。

          第一類接口主要是對(duì)web application及其各個(gè)組成部分的抽象。這些接口以Container為父接口,分別為Context,Engine,Host,Wrapper。

          Engine代表的是整個(gè)Catalina Servlet引擎。

          Host代表的是Catalina Servlet引擎中的一個(gè)虛擬主機(jī)。

          Context

          Wrapper代表的是某一個(gè)具體的servlet

          下面我從Container的抽象實(shí)現(xiàn)ContainerBase來(lái)切入Container,Context,Engine,Host,Wrapper的實(shí)現(xiàn)。

          由于Container接口是web application中各部分的抽象的公共部分,因此其實(shí)現(xiàn)類ContrainerBase是一個(gè)抽象類。對(duì)于Container接口的各個(gè)子接口的實(shí)現(xiàn)類,則通過(guò)繼承ContainerBase來(lái)實(shí)現(xiàn)接口Container接口。例如Engine接口繼承Container接口,Engine的實(shí)現(xiàn)類StandardEnginer繼承ContainerBase類。

          ContainerBase實(shí)現(xiàn)得接口有Container,Lifecycle,MBeanRegistration, Pipeline,Serializable。其中Lifecycle,Pipeline和Container屬于同一個(gè)包。

          Lifecycle接口定義了一個(gè)具有生命期屬性的組件所必須提供的方法:start(啟動(dòng)一個(gè)組件),stop(停止一個(gè)組件);除此之外該接口還定義了與具有生命期屬性的組件的Listener相關(guān)的3個(gè)方法,用來(lái)添加、刪除、查找對(duì)該組件的生命期階段變化感興趣的Listener。

          Pipeline在Tomcat中是一個(gè)或者多個(gè)Value的組合,Value用來(lái)對(duì)Request進(jìn)行處理,生成Response或者將Request和Response傳給下一個(gè)Value進(jìn)行處理。Tomcat并沒(méi)有象通常一樣將Pipeline和Value作為同一個(gè)接口,即使用Composite模式,而是Pipeline和Value分別作為集合和元素,Pipeline只能加入Value而不能加入Pipeline,Value則不能包含任何子Value。

          ContainerBase對(duì)lifecycle接口的實(shí)現(xiàn)分為兩類,addLifecycleListener、findLifecycleListener、removeLifecycleListener都是通過(guò)調(diào)用ContainerBase的一個(gè)LifecycleSupport成員實(shí)現(xiàn);start和stop方法則為ContainerBase自己實(shí)現(xiàn)。我一開始以為L(zhǎng)ifecycleSupport也實(shí)現(xiàn)了lifecycle接口,但實(shí)際上并不是這樣,原因是start和stop方法與具體的組件密切相關(guān)。此外LifecycleSupport中還包括一個(gè)名為fireLifecycleEvent的方法,該方法遍歷所有的LifeCycleListener,并觸發(fā)Lifecycle事件??傮w上看LifecycleSupport實(shí)現(xiàn)了所有實(shí)現(xiàn)Lifecycle接口的組件的公共部分,維護(hù)一個(gè)LifecycleListener的數(shù)組,提供了添加、修改、獲取LifecycleListener和觸發(fā)各個(gè)Listener的方法。一個(gè)有趣的情況是,LifecycleSupport是一個(gè)final類,無(wú)法被繼承,利用java的語(yǔ)言性質(zhì)強(qiáng)制執(zhí)行了面向?qū)ο笾薪M合優(yōu)于繼承的思想。

          posted @ 2007-04-25 22:21 Job Hu 閱讀(353) | 評(píng)論 (1)編輯 收藏

          主站蜘蛛池模板: 吴桥县| 宝山区| 大埔县| 遵义县| 栾川县| 新绛县| 丽水市| 合肥市| 隆化县| 静乐县| 邵东县| 壶关县| 彝良县| 乌拉特前旗| 无锡市| 开封市| 三原县| 绥棱县| 上杭县| 苍山县| 桂阳县| 临武县| 章丘市| 新田县| 武汉市| 兖州市| 通山县| 新建县| 莆田市| 汽车| 高州市| 五大连池市| 资溪县| 东乌珠穆沁旗| 阿城市| 宝坻区| 江门市| 石景山区| 富民县| 桦南县| 陆良县|