学生的考试
功能描述
学生类
- 答题
- 交卷
- 作弊
- 交头接耳
班长
- 打小报告(看有没有同学交头接耳)
老师
- 发卷子
- 收卷子
- 监督考场
- 评卷
- 公布分数
- 处理小报告
班主任
- 巡视考场
场景描述
10个学生(含一个班长)有一场考试。根据以上功能完成以下需求
40道题,学生答题,交卷。在整个考试期间学生随机出现作弊、交头接耳的行为。
班长随机抽查有没有学生交头接耳,如果有则报告给老师。
老师分发试卷,考试结束(时间五分钟)收卷,对卷子进行评分,并公布成绩,老师收到班长的小报告,对交头接耳的同学进行批评教育
代码实现
1.学生类
1.首先准备学生类,根据需求属性需要设计 姓名,试卷
2. @Data 实现构造方法
3. 实现学生的行为,分别为作弊、答题、交卷、交头接耳
4. 考虑到班长是学生,设计班长的抽象类,提供打小报告的方法,学生类继承此抽象类,实现抽象方法
package com.common.test;import lombok.Data;
import lombok.experimental.Accessors;
import org.springframework.util.StringUtils;import java.util.*;
import java.util.concurrent.ThreadLocalRandom;@Data@Accessors(chain = true)
public class Student extends Monitor {private String name;private ExaminationPaper examinationPaper;//作弊public Boolean Cheat() {return random(4) == 0;}private final Map<Integer, String> map = new HashMap<Integer, String>() {{put(0, "A");put(1, "B");put(2, "C");put(3, "D");put(4, "N");}};public void tianjuan(ExaminationPaper examinationPaper){this.examinationPaper = examinationPaper;this.examinationPaper.setName(this.name);}//答题public void Answer() {Map<String, String> topic = this.examinationPaper.getTopic();for (String key : topic.keySet()) {if (StringUtils.isEmpty(topic.get(key))) {topic.put(key, map.get(random(5)));return;}}}//交卷public Boolean HandPaper() {Map<String, String> topic = this.examinationPaper.getTopic();for (String key : topic.keySet()) {if (StringUtils.isEmpty(topic.get(key))) {return false;}}return true;}//交头接耳public Boolean Whisper() {return random(6) == 0;}private Integer random(Integer bound){ThreadLocalRandom random = ThreadLocalRandom.current();return random.nextInt(bound);}@Overridevoid report(List<String> names) {System.out.print("交头接耳的同学有:");List<String> result = new ArrayList<>();Set set = new HashSet(); //新建一个HashSetset.addAll(names); //list里的所有东西放入set中 进行去重result.addAll(set); //把去重完的set重新放回list里for (String name : result) {System.out.print(name+",");}System.out.println("");}
}
班长抽象类
package com.common.test;import java.util.List;abstract class Monitor {abstract void report(List<String> names);
}
试卷类
- 试卷包含姓名、题目属性
- 题目属性为map key为题目 value 为答案
package com.common.test;
import lombok.Data;
import java.util.Map;@Data
public class ExaminationPaper {private String name;//姓名private Map<String,String> topic;//题目}
老师类
- 由于班主任为老师,因此设计班主任的接口,提供监督考场的功能(方法)
- 结合老师收取学生试卷与公布成绩的需要,设计试卷与成绩的属性
- 实现老师的发卷、收卷、批评教育、判卷、公布成绩的功能,分别对应以下方法
package com.common.test;import lombok.Data;
import java.util.*;@Data
public class Teacher implements ClassTeacher {private List<ExaminationPaper> examinationPapers = new ArrayList<>();//试卷private Map<String, Integer> result = new HashMap<>(); //成绩@Overridepublic void supervise() {System.out.println("班主任监督第一个考场");}/*** 分发试卷** @return*/public ExaminationPaper DistributePapers() {HashMap<String, String> map = new HashMap<>();for (int i = 1; i <= 40; i++) {map.put(i + "、第" + i + "题的答案是什么?", null);}ExaminationPaper examinationPaper = new ExaminationPaper();examinationPaper.setTopic(map);return examinationPaper;}/*** 收试卷*/public void CollectPapers(List<Student> students) {for (Student student : students) {this.examinationPapers.add(student.getExaminationPaper());}}/*** 批评教育*/public void ReportCollection(List<String> names) {System.out.print("以下同学考试交头接耳,下课来办公室!");List<String> result = new ArrayList<>();Set set = new HashSet(); //新建一个HashSetset.addAll(names); //list里的所有东西放入set中 进行去重result.addAll(set); //把去重完的set重新放回list里for (String name : result) {System.out.print(name+",");}System.out.println("");}/*** 判卷*/public void MarkPapers() {List<ExaminationPaper> examinationPapers = this.examinationPapers;for (ExaminationPaper examinationPaper : examinationPapers) {Integer score = 0;String name = examinationPaper.getName();Map<String, String> topic = examinationPaper.getTopic();for (String key : topic.keySet()) {if ("A".equals(topic.get(key))) {score += 1;}}this.result.put(name, score);}}/*** 公布成绩*/public void AnnounceResults() {for (String key : this.result.keySet()) {System.out.println(key+"的成绩为"+this.result.get(key));}}
}
复现场景
- 首先先初始化10位学生
- 在学生中随机选一位学生作为班长
- 老师分发试卷,分发完成之后记录考试开始的时间
- 在五分钟的考试过程中(并发的考试过程),学生进行答题,会可能伴随作弊,交头接耳的行为;班长会随时查看并记录交头接耳的学生名单
- 考试结束之后,老师收卷
- 班长打小报告,老师批评教育交头接耳的学生
- 老师判卷,公布学生成绩
package com.common.test;import org.springframework.util.StringUtils;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.concurrent.ThreadLocalRandom;public class Test {public static void main(String[] args) {Student monitor = null;List<String> names = new ArrayList<>();List<String> blacklist = new ArrayList<>();List<Student> students = new ArrayList<>();for (int i = 0; i < 40; i++) {Student student = new Student();student.setName("学生" + i);students.add(student);}//班长任命ThreadLocalRandom random = ThreadLocalRandom.current();int num = random.nextInt(students.size());monitor = students.get(num);//老师发试卷Teacher teacher = new Teacher();for (int i = 0; i < students.size(); i++) {ExaminationPaper examinationPaper = teacher.DistributePapers();Student student = students.get(i);student.tianjuan(examinationPaper);}long time = new Date().getTime();//考试开始时间//答题while (new Date().getTime() - time <= 3000) {Integer number = 0;for (Student student : students) {Student finalMonitor = monitor;Thread thread = new Thread(new Runnable() {@Overridepublic void run() {//答题student.Answer();//作弊if (student.Cheat()) {blacklist.add(student.getName());}
// //答题完成,交卷
// if (student.HandPaper()) {
// number += 1;
// }//记录交头接耳的人名 ;班长打小报告if (student.Whisper() && !finalMonitor.equals(student.getName())) {names.add(student.getName());}}});thread.start();}if (number == 10) {break;}}if (!StringUtils.isEmpty(names)) {//打小报告的方法monitor.report(names);//批评教育teacher.ReportCollection(names);}teacher.CollectPapers(students);System.out.println("收卷完成,考试结束!");teacher.MarkPapers();teacher.AnnounceResults();}
}