黑马程序员_面试题(1) 交通灯管理系统

------- android培训 java培训 、期待与您交流! ----------

一:系统实现

   模拟实现十字路口的交通灯管理系统逻辑,具体需求如下:
1.异步随机生成按照各个路线行驶的车辆。
例如:
       由南向而来去往北向的车辆 ---- 直行车辆
       由西向而来去往南向的车辆 ---- 右转车辆
       由东向而来去往南向的车辆 ---- 左转车辆
       。。。
2.信号灯忽略黄灯,只考虑红灯和绿灯
3.应考虑左转车辆控制信号灯,右转车辆不受信号灯控制
4. 具体信号灯控制逻辑与现实生活中普通交通灯控制逻辑相同,不考虑特殊情况下的控制逻辑。
注:南北向车辆与东西向车辆交替放行,同方向等待车辆应先放行直行车辆而后放行左转车辆
5.每辆车通过路口时间为1秒(提示:可通过线程Sleep的方式模拟)
6.随机生成车辆时间间隔以及红绿灯交换时间间隔自定,可以设置。
7.不要求实现GUI,只考虑系统逻辑实现,可通过Log方式展现程序运行结果
-------------------------------------------------------------------------------------------------------------------------

二.系统分析与设计

 1.经分析,设计的类,路线,信号灯,交通灯控制;推理出三者之间关系,共12路线且每条路线不同的信号灯,即红灯时此路线车辆在增加,变为绿灯时此路线车辆在减少。
 2.设计思路以及模型
    十字路口共12条路线,分别是南向北 、北向南、南向西、北向东、东向西、西向东、东向南、西向北,加上4个右拐弯南向东、东向北、北向西、西向南,即12个信号灯,据分析,其四条右拐路线的交通灯处于绿灯状态,剩余8条路线,根据路线方向对应相反分为一组,共分为4组,且每组路线上的灯状态一致,每组选一条路线的灯在某时刻轮流切换下一组灯的状态
    路线的模型设计:名字描述,车辆缓冲池,通过异步完成车辆的增加,根据此路线灯状态为绿灯则移除
    交通灯的设计模型设计: JDK1.5 新特性 枚举 完成此类设计,记录每个灯的状态,每组路线的灯状态一致,获取下一组路线其一个灯的状态,某时刻轮流切换灯的状态
   交通灯控制模型设计:选取某条路线为当前灯,且为绿灯状态,定时10秒处理事务,轮流切换下一组路线其一个灯的状态
 3.路线图分析
        
     
 4.涉及知识:oop 设计分析,交通灯逻辑分析,枚举 新特性运用,并发库线程池处理线程数量,单线程调度延迟或某定期执行事务
             思考 灯顺序实现过程:
             开始从 (NORTH2SOUTH,SOUTH2NORTH),这组灯转到 
             左拐路线的灯 (NORTH2EAST,SOUTH2WEST),  
             南北路线车辆全部走完了
             东西走向 转到 灯(EAST2WEST,WEST2EAST),
             这组红灯就到转弯灯(EAST2SOUTH,WEST2NORTH)
             走完右转路线的灯(SOUTH2EAST,EAST2NORTH,NORHTN2WEST,WEST2SOUTH)
-------------------------------------------------------------------------------------------------------------------------

三:代码实现

      路线Road类
import java.util.ArrayList;
import java.util.List;
import java.util.Random;
import java.util.concurrent.Executors;
import java.util.concurrent.TimeUnit;

public class Road {
	
	/* 路线上车辆存放的临时缓冲*/
  private List<String> vechicles = new ArrayList<String>();
  
   /* 车辆名称描述*/
  private String name;
  
  /*某路线存放车辆最大数*/
  private int vechiclesMaxNumber;
  
  public Road(String name ,int vechiclesMaxNumber){
	  this.name = name;
	  this.vechiclesMaxNumber = vechiclesMaxNumber;
	  this.generationVechicles();
	  this.moveVechicles();
  }
  
  /**
   * 模拟某路线上不断有车辆增加
   */
  public void generationVechicles(){
	  Executors.newSingleThreadExecutor().execute(new Runnable(){

		@Override
		public void run() {
			  for(int i=1;i<=vechiclesMaxNumber;i++){
				  try{
					  /* 随机控制产生车辆的时间间隔*/
					  Thread.sleep((new Random().nextInt(10)+1)*1000);
					  
					  /* 将车辆添加到集合 */
					  vechicles.add(name+"第"+"["+i+"]"+"辆车");
				  }catch(InterruptedException e){
					 e.printStackTrace();
				  }
			  }
	      }		  
	  });	
   }
  
 /*
  * 每个一秒处理事务,某路线对应的灯是否为绿灯,若是则车辆放行,路线上车辆减少一个
  */
  public void moveVechicles(){
	  Executors.newScheduledThreadPool(1).scheduleAtFixedRate(
			  new Runnable(){

				@Override
				public void run() {
				if(vechicles.size()>0){
					
					/* 判断当前灯状态,若为绿灯,则当前路线的车辆放行*/
					if(Lamp.valueOf(name).isLightState())
	                   System.out.println(vechicles.remove(0)+": 已从 "+"["+Lamp.valueOf(name).getRoadName()+"]"+"驶过路口 ");	
					}
				}			  
			  }, 
			  1,
			  1, 
			  TimeUnit.SECONDS);
  }  
}

     交通灯 Lamp 类  
    
package com.isoftstone.interview.traffic;

/**
 * 
 * 每个枚举元素是一个路线方向的灯
 * 每个路线对应的相反路线,此两个合并成一组,一组线路的灯状态一致,即控制每组灯的一个灯
 * @author jonn
 * @version v1.0
 *
 */
public enum Lamp {
	
	/* 直线 路线的交通灯
	 * 线路相反方向的灯忽略不计
	 * 第一个参数 当前路线名称描述,第二个参数 指向一组灯中对应相反的路线灯,第三个参数 下一组的路线灯,
	 * 当前路线灯的状态,true(绿灯),false(红灯)
	 * */
   SOUTH2NORTH("南北方向直线路线","NORTH2SOUTH","SOUTH2WEST",false),
   NORTH2SOUTH("北南方向直线路线",null,null,false),  
   EAST2WEST("东西方向直线路线","WEST2EAST","EAST2SOUTH",false),
   WEST2EAST("西东方向直线路线",null,null,false),
  
    /* 左转路线的交通灯
     * 线路相反方向的灯忽略不计
     * */
   SOUTH2WEST("南西方向左转路线","NORTH2EAST","EAST2WEST",false),
   NORTH2EAST("北东方向左转路线",null,null,false),
   EAST2SOUTH("东南方向左转路线","WEST2NORTH","SOUTH2NORTH",false),
   WEST2NORTH("西北方向左转路线",null,null,false),
   
   /* 右转路线的交通灯
    * 右拐弯的灯无红绿灯控制,总是绿灯状态
    * */
   SOUTH2EAST("南东方向右转路线",null,null,true),
   EAST2NORTH("东北方向右转路线",null,null,true),
   NORTH2WEST("北西方向右转路线",null,null,true),
   WEST2SOUTH("西南方向右转路线",null,null,true);
   
    /* 当前路线名称描述*/
   private String roadName;
   
   /* 当前路线交通灯状态, 亮(绿灯),暗(红灯)*/
   private boolean lightState;
   
   /* 当前路线对应相反的路线的交通灯*/
   private String oppositeLight;
   
   /* 当前路线指向下一个路线的交通灯*/
   private String nextLight;
   
   private Lamp(String roadName,String oppositeLight,String nextLight,boolean lightState){
	   this.roadName = roadName;
	   this.oppositeLight= oppositeLight;
	   this.nextLight = nextLight;
	   this.lightState = lightState;
   }
   
   /**
    * 获取当前灯的状态
    * @return 
    */
   public boolean isLightState(){
	   return this.lightState;
   }
   
   /**
    * 当前交通灯为绿,则对应方向的交通灯为绿
    */
   public void alight(){
	   this.lightState = true;
	   if(oppositeLight!=null){
	      Lamp.valueOf(oppositeLight).alight();
	   }
	  
   }
   /**
    * 当前交通灯为红,则对应方向的交通灯为红
    * @return next (下一个变为绿的灯 )
    */
   public Lamp blackOut(){
	   this.lightState = false;
	   if(oppositeLight!=null){
		      Lamp.valueOf(oppositeLight).blackOut();
		   }
	   Lamp next = null; 
	   /* 下一组灯 不为null,则变为绿灯,且返回当前灯*/
	   if(nextLight!=null){
		   next = Lamp.valueOf(nextLight);
		   next.alight();		   
	   }
	   return next;
   }
   
    /**
     * 返回当前灯的路线描述
     * @return 
     */
   public String getRoadName(){
	   return this.roadName;
   }
}


交通控制类 LampControllel
package com.isoftstone.interview.traffic;

/**
 * @author jonn
 * @version v1.0
 */
import java.util.concurrent.Executors;
import java.util.concurrent.TimeUnit;

public class LampController {
	/* 某条路线当前灯*/
   private Lamp currentLight;
   public LampController(Lamp currentLight){
	this.currentLight = currentLight;
	/*当前灯为绿灯*/
	currentLight.alight();
	this.shceduledLight();
   }
   
   /***
    * 每隔10秒处理事务,轮流改变所有路线的灯状态,将当前绿灯变为红灯,并将下一个路线方向的灯变为绿灯
    */
   public void shceduledLight(){
	   Executors.newScheduledThreadPool(1).scheduleAtFixedRate(
			   new Runnable(){

				@Override
				public void run() {
				currentLight = currentLight.blackOut();					
				}				   
			   }, 
			   10, 
			   10, 
			   TimeUnit.SECONDS);
   }
}

 客户端 MainTraffic 类
package com.isoftstone.interview.traffic;

/**
 * @author jonn
 * @version v1.0
 */
public class MainTraffic {
	
	/*每条路线固定的车辆数量*/
	private static int vechiclesNumber = 1000;
	
	/*12条路线的灯*/
	private static String[] roads = {
		"SOUTH2NORTH","SOUTH2WEST","EAST2WEST","EAST2SOUTH",
		"NORTH2SOUTH","NORTH2EAST","WEST2EAST","WEST2NORTH",
		"SOUTH2EAST","EAST2NORTH","NORTH2WEST","WEST2SOUTH"
		};
	
	/* 每条路线生成与减少车辆*/
	public static void generationRoad(){
		for(int i=0;i<roads.length;i++){
			new Road(roads[i],vechiclesNumber);
		}
	}
	
	/*生成交通灯控制器,指定南北直线路线为当前灯*/
	public static void generationLampController(){
		new LampController(Lamp.SOUTH2NORTH);
	}
	
	public static void main(String[] args){
	 	generationRoad();
	 	generationLampController();
	}
}

运行结果


------- android培训 java培训 、期待与您交流! ----------

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值