黑马程序员_Java7K面试题——交通灯管理系统(第10篇)

---------------------- ASP.Net+Unity开发.Net培训、期待与您交流! ----------------------

一、题目和一些感触

    今天把视频中的交通灯管理系统的面试题动手跟着张老师的步骤做了下。我发现,代码的实现其实并不困难,困难的在于前期的对于项目的整体的把握,对项目的详细的分析,具体需求的拆解,更重要的是实现的逻辑一定不能有错,这涉及到根本,逻辑错了,等于没写,就像视频中张孝祥老师说那个拿来题目的同学,一开始就没搞清楚到底有几条线路。所以大家写程序前,一定不要拿到手就写,要把前后流程、逻辑关系理清楚了再动手,不然只能是浪费时间。

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

二、项目分析

1.对于十字路口,我们要清楚有多少条路线,即使多少种行走方向,我们可以通过下图来清晰的表达。


由图中,我们可以清晰的看出十字路口的路线有直行的4条,拐弯的8条,总计是12条线路。
--所以要设计一个表示路线的类Road,因为有12条路线,所以系统中要产生12个Road实例对象。
--我们的程序中要有车辆通过路口,所以路线上应该随机增加车辆,所以在Road类中要有一个集合用来存放产生的车辆。
--由项目需求可知每条路线每隔一秒都会检查控制本路线的灯是否为绿,则可以将本路线保存车的集合中的第一辆车移除,即表示车穿过了路口。

2.每条路线每隔一秒都会检查控制本路线的灯是否为绿,一个灯由绿变红时,应该将下一个方向的灯变绿。那么我们需要有一个交通灯类

--设计一个Lamp类来表示一个交通灯,每个交通灯都维护一个状态:亮(绿)或不亮(红),每个交通灯要有变亮和变黑的方法,并且能返回自己的亮黑状态。
--总共有12条路线,所以,系统中总共要产生12个交通灯。右拐弯的路线本来不受灯的控制,但是为了让程序采用统一的处理方式,故假设出有四个右拐弯的灯,只是这些灯为常亮状态,即永远不变黑。
--除了右拐弯方向的其他8条路线的灯,它们是两两成对的,可以归为4组,所以,在编程处理时,只要从这4组中各取出一个灯,对这4个灯依次轮询变亮,与这4个灯方向对应的灯则随之一同变化,因此Lamp类中要有一个变量来记住自己相反方向的灯,在一个Lamp对象的变亮和变黑方法中,将对应方向的灯也变亮和变黑。每个灯变黑时,都伴随者下一个灯的变亮,Lamp类中还用一个变量来记住自己的下一个灯。
--无论在程序的什么地方去获得某个方向的灯时,每次获得的都是同一个实例对象,所以Lamp类改用枚举来做显然具有很大的方便性,永远都只有代表12个方向的灯的实例对象。
--设计一个LampController类,它定时让当前的绿灯变红。

三、类的编写

1.Road

--每个Road对象都有一个name成员变量来代表方向,有一个che成员变量来代表方向上的车辆集合。
--在Road对象的构造方法中启动一个线程每隔一个随机的时间向vehicles集合中增加一辆车(用一个“路线名_id”形式的字符串进行表示)。
--在Road对象的构造方法中启动一个定时器,每隔一秒检查该方向上的灯是否为绿,是则打印车辆集合和将集合中的第一辆车移除掉。

Road类如下:

class Road
{
	//路名
	private String name = null;
	List<String> che = new ArrayList<String>();	
	public Road(String name)
	{
		this.name = name;
		//创建单个线程放到线程池中
		ExecutorService pool = Executors.newSingleThreadExecutor();
		pool.execute(new Runnable(){
			public void run()
			{
				for(int i = 1; i < 1000; i++)
				{
					try
					{
						//1-10秒随机
						Thread.sleep((new Random().nextInt(10) + 1) * 1000);			
					}
					catch (InterruptedException e)
					{
						e.printStackTrace();
					}
					che.add(Road.this.name + "_" + i);
				}
			}
		});
		//定时器
		ScheduledExecutorService timer = Executors.newScheduledThreadPool(1);
		timer.scheduleAtFixedRate(
			new Runnable(){
				public void run()
				{
					if(che.size() > 0)
					{
						boolean lighted = Lamp.valueOf(Road.this.name).isLighted();
						if(lighted)
						{
							System.out.println(che.remove(0) + "通过...");
						}
					}
				}
		},1 , 1, TimeUnit.SECONDS);
	}
		
}

2.Lamp

--系统中有12个方向上的灯,在程序的其他地方要根据灯的名称就可以获得对应的灯的实例对象,综合这些因素,将Lamp类用java5中的枚举形式定义更为简单。
--每个Lamp对象中的亮黑状态用lighted变量表示,选用S2N、S2W、E2W、E2N这四个方向上的Lamp对象依次轮询变亮,Lamp对象中还要有一个oppositeLampName变量来表示它们相反方向的灯,再用一个nextLampName变量来表示此灯变亮后的下一个变亮的灯。这三个变量用构造方法的形式进行赋值,因为枚举元素必须在定义之后引用,所以无法再构造方法中彼此相互引用,所以,相反方向和下一个方向的灯用字符串形式表示。 
--增加让Lamp变亮和变黑的方法:light和blackOut,对于N2B、N2X、D2X、D2B这四个方向上的Lamp对象,这两个方法内部要让相反方向的灯随之变亮和变黑,blackOut方法还要让下一个灯变亮。
--除了N2B、N2X、D2X、D2B这四个方向上的Lamp对象之外,其他方向上的Lamp对象的DuiMian和next属性设置为null即可,并且S2N、S2W、E2W、E2N这四个方向上的Lamp对象的nextLampName和oppositeLampName属性必须设置为null,以便防止light和blackOut进入死循环。

Lamp类如下:

public enum Lamp
{
	//12条路线
	N2B("B2N", "N2X", false), N2X("B2D", "D2X", false), D2X("X2D", "D2N", false), D2N("X2B", "N2B", false),
	B2N("null", "null", false), B2D("null", "null", false), X2D("null", "null", false), X2B("null", "null", false),
	N2D(null, null, true), D2B(null, null, true), B2X(null, null, true), X2N(null, null, true);
	private Lamp(String duiMian, String next, boolean lighted)
	{
		this.duiMian = duiMian;  
		this.next = next;
		this.lighted = lighted;
	}
	private boolean lighted;
	private String duiMian;
	private String next;
	//判断灯是否亮
	public boolean isLighted()
	{
		return lighted;
	}
	//亮绿灯,对面的绿灯也亮
	public void light()
	{
		this.lighted = true;
		if(duiMian != null)
			Lamp.valueOf(duiMian).light();
	}
	//亮红灯
	public Lamp blackOut()
	{
		this.lighted = false;
		if(duiMian != null)
			Lamp.valueOf(duiMian).blackOut();
		
		Lamp nextLamp= null;
		if(next != null)
		{
			nextLamp = Lamp.valueOf(next);
			nextLamp.light();
		}
		return nextLamp;
	}

}

3.LampController

--整个系统中只能有一套交通灯控制系统,所以,LampController类最好是设计成单例。
--LampController构造方法中要设定第一个为绿的灯。
--LampController对象的start方法中将当前灯变绿,然后启动一个定时器,每隔10秒将当前灯变红和将下一个灯变绿。

LampController类如下:

class LampController
{
	private Lamp currentLamp;
	public LampController()
	{
		currentLamp = Lamp.N2B;
		currentLamp.light();

		ScheduledExecutorService timer = Executors.newScheduledThreadPool(1);
		timer.scheduleAtFixedRate(new Runnable(){
			public void run()
			{
				currentLamp = currentLamp.blackOut();
			}
		}, 10, 10,TimeUnit.SECONDS);
	}
}

4.MainClass

--用for循环创建出代表12条路线的对象。
--接着再获得LampController对象并调用其start方法。

MainClass类如下:

class MainClass
{
	public static void main(String[] args)
	{
		/*产生12个方向的路线*/		
		String [] directions = new String[]{
				"N2B", "N2X", "D2X", "D2N", "B2N", "B2D", "X2D", "X2B", "N2D", "D2B", "B2X", "X2N"		
		};
		for(int i=0;i<directions.length;i++){
			new Road(directions[i]);
		}
		
		/*产生整个交通灯系统*/		
		new LampController();
	}
}

---------------------- ASP.Net+Unity开发.Net培训、期待与您交流! ----------------------

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
东南亚位于我国倡导推进的“一带一路”海陆交汇地带,作为当今全球发展最为迅速的地区之一,近年来区域内生产总值实现了显著且稳定的增长。根据东盟主要经济体公布的最新数据,印度尼西亚2023年国内生产总值(GDP)增长5.05%;越南2023年经济增长5.05%;马来西亚2023年经济增速为3.7%;泰国2023年经济增长1.9%;新加坡2023年经济增长1.1%;柬埔寨2023年经济增速预计为5.6%。 东盟国家在“一带一路”沿线国家中的总体GDP经济规模、贸易总额与国外直接投资均为最大,因此有着举足轻重的地位和作用。当前,东盟与中国已互相成为双方最大的交易伙伴。中国-东盟贸易总额已从2013年的443亿元增长至 2023年合计超逾6.4万亿元,占中国外贸总值的15.4%。在过去20余年中,东盟国家不断在全球多变的格局里面临挑战并寻求机遇。2023东盟国家主要经济体受到国内消费、国外投资、货币政策、旅游业复苏、和大宗商品出口价企稳等方面的提振,经济显现出稳步增长态势和强韧性的潜能。 本调研报告旨在深度挖掘东南亚市场的增长潜力与发展机会,分析东南亚市场竞争态势、销售模式、客户偏好、整体市场营商环境,为国内企业出海开展业务提供客观参考意见。 本文核心内容: 市场空间:全球行业市场空间、东南亚市场发展空间。 竞争态势:全球份额,东南亚市场企业份额。 销售模式:东南亚市场销售模式、本地代理商 客户情况:东南亚本地客户及偏好分析 营商环境:东南亚营商环境分析 本文纳入的企业包括国外及印尼本土企业,以及相关上下游企业等,部分名单 QYResearch是全球知名的大型咨询公司,行业涵盖各高科技行业产业链细分市场,横跨如半导体产业链(半导体设备及零部件、半导体材料、集成电路、制造、封测、分立器件、传感器、光电器件)、光伏产业链(设备、硅料/硅片、电池片、组件、辅料支架、逆变器、电站终端)、新能源汽车产业链(动力电池及材料、电驱电控、汽车半导体/电子、整车、充电桩)、通信产业链(通信系统设备、终端设备、电子元器件、射频前端、光模块、4G/5G/6G、宽带、IoT、数字经济、AI)、先进材料产业链(金属材料、高分子材料、陶瓷材料、纳米材料等)、机械制造产业链(数控机床、工程机械、电气机械、3C自动化、工业机器人、激光、工控、无人机)、食品药品、医疗器械、农业等。邮箱:market@qyresearch.com

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值