昨天某知名互联网企业对我做了一个电话面试。然后叫我在他给的一个网址上面做一个编程题。
题目是这样的。
共计9个苹果,有2只猴子,一个猴子每次拿2个苹果,一个猴子每次拿3个苹果,如果剩余的苹果不够猴子每次拿的数量,则2只猴子停止拿苹果,请用java多线程模拟上面的描述
描述是挺简单的。但当在电话面试的情况下,又是一个比较知名公司的限时下。我那小心肝是紧张的,再加上是在一个非IDE环境下写代码很多API记不详细,所以导致我写出了下面的这个诡异的版本。真是丢脸呀。
//monkey2 是类似 monkey1的。当时紧张还没写完然后自己的网络突然异常了,然后就断联了。注定是抓不住机会好好表现了
private static volatile int appleStoreCount = 9;
public static void main(String... args) {
ReentrantLock lock = new ReentrantLock();
Runnable monkey1 = () -> {
int takeOffNum = 2;
outer : while(true){
lock.lock()
while( appleStoreCount >= takeOffNum) {
appleStoreCount -= takeOffNum;
lock.unlock();// 这个业务简单假设不出现异常,所以不放finally里了
continue outer;
}
break;
};
};
Runnable monkey2 = () -> {
int takeOffNum = 3;
while( appleStoreCount.get() > = takeOffNum){
if (appleStoreCount.compareAndDecrement(takeOffNum) == false){
continue;
}
};
};
Thread monkey1Task = new Thread(monkey1);
Thread monkey2Task = new Thread(monkey2);
monkey1Task.start();
monkey1Task.start();
}
但这代码真不是我最初设想的那样的。真不知我这心里素质是什么情况了。
下面给出我冷静后并且未查询资料,只是在IDE环境下写出的代码。
private static final AtomicInteger STORE_COUNT = new AtomicInteger(9);
@Test
public void tttt() {
Runnable monkey1 = () -> {
String monkeyName = "monkey1";
int takeoffNum = 2,
storeCountByGet = 0;
while ((storeCountByGet = STORE_COUNT.get()) >= takeoffNum) {
if (STORE_COUNT.compareAndSet(storeCountByGet, storeCountByGet - takeoffNum)) {
System.out.println(monkeyName + "争抢水果成功 => " + takeoffNum);
} else {
System.out.println(monkeyName + "争抢水果失败");
}
}
};
Runnable monkey2 = () -> {
String monkeyName = "monkey2";
int takeoffNum = 3,
storeCountByGet = 0;
while ((storeCountByGet = STORE_COUNT.get()) >= takeoffNum) {
if (STORE_COUNT.compareAndSet(storeCountByGet, storeCountByGet - takeoffNum)) {
System.out.println(monkeyName + "争抢水果成功 => " + takeoffNum);
} else {
System.out.println(monkeyName + "争抢水果失败");
}
}
};
Thread m1Task = new Thread(monkey1);
Thread m2Task = new Thread(monkey2);
m2Task.start();
m1Task.start();
}
输出如下
monkey2争抢水果失败
monkey1争抢水果成功 => 2
monkey2争抢水果成功 => 3
monkey1争抢水果成功 => 2
monkey1争抢水果成功 => 2
这一个才是我最初设想的实现。只能说较差的心理素质和非IDE环境导致了发挥失常。可惜呀。这个实现不算完美,但算符合需求且干净的实现。
————————————————不希望被忽视的分割线——————————
这部分是我看到题目时所想到的一个扩展问题。
共计9个苹果,有2只猴子,一个猴子每次拿2个苹果,一个猴子每次拿3个苹果,如果剩余的苹果不够猴子每次拿的数量,则2只猴子停止拿苹果,两只猴子依次拿取苹果。请用java多线程模拟上面的描述
下面是我实现
private volatile Integer[] storeCount = { 9 };
private volatile int flagInt = 2;
@Test
public void tttt1() {
Runnable monkey1 = () -> {
String monkeyName = "monkey1";
int takeoffNum = 2,
flagVal = 1;
synchronized (storeCount) {
try {
while (storeCount[0].intValue() >= takeoffNum) {
if (flagInt != flagVal) {
storeCount.wait();
}
if (storeCount[0].intValue() >= takeoffNum) {
storeCount[0] -= takeoffNum;
System.out.println(monkeyName + "争抢水果成功 => " + takeoffNum);
flagInt = 2;
storeCount.notifyAll();
}
}
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
};
Runnable monkey2 = () -> {
String monkeyName = "monkey2";
int takeoffNum = 3,
flagVal = 2;
synchronized (storeCount) {
try {
while (storeCount[0].intValue() >= takeoffNum) {
if (flagInt != flagVal) {
storeCount.wait();
}
if (storeCount[0].intValue() >= takeoffNum) {
storeCount[0] -= takeoffNum;
System.out.println(monkeyName + "争抢水果成功 => " + takeoffNum);
flagInt = 1;
storeCount.notifyAll();
}
}
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
};
Thread m1Task = new Thread(monkey1);
Thread m2Task = new Thread(monkey2);
m1Task.start();
m2Task.start();
}
输出如下
monkey2争抢水果成功 => 3
monkey1争抢水果成功 => 2
monkey2争抢水果成功 => 3
将flagInt的初始值改成1后的输出如下
monkey1争抢水果成功 => 2
monkey2争抢水果成功 => 3
monkey1争抢水果成功 => 2
分享到:
相关推荐
1. **观察与实验**:通过观察现象和实验来解决问题。 2. **组合与拆分**:将问题分解成更小的部分,通过组合这些部分来解决问题。 **实现细节**: - 对于灯泡的问题,可以分别打开每一个开关,观察灯泡的状态,从而...
【面试题】是高校软件相关实验室或社团筛选新成员的重要环节,主要目的是考察候选人的个人能力、技术素养以及团队合作精神。以下是对这些面试题所涉及的知识点的详细解析: 0x01 自我介绍:这不仅是展示个人基本...
"C++面试实验题知识点总结" 本文将对C++面试实验题中的...通过这些知识点的总结,我们可以看到C++面试实验题涵盖了C++语言的方方面面,包括类和对象、指针和数组、函数和运算符、输入输出和字符串、面向对象编程等。
并发编程面试题大全.rar
C语言开发编程面试题汇总 本资源汇总了C语言开发面试中常见的问题和答案,涵盖了模块化编程、关键字和运算符、变量、printf()和scanf()函数、AT&T实验室、ANSI、ARM等多个方面的知识点。 模块化编程 模块化编程是...
函数模板是C++中的泛型编程工具,第4题中,函数模板并不是一个具体的函数,而是用于生成特定类型函数的蓝图。当与特定的数据类型一起使用时,函数模板实例化为实际的函数,因此正确答案是C。 结构体(struct)是C++...
2. **编程语言**:掌握至少一种或多种编程语言,如C/C++、Java、Python等,了解其特点和应用场景,能够解决实际编程问题。 3. **数据库管理**:SQL语言的基础知识,数据库设计概念,如ER模型、范式理论,以及事务...
"计算机网络习题/编程/实验答案.zip" 是一个压缩包,其中包含了对《计算机网络——自顶向下方法》这本书的学习资料,包括习题解答、编程练习和实验方案。这本书通常被用作大学计算机科学或信息技术专业的教材,其自...
机器学习、深度学习面试题合集 机器学习、深度学习面试题合集是机器学习和深度学习领域的常见面试题的集合。该合集涵盖了机器学习和深度学习的基本概念、算法和模型,包括支持向量机(SVM)、TensorFlow、Gradient ...
这份“C++笔试面试题基础”资料可能是为了帮助求职者准备C++相关的技术面试而设计的。下面将针对C++的基础知识进行详细阐述。 1. **C++简介**:C++是C语言的增强版,由Bjarne Stroustrup于1983年在贝尔实验室发起。...
3. **面试集合**:这部分可能包含了历年的面试真题或者模拟题,帮助考生了解面试的常见问题和形式。面试通常会涉及到上述课程的内容,同时还会考察学生的编程能力、解决问题的能力以及对最新技术的了解,如人工智能...
嵌入式软硬件面试笔试题集锦涵盖了C语言、C++、Linux驱动开发以及STM32微控制器等多个关键领域的知识,这些是嵌入式系统设计和开发中的核心技能。下面,我们将逐一深入探讨这些知识点。 1. **C语言**:作为嵌入式...
从给定的文件信息来看,主要涉及的是IBM面试中出现的一些智力题,这些题目涵盖了逻辑推理、数学计算、策略思考等多个方面。下面将对部分题目进行详细的解析与知识点的提炼。 ### 题目解析 #### 1. 时间与速度问题 ...
### 其他面试题中的技术问题 #### 问题1:页面访问速度不一的原因 可能原因包括: - 文件大小不一,大文件加载时间较长。 - 网络延迟不同,某些资源可能位于较远的位置。 - 服务器负载不同,繁忙时响应速度减慢。 ...
文件"微软面试题.txt"很可能包含了微软在面试中常问的逻辑思维题目,这些题目可能涵盖算法设计、问题解决、数据分析、编程逻辑等多个方面。这些问题通常需要应聘者以逻辑清晰、条理分明的方式去分析问题,找到最优...
该压缩包文件"必达泰克笔试题_嵌入式-常用知识&面试题库_大厂面试真题.rar"显然是一个针对必达泰克公司嵌入式岗位的面试准备资料集合,可能包含多套笔试题目和相关解答,旨在测试和评估应聘者对嵌入式领域的理解和...
6. 实验技能与实践项目:考生应能阐述自己在本科期间参与的实验项目或实践经验,例如自动化生产线的设计、机器人控制、智能小车的制作等。 7. 工程伦理与法规:面试还可能测试考生对于工程道德规范、行业标准以及...
在IT行业中,图形智力题是许多公司在面试过程中用于评估求职者逻辑思维、问题解决能力和创新思维的一种常见方式。这类题目通常不涉及特定的编程语言或技术细节,而是侧重于考察应聘者的抽象思考、模式识别和推理能力...
北航计算机复试面试题(完整版)资料.doc 本资源包含了北航计算机复试面试题的完整版资料,涵盖了计算机科学和信息技术的多个领域,包括操作系统、计算机网络、数据结构与算法、数据库、软件测试、编译原理、计算机...
以下是一些C语言相关的面试题,旨在测试和提升你的C语言知识。 1. **基本概念** - 什么是C语言?C语言是由Dennis Ritchie在贝尔实验室开发的,它是一种面向过程的、低级的、结构化的编程语言。 - C语言的特点有...