广联达笔试 广联达秋招 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 春招笔试合集 文章被收录于专栏
2025打怪升级记录,大厂笔试合集 C++, Java, Python等多种语言做法集合指南
查看6道真题和解析