张老师面试题讲解——交通信号灯

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

 

今天看了张老师的这个面试题讲解才感觉到自己在一个什么水平,继续努力学习,还需不断提升自己的能力!

继续学习巩固一些知识,对线程池的认识以及对定时器的熟练掌握。各个知识点融会贯通才能成为一名优秀的程序员。

 

交通信号灯题目及要求

1.异步随机生成按照各个路线行驶的车辆。

例如:

       由南向而来去往北向的车辆 ---- 直行车辆

       由西向而来去往南向的车辆 ---- 右转车辆

       由东向而来去往南向的车辆 ---- 左转车辆

       。。。

2. 信号灯忽略黄灯,只考虑红灯和绿灯。

3. 应考虑左转车辆控制信号灯,右转车辆不受信号灯控制。

4.具体信号灯控制逻辑与现实生活中普通交通灯控制逻辑相同,不考虑特殊情况下的控制逻辑。

注:南北向车辆与东西向车辆交替放行,同方向等待车辆应先放行直行车辆而后放行左转车辆。

5. 每辆车通过路口时间为1秒(提示:可通过线程Sleep的方式模拟)。

6. 随机生成车辆时间间隔以及红绿灯交换时间间隔自定,可以设置。

7. 不要求实现GUI,只考虑系统逻辑实现,可通过Log方式展现程序运行结果。

画图分析:

分析对象,原则:谁拥有数据,谁就对外提供操作这些数据的方法。

路对象:

通过线程时间随机地产生汽车并存入集合众,跟据交通信号灯的变化移除汽车。

灯对象:

图中共有12条路线 , 就可以看作为12个固定的交通灯 ,由于每次都是在操作同一对象, 所以运用用Enum枚举类就更加方便。,
由于向右拐弯是不受灯控制的 , 所以4条右转弯的灯一直为绿(true) ,  在剩下的8条路线中 , 路线是两两对应的  , S2N-N2S , S2W-N2E ,W2E-E2W , E2S-W2N , 并且第一组灯变红(false)时 , 第二组灯就变绿(true) , 依次往复 , 这样就明确的灯的对应和交替关系 。

信号灯控制器:

添加定时器,控制红绿灯变化。

路的代码:

import java.util.ArrayList;
import java.util.List;
import java.util.Random;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.ScheduledExecutorService;
import java.util.concurrent.TimeUnit;

public class Road {
	private List<String> vehicles = new ArrayList<String>();   //创建集合,用来存放产生的汽车
	
	String roadName = null;
	
	Road(String roadName){   //路的构造方法
		this.roadName = roadName;	
		
		ExecutorService pool = Executors.newSingleThreadExecutor();   //学习Executors类,创建独立线程。Java1.5			
		pool.execute(new Runnable(){    //匿名内部类
			@Override
			public void run() {

				for(int i=1; i<1000; i++){
					try {
						
						Thread.sleep((new Random().nextInt(10)+1)*1000);  //
					} 
					catch (InterruptedException e) {
						e.printStackTrace();
					}
					//把车放进集合中
					vehicles.add(Road.this.roadName+"_"+i);	  //外部类的局部变量的访问方式:外部类名.this.变量名				
				}
			}
		});
		
		
		ScheduledExecutorService timer = Executors.newScheduledThreadPool(1);  //定义一个计划的线程池,线程的数量为1
		
		//创建并执行此线程池,初始可以定时、并且后续具有周期性的方法.
		//用于当交通灯为绿色时,移出当前路上的车辆
		timer.scheduleAtFixedRate(
				new Runnable(){
					@Override
					public void run() {
						if(vehicles.size()!=0){							
							boolean lighted = Lamp.valueOf(Road.this.roadName).isLighted();
							if(lighted){
								System.out.println(vehicles.remove(0)+" is traversing");
							}
						}
					}					
				},
				1,
				1,
				TimeUnit.SECONDS);
	}
}

信号灯:

public enum Lamp {
	//前四个灯为主控灯,括号内传入的分别是,"对应的灯","下一个灯",灯默认值
	S2N("N2S","S2W",false),S2W("N2E","E2W",false),E2W("W2E","E2S",false),E2S("W2N","S2N",false),
	//中间四个灯为上面四个灯所对应的灯,并受其控制
	N2S(null,null,false),N2E(null,null,false),W2E(null,null,false),W2N(null,null,false),
	//后四个为右转弯的灯,为常绿状态
	S2E(null,null,true),E2N(null,null,true),N2W(null,null,true),W2S(null,null,true);
	
	private Lamp(String opposite,String next,boolean lighted){
		this.opposite = opposite;
		this.next = next;
		this.lighted = lighted;
	}
	
	private boolean lighted;
	private String opposite;
	private String next;
	
	public boolean isLighted(){   //判断灯的状态
		return lighted;
	}
	//灯变绿方法
	public void light(){
		this.lighted = true;
		if(opposite != null){
			Lamp.valueOf(opposite).light();
		}
		System.out.println(this.name()+"lamp is green");
	}
	//灯变红方法
	public Lamp lightOff(){
		this.lighted = false;
		if(opposite != null){
			Lamp.valueOf(opposite).lightOff();
		}
		System.out.println(next);
		Lamp nextLamp = null;
		if(next != null){
			System.out.println("绿灯由"+name()+"变成"+next);		
			nextLamp = Lamp.valueOf(next);
			//System.out.println("test");
			nextLamp.light();
		}
		return nextLamp;
	}
}

信号灯控制器:

public class LampController {
	private Lamp currentLamp = null;
	public LampController(){
		currentLamp = Lamp.S2N;  //定义初始变绿方向的灯
		currentLamp.lightOn();
		
		ScheduledExecutorService timer = Executors.newScheduledThreadPool(1);   //添加定时器,根据实际逻辑红绿灯不断交替
		timer.scheduleAtFixedRate(
				new Runnable(){
					public void run(){
						
						currentLamp = currentLamp.lightOff();  //lightOff返回下一个当前状态等
					}
				},
				10, 
				10,
				TimeUnit.SECONDS);
	}
}

编写住方法实现功能:

public class MainClass {

	public static void main(String[] args) {
		String[] roadNames = new String[]{
				"S2N","S2W","E2W","E2S",
				"N2S","N2E","W2E","W2N",
				"S2E","E2N","N2W","W2S"
				};
		for(String roadName : roadNames){
			new Road(roadName);
		}
		new LampController();
	}
}





 

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值