交通灯系统面试题总结
在交通灯系统中,交通灯,交通灯控制器,道路为主要对象。因此,可以设计三个主要类:交通灯类,交通灯控制器类,道路类。
设计思路:道路上有车,路上的交通灯控制车过马路,交通灯控制器控制灯的红绿变化。
1. 交通灯类中封装了12个方法上的交通灯名,用枚举表示。其中交通灯中的三个参数依次是当前灯的对面灯,下一个要变绿的交通灯以及判断当前灯是否是绿灯。
另外封装了交通灯变绿,变红的方法。
publicenum Lamp {
//枚举中定义12个方法的灯实例
S2N("N2S","S2W",false),S2W("N2E","E2W",false),E2W("W2E","E2S",false),E2S("W2S","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(){
}
//oppositeLamp表示对面的交通灯,nextLamp表示下一个要变绿的灯,isGreen判断当前交通灯是否变绿了
private Lamp(String oppositeLamp,String nextLamp,boolean isGreen){
this.oppositeLamp=oppositeLamp;
this.nextLamp=nextLamp;
this.isGreen=isGreen;
}
publicboolean isGreen(){
returnisGreen;
}
//当前交通灯变绿时,把对面的交通灯也变绿
publicvoid turnGreen(){
this.isGreen=true;
if(null==oppositeLamp){
Lamp.valueOf(oppositeLamp).turnGreen();
//System.out.println("lamp and the opposite lamp is turning green");
}
}
//当前交通灯变红时,把对面的交通灯也变红,并把nextLamp变绿
public Lamp turnRed(){
this.isGreen=false;
if(null==oppositeLamp){
Lamp.valueOf(oppositeLamp).turnRed();
//System.out.println("lamp and the opposite lamp is turning red");
}
Lamp next = Lamp.valueOf(nextLamp) ;
if(null!=next){
next.turnGreen();
//System.out.println("the next is turning green");
}
return next;
}
private String oppositeLamp;
private String nextLamp;
privatebooleanisGreen;
}
2. 交通灯控制器类中封装了一个当前交通灯引用,并在构造方法中确定将哪一个灯设置为当前交通灯然后将它变绿,然后用一个线程执行交通灯周期变红变绿。
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.ScheduledExecutorService;
import java.util.concurrent.TimeUnit;
public class LampController {
private Lamp currentLamp;//封装一个当前交通灯的引用
//将当前交通灯设置为S2N的交通灯,并且让它变绿。然后利用一个线程让currentLamp在第10秒变红,并让nextLamp变绿。
// 每隔10秒钟重复上述操作。
public LampController(){
currentLamp=Lamp.S2N;
currentLamp.turnGreen();
ScheduledExecutorService timer =Executors.newScheduledThreadPool(1);//创建一个线程调度池
timer.scheduleAtFixedRate(new Runnable(){
public void run(){
currentLamp = currentLamp.turnRed();//让当前交通灯变红,并返回下一个要变绿的交通灯赋给currentLamp
currentLamp.turnGreen();
}
},
10,//第10秒钟开始
10,//每隔10秒重复一次
TimeUnit.SECONDS);//时间单位为秒
}
}
3. 道路类封装用一个集合成员变量,用来表示每一条道路上的车辆数量;构造方法表示每条道上最多跑100辆车,当有车进入道路,就加进集合中,这个任务用一个线程来执行。再用一个固定频率的线程来判断绿灯时道路上有车就开走第一辆的任务。
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> vechicles =new ArrayList<String>();//用一个集合vechicles来管理道路上的车辆
private String name;//对应交通灯的道路名
//Road构造方法表示每条道路上最多可以容纳100辆车,然后每一秒判定该道路上是否有车和灯是否为绿,
//当该道路上有车并且交通灯为绿,就让该道路上的第一辆车跑出去
public Road(String name){
this.name =name;
ExecutorService pool = Executors.newSingleThreadExecutor();
//用匿名内部类作为参数,实现Runnable接口。
pool.execute(new Runnable(){
public void run(){
for(int i =1; i<100;i++){
try {
Thread.sleep((new Random().nextInt(1000)+1)*10);//随机睡眠1-10秒
} catch (InterruptedException e) {
e.printStackTrace();
}
vechicles.add(Road.this.name+ "--"+ i); //每有一辆车进入name表示的道路,就将该车辆加入vechicles
}
}
});
ScheduledExecutorService timer =Executors.newScheduledThreadPool(1);
timer.scheduleAtFixedRate(new Runnable(){
public void run(){
//当vechicles中的车辆不为0,判断Road.this.name表示的交通灯是否为绿
if(vechicles.size()>0){
boolean isGreen = Lamp.valueOf(Road.this.name).isGreen();
//如果Road.this.name道路上的交通灯是绿的,就让vechicles中的第一辆车开出去。
if(isGreen){
System.out.println(vechicles.remove(0)+"is running off");
}
}
}
},
1,//在第1秒钟的时候开始执行
1,//每隔一秒重复执行
TimeUnit.SECONDS);//时间单位为秒
}
}
4. 编写出一个测试类,里面包含一个灯控制器,12个方向上交通灯以及对应12个交通灯的12条道路。运行后就会得到正确的结果。
publicclass Test {
publicstaticvoid main(String[] args){
//12个方向上的交通灯
String [] directions = new String[]{ "S2N","S2W","E2W","E2S",
"N2S","N2E","W2E","W2N",
"S2E","E2N","N2W","W2S"};
//对应12个交通灯的12条道路
for(int i=0; i<directions.length;i++){
new Road(directions[i]);
}
//交通灯控制器
new LampController();
}
}