閱讀源代碼的一點小技巧

  1. 在跟蹤源代碼的時候,要追着源代碼打斷點,否則不知道每一步執行到那裏。

 有時候有的方法被多個地方調用,這時沒法確認走哪一個方法,改怎麼辦呢?java

 能夠提早經過打調用棧的方式把整個流程弄通,而後在關鍵點打斷點,這樣效率更高。apache

2.打印方法的調用鏈(堆棧)兩種方式:
閱讀源代碼的一點小技巧數組

2.1 正常方式示例:session

@Override
  public SimWeight computeWeight(float boost, CollectionStatistics collectionStats, TermStatistics... termStats) {

    /* Exception e=new Exception();
    e.printStackTrace();*/

   java.util.Map<Thread, StackTraceElement[]> ts = Thread.getAllStackTraces();
    StackTraceElement[] ste = ts.get(Thread.currentThread());
    for (StackTraceElement s : ste) { 
      System.out.println("###################################"+s.getClassName()+"$"+s.getMethodName());
    } 
    //業務邏輯
    return new DavidStats(field,K_length,KE_length, termStats) ;
  }

打印結果app

###################################java.lang.Thread$dumpThreads
###################################java.lang.Thread$getAllStackTraces
###################################org.apache.lucene.search.similarities.DavidSimilarity$computeWeight
###################################org.apache.lucene.search.SynonymQuery$SynonymWeight$<init>
###################################org.apache.lucene.search.SynonymQuery$createWeight
###################################org.apache.lucene.search.IndexSearcher$createWeight
###################################org.apache.lucene.search.IndexSearcher$createNormalizedWeight
###################################org.apache.lucene.search.IndexSearcher$search
###################################org.apache.solr.search.SolrIndexSearcher$buildAndRunCollectorChain
###################################org.apache.solr.search.SolrIndexSearcher$getDocListNC
###################################org.apache.solr.search.SolrIndexSearcher$getDocListC
###################################org.apache.solr.search.SolrIndexSearcher$search
###################################org.apache.solr.handler.component.QueryComponent$doProcessUngroupedSearch
###################################org.apache.solr.handler.component.QueryComponent$process
###################################org.apache.solr.handler.component.SearchHandler$handleRequestBody
###################################org.apache.solr.handler.RequestHandlerBase$handleRequest
###################################org.apache.solr.core.SolrCore$execute
###################################org.apache.solr.servlet.HttpSolrCall$execute
###################################org.apache.solr.servlet.HttpSolrCall$call
###################################org.apache.solr.servlet.SolrDispatchFilter$doFilter
###################################org.apache.solr.servlet.SolrDispatchFilter$doFilter
###################################org.eclipse.jetty.servlet.ServletHandler$CachedChain$doFilter
###################################org.eclipse.jetty.servlet.ServletHandler$doHandle
###################################org.eclipse.jetty.server.handler.ScopedHandler$handle
###################################org.eclipse.jetty.security.SecurityHandler$handle
###################################org.eclipse.jetty.server.session.SessionHandler$doHandle
###################################org.eclipse.jetty.server.handler.ContextHandler$doHandle
###################################org.eclipse.jetty.servlet.ServletHandler$doScope
###################################org.eclipse.jetty.server.session.SessionHandler$doScope
###################################org.eclipse.jetty.server.handler.ContextHandler$doScope
###################################org.eclipse.jetty.server.handler.ScopedHandler$handle
###################################org.eclipse.jetty.server.handler.HandlerWrapper$handle
###################################org.eclipse.jetty.server.Server$handle
###################################org.eclipse.jetty.server.HttpChannel$handle
###################################org.eclipse.jetty.server.HttpConnection$onFillable
###################################org.eclipse.jetty.io.AbstractConnection$ReadCallback$succeeded
###################################org.eclipse.jetty.io.FillInterest$fillable
###################################org.eclipse.jetty.io.SelectChannelEndPoint$2$run
###################################org.eclipse.jetty.util.thread.strategy.ExecuteProduceConsume$executeProduceConsume
###################################org.eclipse.jetty.util.thread.strategy.ExecuteProduceConsume$produceConsume
###################################org.eclipse.jetty.util.thread.strategy.ExecuteProduceConsume$run
###################################org.eclipse.jetty.util.thread.QueuedThreadPool$runJob
###################################org.eclipse.jetty.util.thread.QueuedThreadPool$2$run
###################################java.lang.Thread$run

2.2 異常方式eclipse

Exception e=new Exception();
e.printStackTrace();

舉例:ide

@Override
  public SimWeight computeWeight(float boost, CollectionStatistics collectionStats, TermStatistics... termStats) {

    Exception e=new Exception();
    e.printStackTrace();

/*    java.util.Map<Thread, StackTraceElement[]> ts = Thread.getAllStackTraces();
    StackTraceElement[] ste = ts.get(Thread.currentThread());
    for (StackTraceElement s : ste) { 
      System.out.println("###################################"+s.getClassName()+"$"+s.getMethodName());
    } */
    //業務邏輯
    return new DavidStats(field,K_length,KE_length, termStats) ;
  }

打印狀況ui

java.lang.Exception
  at org.apache.lucene.search.similarities.DavidSimilarity.computeWeight(DavidSimilarity.java:91)
  at org.apache.lucene.search.TermQuery$TermWeight.<init>(TermQuery.java:75)
  at org.apache.lucene.search.TermQuery.createWeight(TermQuery.java:205)
  at org.apache.lucene.search.IndexSearcher.createWeight(IndexSearcher.java:738)
  at org.apache.lucene.search.BooleanWeight.<init>(BooleanWeight.java:56)
  at org.apache.lucene.search.BooleanQuery.createWeight(BooleanQuery.java:208)
  at org.apache.lucene.search.IndexSearcher.createWeight(IndexSearcher.java:738)
  at org.apache.lucene.search.IndexSearcher.createNormalizedWeight(IndexSearcher.java:727)
  at org.apache.lucene.search.IndexSearcher.search(IndexSearcher.java:462)
  at org.apache.solr.search.SolrIndexSearcher.buildAndRunCollectorChain(SolrIndexSearcher.java:215)
  at org.apache.solr.search.SolrIndexSearcher.getDocListNC(SolrIndexSearcher.java:1602)
  at org.apache.solr.search.SolrIndexSearcher.getDocListC(SolrIndexSearcher.java:1417)
  at org.apache.solr.search.SolrIndexSearcher.search(SolrIndexSearcher.java:584)
  at org.apache.solr.handler.component.QueryComponent.doProcessUngroupedSearch(QueryComponent.java:1435)
  at org.apache.solr.handler.component.QueryComponent.process(QueryComponent.java:375)
  at org.apache.solr.handler.component.SearchHandler.handleRequestBody(SearchHandler.java:295)
  at org.apache.solr.handler.RequestHandlerBase.handleRequest(RequestHandlerBase.java:177)
  at org.apache.solr.core.SolrCore.execute(SolrCore.java:2503)
  at org.apache.solr.core.QuerySenderListener.newSearcher(QuerySenderListener.java:74)
  at org.apache.solr.core.SolrCore.lambda$17(SolrCore.java:2275)
  at java.util.concurrent.FutureTask.run(FutureTask.java:266)
  at org.apache.solr.common.util.ExecutorUtil$MDCAwareThreadPoolExecutor.lambda$0(ExecutorUtil.java:188)
  at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1142)
  at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:617)
  at java.lang.Thread.run(Thread.java:745)

2.3 經過在代碼故意形成報錯致使打印調用鏈spa

好比數組越界,被除數爲0等方式rest

String str="123";
System.out.println(str.toCharArray()[10]);

3.經過時序圖將調用鏈路畫出來(示例,非嚴格按照上面的邏輯)

閱讀源代碼的一點小技巧

總結:

閱讀源碼整體上是一個長期的過程,每次閱讀想要有所收穫,就須要留下一些東西,好比有人寫博客,有人記日誌等等,若是不作任何準備,盲目的去閱讀代碼,每每今天讀明天忘,浪費了大量的時間反而沒有相應的收穫。

經過梳理調用鏈的方式能夠加深對源碼的理解,經過流程圖的梳理,讓下次源碼閱讀更有效率,有圖有真相。

相關文章
相關標籤/搜索