广联达笔试 广联达秋招 0916

笔试时间:2025年9月16日

往年笔试合集:

2023春招秋招笔试合集

2024春招秋招笔试合集

第一题:多线程外卖配送系统

你经营一家外卖餐厅,有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等多种语言做法集合指南

    全部评论

    相关推荐

    评论
    点赞
    收藏
    分享

    创作者周榜

    更多
    牛客网
    牛客网在线编程
    牛客网题解
    牛客企业服务