☰
广联达校招笔试复盘:Java基础与算法高频考点全解析
2026/10/28 1:18:41 网站建设 项目流程

2018年那会儿我还在学校跑招聘会,广联达的笔试算是我秋招里印象比较深的一场。这家公司做建筑信息化起家,造价软件在行业里覆盖率极高,笔试题目风格也带着明显的“工程思维”痕迹——不玩偏题怪题,考察的都是开发岗真正天天在用的东西。我当时考完出来,第一感觉是“稳”,第二感觉是“自己复习的方向全在点子上”。这篇文章就把当时考场上遇到的题型、解题思路、以及考前我整理的高频考点完整复盘一遍,给接下来准备广联达或者同类建筑软件公司开发岗的学弟学妹们做个参考。

你可以把它当作一份“笔试地图”来看。我会从命题风格讲起,再逐个科目拆解高频题型,每个题型都附上我自己总结的答题套路和踩坑记录。无论你是Java方向还是C++方向,这份内容对你的秋招笔试准备都会有实际帮助。

1. 广联达校招笔试题的命题风格与考点分布

1.1 整体印象:基础为王,范围广但深度可控

广联达的笔试题型通常分为客观题(单选、多选、判断)和主观题(简答、编程、设计类)两大部分。客观题覆盖面很广,Java/C++基础、数据结构、操作系统、计算机网络、数据库几乎都有涉及,但每道题的深度控制得比较克制,基本上“学过、复习过”就能答上来,不会像某些大厂那样拿极端冷门的知识点卡人。

主观题方面,编程题一般两到三道,难度阶梯很清晰:第一道是基础模拟题,第二道是经典算法题(链表、字符串、二叉树方向),第三道则偏向业务场景设计。整体来看,这套题透露出来的信号是:广联达在筛选“基本功扎实、能直接上手干活”的工程师,而不是海量刷过难题偏题的竞赛型选手。

1.2 考点权重分析

从我当时回忆加后来和同批笔试的同学对答案统计来看,各科目的大致占比是这样的:

考察科目客观题占比主观题占比高频考察点
Java/C++基础30%10%集合、String、并发、内存管理
数据结构与算法20%50%链表、二叉树、字符串处理
数据库15%10%SQL编写、索引原理、事务特性
计算机网络15%0%TCP握手、HTTP协议、网络模型
操作系统10%0%进程调度、死锁、Linux命令
逻辑与综合10%30%逻辑推理、场景设计、行为描述

这个分布很有代表性。数据结构和算法占比最大,因为这是区分候选人的核心标尺;Java基础紧随其后,考察你能不能写出健壮的代码;数据库和网络是日常开发的地基,属于基础素养考核。

1.3 为什么这个命题思路值得研究

广联达的产品体系里,造价软件有大量的表单计算、数据校验、批量处理逻辑,底层对Java和数据库的依赖非常大。笔试题里频繁出现的集合类题目、SQL查询题目,其实都是在模拟真实业务场景中你会遇到的操作。明白了这一点,你就知道备考重点应该放在哪——不是死磕红黑树的手写实现,而是把日常开发里最常用的API用熟、把原理吃透。

2. Java基础高频题精讲

2.1 集合框架:ArrayList和LinkedList的区别只是“一个数组一个链表”吗

这道题几乎年年出现,形式可能是简答,也可能是让你分析某个场景该选哪个集合。2018年广联达的卷子里出现的是选择题变体:下列哪项关于ArrayList和LinkedList的说法是错误的。选项里故意混淆了“增删快慢”的边界。

这里有个关键坑点:很多人只记住了“ArrayList增删慢、LinkedList增删快”,但这是不严谨的。LinkedList在指定位置插入需要先遍历到那个位置,时间复杂度O(n),而ArrayList在尾部添加时均摊时间复杂度是O(1)。所以真正的结论是:尾部追加用ArrayList更好,头部或中间大量插入用LinkedList更合适,但查询场景ArrayList完胜。

我当时在答题时额外补充了扩容机制的对比:ArrayList默认容量10,超过后按1.5倍扩容,每次扩容都涉及数组拷贝;LinkedList没有容量限制,每个节点有额外的内存开销存储前后指针。这种细节才是判卷人真正想看到的。

2.2 String、StringBuffer、StringBuilder三兄弟

笔试里出现的方式很直接:写出三者区别,并说明为什么String拼接受性能诟病。核心考点有三个层面。第一,String是不可变对象,每次拼接都会创建新对象,循环一万次就产生一万个中间对象;StringBuffer和StringBuilder是可变的字符序列,追加操作修改的是同一个对象。第二,StringBuffer的方法加了synchronized,线程安全但性能有损耗;StringBuilder是线程不安全的,但单线程环境下效率最高。第三,编译器对字符串常量拼接有优化,字面量加字面量在编译期就合并了,所以“a” + “b”不会产生额外对象。

我记得卷子里还问了一道String的intern方法,题目给的代码是String s1 = new String("abc"),问创建了几个对象。答案是两个,一个在堆上,一个在常量池里。intern方法的作用是把这个字符串加入常量池并返回常量池引用。这类题属于看着简单、容易丢分的细节题。

2.3 并发编程:volatile和synchronized到底解决什么问题

广联达并发方向的题目不算难,考的是基础概念辨析。volatile的两个核心语义要记牢:保证可见性、禁止指令重排序,但不保证原子性。synchronized则同时保证原子性和可见性。这里有个特别容易踩坑的点:很多人以为volatile能解决i++的并发问题,实际上不能,因为i++是“读-改-写”三步操作,volatile只保证了读和写的可见,中间的过程依然可能被线程穿插。

如果笔试考手写单例模式,你要能写出双重检查锁版本。关键点有两个:单例对象要用volatile修饰,防止指令重排序导致其他线程拿到未初始化完成的对象;加锁判断要分两层,外层减少加锁开销,内层保证实例唯一性。

3. 数据结构与算法题实战

3.1 链表反转:迭代和递归两种写法都要会

编程题第一题大概率是链表相关,反转单链表是出现频率最高的那个。我当时在卷子上写了迭代解法,核心思路是三个指针:pre记录前一个节点,cur记录当前节点,next暂存下一个节点。每次循环把cur.next指向前一个节点,然后三个指针整体后移,直到cur为空时返回pre。

迭代代码大概是这样的:

public ListNode reverseList(ListNode head) { ListNode pre = null; ListNode cur = head; while (cur != null) { ListNode next = cur.next; cur.next = pre; pre = cur; cur = next; } return pre; }

递归写法也建议准备一下。递归版本的核心公式是:reverse(head) = reverse(head.next) + 把head接到尾部。理解递归的关键在于不要尝试追踪每一层调用,而是相信“reverse(head.next)已经返回了一个反转好的链表”,你只需要把当前节点接上去。

链表题我最想提醒的一点是:一定要考虑边界条件,空链表、只有一个节点的链表、反转后头节点是否正确。笔试题不会给你编译器,代码必须一遍写对,所以平时要多练白板写代码,别总是依赖IDE的自动提示。

3.2 字符串处理:判断回文和字符统计

字符串类题目在笔试里属于“看起来简单、做起来容易翻车”的类型。回文判断要注意忽略大小写和非字母数字字符,Java里Character.isLetterOrDigit加上toLowerCase组合使用就行。字符统计类题目则要熟悉HashMap的getOrDefault方法,或者用长度为128的数组做字符计数,后者在纯字母数字场景下性能更好。

2018年的卷子有一道比较有意思的题目:给定一个字符串,找出最长无重复字符子串的长度。这道题在LeetCode上对应第3题,属于滑动窗口的经典应用。窗口右边不断扩展,遇到重复字符就把窗口左边收缩到重复位置的下一个字符,用HashMap记录每个字符最后出现的下标。

public int lengthOfLongestSubstring(String s) { HashMap<Character, Integer> map = new HashMap<>(); int left = 0, max = 0; for (int right = 0; right < s.length(); right++) { char c = s.charAt(right); if (map.containsKey(c)) { left = Math.max(left, map.get(c) + 1); } map.put(c, right); max = Math.max(max, right - left + 1); } return max; }

这个代码里的关键优化是left的更新用了Math.max,避免窗口指针回退。很多人写这题时直接用map.get(c) + 1赋值给left,遇到abba这种用例就出问题了——当遍历到第二个a时,map里存的a下标是0,如果直接把left更新为1,窗口就错误地包含了重复的b。

3.3 二叉树遍历:递归秒写,非递归才是分水岭

二叉树的前序、中序、后序遍历,递归写法是基础中的基础,笔试一般不会卡在这里。非递归写法才是拉开差距的地方。前序和中序的非递归可以通过栈模拟,后序的非递归最稳妥的做法是双栈法——第一个栈按“根右左”的顺序入栈出栈,把出栈节点压入第二个栈,最后第二个栈的弹出顺序就是“左右根”。

除了遍历,求二叉树深度和判断平衡二叉树也是高频题。判断平衡要求每个节点的左右子树高度差不超过1,这里有个性能优化点:不应该单独写一个求高度的函数然后逐节点调用,那样时间复杂度是O(n²)。正确做法是让递归函数在返回高度的同时判断是否平衡,一旦发现不平衡就提前返回-1。

3.4 逻辑思维题:别被花哨描述带偏

广联达笔试还会穿插几道逻辑推理题。我记得有一道是给了一堆条件判断某人的位置关系,还有一道是关于真假话的逻辑推导。这类题没有特定的数据结构考点,考察的是信息抽象和分情况讨论能力。

我的做题习惯是:用字母代替人物,用不等式或表格整理条件,把文字描述转换成符号逻辑。真假话题的核心是找矛盾关系——两个人说的话互为矛盾,那真话必然在这两句之间,其余人的话就可以直接判断真假了。逻辑题的价值在于快速筛选,遇到卡壳超过五分钟的建议先跳过,后面做完再回头整理。

4. 数据库与计算机网络题型拆解

4.1 SQL编写题:分组统计永远比想象中容易丢分

数据库方向的主观题一般是给两张或三张表,要求写出查询语句。广联达的题目场景贴合业务需求,比如查询各项目中造价金额最大的前三条记录这类。

写SQL有几个容易扣分的细节:第一,GROUP BY之后如果SELECT里有非聚合列,那这个列必须包含在GROUP BY中,MySQL的ONLY_FULL_GROUP_BY模式开启时会直接报错;第二,HAVING和WHERE的区别要搞清楚,WHERE是分组前过滤,HAVING是分组后过滤;第三,取分组前N条的题目要用窗口函数ROW_NUMBER() OVER(PARTITION BY 分组列 ORDER BY 排序列 DESC),别再用衍生表做关联了,代码复杂还不容易写对。

窗口函数的写法参考:

SELECT 项目名称, 造价, 排名 FROM ( SELECT 项目名称, 造价, ROW_NUMBER() OVER(PARTITION BY 项目名称 ORDER BY 造价 DESC) AS 排名 FROM 造价表 ) t WHERE 排名 <= 3;

笔试时如果不确定窗口函数能不能用,可以写上并附一段注释说明思路,判卷人对思路清晰的解法通常会宽容一些。

4.2 索引原理:为什么MySQL选B+树而不是B树

索引类的选择题考法很多,核心是考察你对B+树的理解。B+树和B树的区别是:B+树的非叶子节点只存索引不存数据,数据全部落在叶子节点,且叶子节点之间用双向链表连接。这个设计带来的直接优势是查询更稳定——任何查找都要走到叶子节点,路径长度一致;范围查询更高效——找到起点后沿着叶子的链表顺序遍历即可,不用回溯到父节点再出发。

另一个高频点是联合索引的最左前缀原则。如果建立了一个(a, b, c)的联合索引,那么查询条件里只有b和c的时候索引是不生效的,只有包含a才能命中。这个原则在笔试答题时一定要详细展开,因为很多候选人只知道“最左匹配”四个字,却说不清楚底层原因——B+树的索引结构是按索引列的顺序逐层比较的,缺失了最左列,比较器就失去了判定依据。

4.3 事务ACID和隔离级别

数据库事务相关的题目我那年碰到的是多选题,问哪些操作可能引发脏读。答案是在Read Uncommitted隔离级别下,一个事务读取了另一个未提交事务的修改。这里要背清楚四个隔离级别能解决的问题:Read Uncommitted什么都不防,Read Committed防脏读,Repeatable Read防脏读加不可重复读,Serializable全部防住。MySQL的默认隔离级别是Repeatable Read,这个知识点是必考点。

MVCC(多版本并发控制)如果笔试考到,不用往深了说,但要能讲清核心思想——通过数据行的多个版本来实现读写不互相阻塞,读操作读取快照版本,写操作创建新版本。能把这个逻辑说清楚,在同类候选人里已经属于加分项了。

4.4 计算机网络:三次握手为什么不是两次或四次

网络方向的客观题集中在TCP协议。三次握手必须理解到位,而且要知道为什么必须是三次。第一次握手客户端发送SYN,第二次服务端回复SYN+ACK,第三次客户端再发ACK。第二次和第三次合在一起,本质上是让双方都确认“我能发你也能收”这一双向链路的建立。

如果只有两次握手,可能出现的问题是:客户端第一次SYN因为网络阻塞超时重传,服务端收到重传请求后回复SYN+ACK,此时旧的SYN也到达了,服务端又会回复一次。客户端的ACK已经完成,就会主动发起RST断开连接,但服务端在没有第三次握手的情况下无法区分这个SYN是旧的还是新的,白白建立了一个无效连接。三次握手通过客户端最后一次ACK让服务端确认“这个客户端确实在线且能收消息”。

HTTP协议方面,考GET和POST的区别、状态码含义、Cookie和Session的区别。这些题属于送分题,但注意要写得有层次感——从语义定位说到请求体区别,再到幂等性,最后补充安全层面的差异。

5. 开放题与编程设计题的答题策略

5.1 场景设计题:从“能跑”到“会设计”

编程题如果出现设计类题目,通常不会要求完整实现一个大系统,而是给你一个具体场景,让你设计核心模块。我们那年的题目大概是设计一个简版的造价数据批量导入功能,需要考虑数据量级、字段校验、失败重试等环节。

这类题的答题思路是:先明确输入输出,再拆分处理流程,最后关注异常边界。我当时按这个结构写的:接收Excel文件,逐行解析并做格式校验,校验通过的数据批量写入数据库,失败的行记录日志并返回错误信息。批量插入要说明用batch操作减少数据库连接开销,校验逻辑要提到区分必填项校验和格式校验,重试机制要说明是整体重试还是失败行单独重试,以及幂等性怎么保证。

这种设计类题目不追求你写得跟生产代码一样完美,而是考察你有没有工程思维——是否考虑过边界条件、失败场景和性能瓶颈。答题时先画流程再写关键代码片段,效果远好于直接糊一整段逻辑混乱的代码。

5.2 编程题的时间分配和做题顺序

编程题在笔试中的分值占比很高,我的建议是先整体扫一遍三道题,按难度高低排序再逐个击破。第一道模拟题通常10分钟左右能完成,先把它写出来保证基础分到手;第二道经典算法题控制在20分钟以内,如果卡住了先写暴力解法兜底;第三道设计题留20到30分钟,因为是开放性的,写完整流程比抠细节更重要。

不要在一道题上死磕超过30分钟。笔试现场的时间管理决定了你能拿到的分数上限,先把会做的题全部做完,再回头研究难题,这个策略在大多数公司的笔试里都适用。

5.3 手写代码的完整性检查清单

笔试不给编译器,代码写完就是直接交,所以平时要有意识地练习“一遍过”的能力。我总结了一个手写代码的完整性检查清单:检查完边界条件,空输入、极端输入、单个元素;检查完中间变量的初始化,特别是在循环之前的变量声明;检查完循环条件的方向,是小于还是小于等于,是加一还是减一;检查完返回值在所有分支都有返回,不是只能在一个分支上return;最后在脑海里模拟一遍流程,尤其注意数组下标会不会越界。

这些检查看起来琐碎,但考场上的大部分失分都不是思路问题,而是代码细节问题。一个小括号写错位置、一个等号写成赋值,整道题可能就前功尽弃了。

6. 非技术题目与笔试之外的加分项

6.1 性格测试和职业规划题怎么答

广联达的那套题里还有一部分非技术题,主要考察沟通表达、团队协作和职业规划。这些题没有标准答案,但可以表达出自己的技术热情和稳定性倾向。比如问到“你如何看待加班”,与其回答“接受加班”,不如说“我会先提高工作效率减少无效加班,关键项目需要冲刺时也能接受弹性安排”,这样既展现了主动性又体现了抗压能力。

职业规划题不要空谈“我想成为架构师”,最好结合公司业务来说,比如“希望在建筑信息化领域深耕,把造价数据处理的底层性能做到极致”,这样会让HR觉得你做过功课、有明确的方向感,又和公司业务绑定了。

6.2 笔试后的复盘比笔试本身更重要

笔试结束后,我习惯把没把握的题目标记下来,当天晚上就对答案复盘。有些知识点在笔试时模糊、后来搞清楚,这类知识的记忆深度远高于平时看书预习的。比如我那次有一道关于HashMap扩容后元素迁移的题没完全答对,回来仔细推演了一遍扩容过程,从此再没忘记过。

7. 备考时间安排与资料推荐

7.1 倒计时两周怎么分配

如果你离广联达笔试还有两周时间,我的建议是前一周以刷题为主,LeetCode按标签刷——链表、字符串、二叉树、哈希表各刷20题,重点整理出通用解法模板;后一周以基础知识背诵为主,把Java集合、并发、JVM、数据库事务、TCP协议这些高频考点过一遍,每天固定时间做一套完整模拟卷,训练手写代码的节奏感。

7.2 值得反复研读的资料清单

经典教材方面,《Java编程思想》的集合章节和《深入理解Java虚拟机》的运行时数据区一定要吃透;算法方面用LeetCode的题库就够了,不要贪多;数据库方面可以看《高性能MySQL》前几章,特别是索引和事务部分;网络方面,把TCP/IP协议栈的三次握手、四次挥手和HTTP状态码整理成自己的笔记,考前反复过。

7.3 刷题时的关键习惯

我在备考最后两周形成的习惯是:每道题先自己思考15分钟写一版代码,再对照参考解法,找出自己思路的盲点,最后在笔记本上画一幅简单的思路图。这三个步骤缺一不可。只看不写等于白看,只写不总结等于白写。算法题的本质是模式识别,做得多了,看到链表就想到双指针,看到字符串就想到滑动窗口,这种直觉必须在刷题量达到一定水平后才会出现。

需要专业的网站建设服务?

联系我们获取免费的网站建设咨询和方案报价,让我们帮助您实现业务目标

立即咨询