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

来源:互联网 发布:双人無心内事无人知 编辑:程序博客网 时间:2024/05/01 18:27

 ------- 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.5pool.execute(new Runnable(){    //匿名内部类@Overridepublic 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(){@Overridepublic 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();}}