广联达笔试 广联达秋招 0916
笔试时间:2025年9月16日
往年笔试合集:
第一题:多线程外卖配送系统
你经营一家外卖餐厅,有3名骑手。系统需要:
- 接收订单(格式:订单号-地址-预计配送时间(分钟))
- 自动分配骑手(骑手ID: 1,2,3)
- 模拟配送过程(每单耗时:预计时间×1.1)
- 实时显示骑手状态(空闲/配送中)
要求:
- 使用3个骑手线程并行处理订单
- 订单按接收顺序处理
- 骑手完成配送后自动接新单
- 系统在收到"end"后完成剩余订单后关闭
输入描述
每行一个订单,格式为"订单号-地址-预计时间","end"结束。
输出描述
样例输入
A100-人民路15号-30
A101-中山公园南门-15
A102-科技大厦B座-25
A103-绿城花园8栋-20
end
样例输出
[A100]分配给骑手 1,预计 30 分钟
骑手状态:1-配送中,2-空闲,3-空闲
[A101]分配给骑手 2,预计 15 分钟
骑手状态:1-配送中,2-配送中,3-空闲
[A102]分配给骑手 3,预计 25 分钟
骑手状态:1-配送中,2-配送中,3-配送中
[A103]等待骑手..
[骑手 2]完成订单 A101! 实际耗时16.5分钟
骑手状态:1-配送中,2-空闲,3-配送中
[A103]分配给骑手 2,预计 20 分钟
骑手状态:1-配送中,2-配送中,3-配送中
[骑手 3]完成订单 A102! 实际耗时27.5分钟
骑手状态:1-配送中,2-配送中,3-空闲
[骑手 1]完成订单 A100! 实际耗时33.0分钟
骑手状态:1-空闲,2-配送中,3-空闲
[骑手 2]完成订单 A103! 实际耗时22.0分钟
骑手状态:1-空闲,2-空闲,3-空闲
参考题解
解题思路:
- 使用多线程模拟3个骑手并行处理订单
- 每个骑手有自己的任务队列
- 维护一个全局等待队列,保证订单按输入顺序分配
- 使用互斥锁和条件变量实现线程同步
- 实际配送时间 = 预计时间 × 1.1
C++:
#include <iostream> #include <functional> #include <thread> #include <mutex> #include <condition_variable> #include <queue> #include <chrono> #include <vector> #include <string> #include <memory> using namespace std; struct Order { string id; string addr; int expected; }; struct Rider { int id; queue<Order> q; mutex mtx; condition_variable cv; bool running = true; Rider(int i) : id(i) {} void addOrder(const Order& o) { { lock_guard<mutex> lock(mtx); q.push(o); } cv.notify_one(); } void stop() { running = false; cv.notify_one(); } void run(function<void(int, const Order&, double)> onFinish, function<void(int)> checkWaiting) { while (running || !q.empty()) { unique_lock<mutex> lock(mtx); cv.wait(lock, [&] { return !q.empty() || !running; }); if (!q.empty()) { Order o = q.front(); q.pop(); lock.unlock(); double actual = o.expected * 1.1; this_thread::sleep_for(chrono::milliseconds((int)(actual * 100))); onFinish(id, o, actual); checkWaiting(id); } } } }; struct RiderManager { vector<thread> threads; vector<shared_ptr<Rider>> riders; vector<bool> busy; queue<Order> waiting; mutex mtx; RiderManager() { for (int i = 1; i <= 3; i++) { auto r = make_shared<Rider>(i); riders.push_back(r); busy.push_back(false); } for (int i = 0; i < 3; i++) { threads.emplace_back([this, i]() { riders[i]->run( [this](int id, const Order& o, double actual) { this->onFinish(id, o, actual); }, [this](int id) { this->assignWaiting(id); } ); }); } } void shutdown() { for (auto& r : riders) r->stop(); for (auto& t : threads) t.join(); } void assign(const Order& o) { lock_guard<mutex> lock(mtx); int freeId = getFree(); if (freeId != -1) { busy[freeId - 1] = true; printf("[%s]分配给骑手 %d,预计 %d 分钟\n", o.id.c_str(), freeId, o.expected); printStatus(); riders[freeId - 1]->addOrder(o); } else { printf("[%s]等待骑手..\n", o.id.c_str()); waiting.push(o); } } void onFinish(int id, const Order& o, double actual) { lock_guard<mutex> lock(mtx); busy[id - 1] = false; printf("[骑手 %d]完成订单 %s! 实际耗时 %.1f分钟\n", id, o.id.c_str(), actual); printStatus(); } void assignWaiting(int id) { lock_guard<mutex> lock(mtx); if (!waiting.empty() && !busy[id - 1]) { Order o = waiting.front(); waiting.pop(); busy[id - 1] = true; printf("[%s]分配给骑手 %d,预计 %d 分钟\n", o.id.c_str(), id, o.expected); printStatus(); riders[id - 1]->addOrder(o); } } int getFree() { for (int i = 0; i < 3; i++) if (!busy[i]) return i + 1; return -1; } void printStatus() { printf("骑手状态:"); for (int i = 0; i < 3; i++) { printf("%d-%s", i + 1, busy[i] ? "配送中" : "空闲"); if (i != 2) printf(","); } printf("\n"); } }; int main() { ios::sync_with_stdio(false); cin.tie(nullptr); RiderManager rm; vector<Order> allOrders; string line; while (getline(cin, line)) { if (line == "end") break; if (line.empty()) continue; vector<string> parts; string tmp; for (auto c : line) { if (c == '-') { parts.push_back(tmp); tmp.clear(); } else tmp.push_back(c); } parts.push_back(tmp); allOrders.push_back({parts[0], parts[1], stoi(parts[2])}); } for (auto& o : allOrders) { rm.assign(o); } rm.shutdown(); return 0; }
Java:
import java.util.*; import java.util.concurrent.*; class Order { String id; String addr; int expected; Order(String id, String addr, int expected) { this.id = id; this.addr = addr; this.expected = expected; } } class Rider implements Runnable { private int id; private BlockingQueue<Order> queue = new LinkedBlockingQueue<>(); private volatile boolean running = true; private BiConsumer<Order, Double> onFinish; private Consumer<Integer> checkWaiting; Rider(int id, BiConsumer<Order, Double> onFinish, Consumer<Integer> checkWaiting) { this.id = id; this.onFinish = onFinish; this.checkWaiting = checkWaiting; } void addOrder(Order order) { queue.offer(order); } void stop() { running = false; } @Override public void run() { while (running || !queue.isEmpty()) { try { Order order = queue.poll(100, TimeUnit.MILLISECONDS); if (order != null) { double actual = order.expected * 1.1; Thread.sleep((long)(actual * 100)); onFinish.accept(order, actual); checkWaiting.accept(id); } } catch (InterruptedException e) { Thread.currentThread().interrupt(); break; } } } } class RiderManager { private List<Rider> riders = new ArrayList<>(); private List<Thread> threads = new ArrayList<>(); private boolean[] busy = new boolean[3]; private Queue<Order> waiting = new LinkedList<>(); private final Object lock = new Object(); RiderManager() { for (int i = 0; i < 3; i++) { final int riderId =
剩余60%内容,订阅专栏后可继续查看/也可单篇购买
2025打怪升级记录,大厂笔试合集 C++, Java, Python等多种语言做法集合指南