黑馬程式設計師面試題一(交通燈管理系統)

gypmypm發表於2013-12-05

--------- android培訓java培訓、期待與您交流!---------

    城市交通問題是本世紀以來,工業已開發國家一直為之困擾的問題。進入80年代以來,我國城市的經濟貿易和社會活動日益繁忙,城市交通發生了前所未有的迅速增長,傳統的道路交通設施已經不能適應現代社會的需要。當前,我國城市特別是大城市的交通問題極其嚴重,如果不能得到有效解決和根本治理,必將對我國經濟的持續、快速、健康發展構成嚴重威脅。
一.專案需求:

              
               模擬實現十字路口的交通燈管理系統邏輯:

      非同步隨機生成按照各個路線行駛的車輛。

      例如:

      由南向而來去往北向的車輛 ---- 直行車輛

      由西向而來去往南向的車輛 ---- 右轉車輛

      由東向而來去往南向的車輛 ---- 左轉車輛

      。。。

     訊號燈忽略黃燈,只考慮紅燈和綠燈。

     應考慮左轉車輛控制訊號燈,右轉車輛不受訊號燈控制。

     具體訊號燈控制邏輯與現實生活中普通交通燈控制邏輯相同,不考慮特殊情況下的控制邏輯。

     注:南北向車輛與東西向車輛交替放行,同方向等待車輛應先放行直行車輛而後放行左轉車輛。

     每輛車通過路口時間為1秒(提示:可通過執行緒Sleep的方式模擬)。

     隨機生成車輛時間間隔以及紅綠燈交換時間間隔自定,可以設定。



二.開發前分析:

  1. 一個方向到其他方向有3條線路,4個方向共12條線路,為了統一程式設計模型,

     可以假設每條路都有一個紅綠燈對其進行控制, 右轉向的4個路口的控制燈可以假設為常亮綠燈狀態。

  2.為了思路清晰,先思考一個方向的路線問題。

  3.初步設想所擁有的物件:紅綠燈,紅綠燈的控制系統,(汽車),路線。

  4.汽車要看所線上路上的紅綠燈,並且判斷前方是否有車。路中儲存著汽車的集合,顯然路上就應該有增加車輛     和減少車輛的方法了。

   我們要捕捉路上減少一輛車的過程,所以,這個車並不需要單獨設計成為一個物件。用一個字串表示就行了。



三.開發過程
     

  類的編寫:

  Road類的編寫:

  每個Road物件都有一個name成員變數來代表方向,有一個vehicles成員變數來代表方向上的車輛集合。

  在Road物件的構造方法中啟動一個執行緒每隔一個隨機的時間向vehicles集合中增加一輛車(用一個“路線名_id”形   式的字串進行表示)。

  在Road物件的構造方法中啟動一個定時器,每隔一秒檢查該方向上的燈是否為綠,是則列印車輛集合和將集合     中的第一輛車移除掉。

  程式碼如下:

[java] view plaincopy
  1. <span style="font-size:18px;">     
  2. public class Road {  
  3.   
  4.  private List<String> vechicles = new ArrayList<String>();  
  5.   
  6.  private String name = null;  
  7.   
  8.  public Road(String name) {  
  9.   this.name = name;  
  10.   
  11.   // 建立車輛  
  12.   
  13.   ExecutorService pool = Executors.newSingleThreadExecutor();   //執行緒池  
  14.   
  15.   pool.execute(new Runnable() {  
  16.   
  17.    @Override  
  18.    public void run() {  
  19.     // TODO Auto-generated method stub  
  20.     for (int i = 1; i < 1000; i++) {  
  21.      try {  
  22.       // 隨機獲取1-10秒的數,讓車輛不定時的往裡增加  
  23.       Thread.sleep((new Random().nextInt(10) + 1) * 1000);  
  24.      } catch (InterruptedException e) {  
  25.       // TODO Auto-generated catch block  
  26.       e.printStackTrace();  
  27.      }  
  28.      vechicles.add(Road.this.name + "_" + i);  
  29.     }  
  30.    }  
  31.   });  
  32.   
  33.   //建立一個執行緒,按時間安排執行任務的功能  
  34.   
  35.   
  36.   ScheduledExecutorService timer = Executors.newScheduledThreadPool(1);  
  37.   timer.scheduleAtFixedRate(new Runnable() {  
  38.    @Override  
  39.    public void run() {  
  40.     // TODO Auto-generated method stub  
  41.     if (vechicles.size() > 0// 判斷現在是否有車輛  
  42.     {  
  43.      boolean lighted = Lamp.valueOf(Road.this.name).isLight();  
  44.      //System.out.println(Road.this.name+">>>>>>>>>>>>>"+lighted);  
  45.      if (lighted) {  
  46.       System.out  
  47.         .println(vechicles.remove(0) + " ...is traverse");  
  48.      }  
  49.     }  
  50.   
  51.   
  52.    }  
  53.   }, 11, TimeUnit.SECONDS);  
  54.  }  
  55. }</span>  

 

  Lamp燈的編寫:

  Lamp類來表示一個交通燈,12個,使用列舉。

   系統中有12個方向上的燈,在程式的其他地方要根據燈的名稱就可以獲得對應

   的燈的例項物件,綜合這些因素,將Lamp類用java5中的列舉形式定義更為簡單。

   每個Lamp物件中的亮黑狀態用lighted變數表示,選用S2N、S2W、E2W、E2N這四

   個方向上的Lamp物件依次輪詢變亮,Lamp物件中還要有一個oppositeLampName變

   量來表示它們相反方向的燈,再用一個nextLampName變數來表示此燈變亮後的下

   一個變亮的燈。這三個變數用構造方法的形式進行賦值,因為列舉元素必須在定

   義之後引用,所以無法再構造方法中彼此相互引用,所以,相反方向和下一個方

   向的燈用字串形式表示。 

   增加讓Lamp變亮和變黑的方法:light和blackOut,對於S2N、S2W、E2W、E2N這

   四個方向上的Lamp物件,這兩個方法內部要讓相反方向的燈隨之變亮和變黑,

   blackOut方法還要讓下一個燈變亮。

   除了S2N、S2W、E2W、E2N這四個方向上的Lamp物件之外,其他方向上的Lamp物件

   的nextLampName和oppositeLampName屬性設定為null即可,並且S2N、S2W、E2W、

   E2N這四個方向上的Lamp物件的nextLampName和oppositeLampName屬性必須設定為

   null,以便防止light和blackOut進入死迴圈。

   

 程式碼如下:

[java] view plaincopy
  1. <span style="font-size:18px;">     
  2. public class Road {  
  3.   
  4.  private List<String> vechicles = new ArrayList<String>();  
  5.   
  6.  private String name = null;  
  7.   
  8.  public Road(String name) {  
  9.   this.name = name;  
  10.   
  11.   // 建立車輛  
  12.   
  13.   ExecutorService pool = Executors.newSingleThreadExecutor();   //執行緒池  
  14.   
  15.   pool.execute(new Runnable() {  
  16.   
  17.    @Override  
  18.    public void run() {  
  19.     // TODO Auto-generated method stub  
  20.     for (int i = 1; i < 1000; i++) {  
  21.      try {  
  22.       // 隨機獲取1-10秒的數,讓車輛不定時的往裡增加  
  23.       Thread.sleep((new Random().nextInt(10) + 1) * 1000);  
  24.      } catch (InterruptedException e) {  
  25.       // TODO Auto-generated catch block  
  26.       e.printStackTrace();  
  27.      }  
  28.      vechicles.add(Road.this.name + "_" + i);  
  29.     }  
  30.    }  
  31.   });  
  32.   
  33.   //建立一個執行緒,按時間安排執行任務的功能  
  34.   
  35.   
  36.   ScheduledExecutorService timer = Executors.newScheduledThreadPool(1);  
  37.   timer.scheduleAtFixedRate(new Runnable() {  
  38.    @Override  
  39.    public void run() {  
  40.     // TODO Auto-generated method stub  
  41.     if (vechicles.size() > 0// 判斷現在是否有車輛  
  42.     {  
  43.      boolean lighted = Lamp.valueOf(Road.this.name).isLight();  
  44.      //System.out.println(Road.this.name+">>>>>>>>>>>>>"+lighted);  
  45.      if (lighted) {  
  46.       System.out  
  47.         .println(vechicles.remove(0) + " ...is traverse");  
  48.      }  
  49.     }  
  50.   
  51.   
  52.    }  
  53.   }, 11, TimeUnit.SECONDS);  
  54.  }  
  55. }</span>  


 LampController類的編寫:

 整個系統中只能有一套交通燈控制系統,所以,LampController類最好是設計成單例。

 LampController構造方法中要設定第一個為綠的燈。

 LampController物件的start方法中將當前燈變綠,然後啟動一個定時器,每隔10秒將當前燈變紅和將下一個燈變  綠。

  

[java] view plaincopy
  1. <span style="font-size:18px;">  程式碼如下:  
  2.  public class LampController {  
  3.   
  4.   
  5.  private Lamp controlLamp;  
  6.  public LampController() {  
  7.     
  8.   controlLamp = Lamp.S2N;  //先初始化一條線路上的燈  
  9.   controlLamp.light();  
  10.   // TODO Auto-generated constructor stub  
  11.   ScheduledExecutorService timer = Executors.newScheduledThreadPool(1);  
  12.     
  13.   timer.scheduleWithFixedDelay(  
  14.     new Runnable() {  
  15.        
  16.      @Override  
  17.      public void run() {  
  18.       // TODO Auto-generated method stub  
  19.       controlLamp = controlLamp.blackOut();  
  20.      }  
  21.     },    
  22.     10,   
  23.     10,   
  24.     TimeUnit.SECONDS);  
  25.     
  26.  }  
  27. }  
  28.   
  29.   
  30.   MainClass類的編寫  
  31.   用for迴圈建立出代表12條路線的物件。  
  32.   接著再獲得LampController物件並呼叫其start方法。  
  33.    
  34.   程式碼如下:  
  35.    
  36.  public class MainClass {  
  37.   
  38.   
  39.  /** 
  40.   * @param args 
  41.   */  
  42.  public static void main(String[] args) {  
  43.   // TODO Auto-generated method stub  
  44.   String[] directions = new String[] { "S2N""S2W""E2W""E2S""N2S",  
  45.     "N2E""W2E""W2N""S2E""E2N""N2W""W2S" };  
  46.   for (int i  = 0; i < directions.length; i++) {  
  47.    new Road(directions[i]);  
  48.   }  
  49.   new LampController();  
  50. }  
  51. }</span>  

相關文章