黑马程序员--7K面试题--第十篇--交通灯管理系统视频教程

ASP.Net+Android+IOS开发.Net培训期待与您交流!

模拟十字路口交通灯管理系统模型,要求如下:

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

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

3:实际逻辑与生活中相同,右转向不受限制

4:每辆车通过路口时间为1秒(可通过线程sleep方法模拟)

5:随机生成车辆时间间隔以及红绿灯交换时间间隔

6:不要求实现GUI,只需实现逻辑即可

看到这个题目,我首先想到的就是我们生活中的交通灯情况,右转向不受信号灯限制,车辆是先直行,后左转弯,东西行驶之后南北再行驶,结合老师所讲的模型,我们可以将12个方向的图简化,只需考虑4条线路即可,即S2N,S2W,E2S,E2W。


然后再仔细分析这个系统有哪些对象,那些类,他们的组合关系是什么?有红绿灯,红绿灯的管理系统,汽车,路。

1:这里,要明白汽车和路的关系,汽车是在路上行驶的,汽车过红绿灯不仅仅看灯是否变绿,还要看前面是否有车,而这又该判断呢?这就要问路,这里,车好比吗咋,路好比一条绳子,在java中,车就好比一个对象,路相当于存储这些对象的集合。这里就需要一点面向对象编程的经验,俗话说谁拥有数据,谁就拥有操作这个数据的方法和属性。车在路上,车是否向前走是由路来决定的,路就拥有增加车减少车的方法。

面向对象编程还可以使用以下例子联系:人在黑板上画圆,火车司机刹车,小明把门关上啦。

2:还需要注意就是灯,12个方向共有十二个灯,这里我们可以用枚举表示各个灯,右转弯为常亮灯,除了4个向右转向的灯,剩下的可以分为4组,因为他们都是两两成对的,所以在编程处理时,只需让这4个灯一次轮训变亮即可,它们相对的灯依次相同变化即可。因此Lamp类中要有一个变量记住相反的灯,在一个Lamp灯变亮或变黑的过程中,将对应方向上的灯也变亮和变黑,每一个灯变亮黑时,都伴随着下一个灯的变黑亮,Lamp类中还有一个变量记录自己下一个灯。

下面来编写路这个类

import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.ScheduledExecutorService;
import java.util.concurrent.TimeUnit;
import java.util.Random;
public class Road {
	//把路当成一个装各种车字符串的集合
	//面向接口编程,这样让面试官看见比较好
	//包名起人家公司的网址比较好,哈哈
	private List<String> vechicles = new ArrayList<String>();
	
	//车开到路上来的代码
	private String name;
	public Road(String name){//传入路的名字
		this.name = name;
		//生成一个含有一个线程的执行器
		ExecutorService pool = Executors.newSingleThreadExecutor();
		pool.execute(new Runnable(){
			public void run(){
				for(int i=0;i<1000;i++){
					try{//线程休眠1到10秒
						Thread.sleep((new Random().nextInt(10)+1)*1000);
					}catch(InterruptedException e){
						e.printStackTrace();
					}
					//路上加车
					vechicles.add(Road.this.name+"_"+i);//访问外部类的成员变量,Road.this.name  S2W1代表从南往西的第一辆车
				}
			}
		});
		//下面是定时器,每隔一段时间运行一次线程,实际意义为过多长时间走一辆车
		// Executors.newScheduledThreadPool(1)new出一个含有一个线程的线程池
		ScheduledExecutorService  timer = Executors.newScheduledThreadPool(1);
		timer.scheduleAtFixedRate(new Runnable(){//以固定频率运行线程
			public void run(){
				if(vechicles.size()>0){
					boolean lighted = Lamp.valueOf(Road.this.name).isLighted();
					if(lighted){
						System.out.println(vechicles.remove(0)+"is traversing");//返回第一辆车
					}
				}
			}
		},
				1,//中间间隔为一秒
				1,//运行时间为一秒
				TimeUnit.SECONDS);//计时单位为妙
	}
	
	
}


下面是灯这个类

public enum Lamp {
	N2S(null,null,false),N2E(null,null,false),S2N("N2S","S2W",false),S2W("N2E","E2W",false),
	E2S("W2N","S2N",false),E2W("W2E","E2S",false),W2N(null,null,false),W2E(null,null,false),
	N2W(null,null,true),S2E(null,null,true),E2N(null,null,true),W2S(null,null,true);
	
	//与灯同时为绿的相反方向的灯
	private String opposite;
	//灯是否变绿
	private boolean lighted;
	//灯变红时下一个变绿的灯
	private String next;
	
	
	public void light(){
		this.lighted = true;
		if(opposite != null){
			Lamp.valueOf(opposite).light();
		}
		System.out.println(name()+"lamp is green 下面总共应该看到有6个方向的汽车穿过");
	}
	
	public Lamp blackOut(){
		this.lighted = false;
		if(opposite != null){
			Lamp.valueOf(opposite).blackOut();
		}
		
		Lamp nextLamp = null;
		if(next != null){
			nextLamp = Lamp.valueOf(next);
			System.out.println("绿灯从"+name()+"------>切换为"+next);
			nextLamp.light();
		}
		return nextLamp;
	}
	//对面的灯的状态,灯将要转变的状态,刚开始是否亮
	private Lamp(String opposite,String next,boolean lighted){
		this.opposite = opposite;
		this.next = next;
		this.lighted = lighted;
	}
	private Lamp(){}
	
	//看是否变亮
	public boolean isLighted(){
		return lighted;
	}
	
}


下面是灯控制器

import java.util.concurrent.Executors;
import java.util.concurrent.ScheduledExecutorService;
import java.util.concurrent.TimeUnit;

public class LampController {
	private Lamp currentLamp;
	
	public LampController(){
		currentLamp = Lamp.S2N;//设置第一个灯
		currentLamp.light();//第一个灯是亮的
		//定时器
		/*
		 * 然后启动一个定时器,每隔10秒将当前灯变红和将下一个灯变绿。
		 * */
		ScheduledExecutorService timer = Executors.newScheduledThreadPool(1);
		timer.scheduleAtFixedRate(new Runnable(){
					public void run(){
						//这句话记录了当前变绿的灯
						currentLamp = currentLamp.blackOut();
					}
				},
				10,//中间间隔10秒
				10,//运行时间为10面
				TimeUnit.SECONDS);
	}
}


测试类

public class MainClass {
	
	public static void main(String[] args) {
		String[] dirs = new String[]{
				"N2S","N2E","S2N","S2W","E2W","E2S","W2E","W2N","N2W","S2E","E2N","W2S"
		};
		for(String str:dirs){
			//new出每个路,车在不停的上路
			 new Road(str);
		}
		//启动红绿灯执行系统
		new LampController();
	}

}
以上内容解决了三个问题:

1,明白车在路上跑,车字符串,路当作集合,绿灯时车不仅仅看灯,还得看前面是否有车,这就得问路,路有增加车和减少车的方法。

2,12个方向的灯,灯有变亮的方法(同时对面的灯也变亮),灯有变暗的方法(同时返回下一个变绿的灯),还有一个方法显示此时此刻灯是否变亮的状态。

3,定时器,那四个参数,一个是以固定频率运行线程,一个是间隔时间,一个是运行时间,一个是设置单位

线程池,可以设置含有多少个线程运行某个程序,这个是一个线程,隔1到10秒,路上添加一辆车。


ASP.Net+Android+IOS开发.Net培训期待与您交流!


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值