☰
恒生金融IT笔试复盘:Java基础、SQL查询与数据结构全解析
2026/10/24 13:13:29 网站建设 项目流程

2015年秋招的时候,我投了恒生的Java开发岗。说实话,金融IT公司里,恒生的笔试算是比较有代表性的——它不像互联网大厂那样狂刷难题,也不像纯外包公司那样随便出点选择题糊弄人,而是把Java基础、数据结构、数据库SQL、逻辑思维四块内容按很均衡的比例拼在一起,整体考察风格偏务实。这套开发类笔试题(三)我记得是综合卷的第三部分,题量不算小,难度梯度拉得也挺明显。今天把它完整复盘一遍,顺便聊聊金融IT方向校招笔试的备考思路。如果你是准备走金融IT方向开发岗的应届生,或者单纯想看看这类公司笔试怎么出题,这篇文章值得你花十分钟读一下。

1. 出题逻辑复盘:金融IT笔试到底在筛什么样的人

1.1 为什么Java和SQL占了半壁江山

先说结论:恒生这类金融IT公司的笔试,核心考察点永远是“业务落地能力”而不是“算法炫技”。它做的系统是什么?证券交易、基金TA、银行核心账务、风控清算——每一个都是高并发、强一致、事务密集的场景。这种业务背景决定了技术栈必须稳,Java在金融IT领域扎根深,关系型数据库(Oracle/MySQL)更是绝对主力,所以笔试题里Java语言特性和SQL就是重头戏。

这一点跟互联网大厂的笔试风格差异很大。大厂喜欢考动态规划、图论、线段树这些偏算法竞赛的内容,考察的是抽象建模能力和思维上限;金融IT的笔试题更愿意花篇幅去问Java集合的底层实现、异常处理细节、SQL语句的正确写法。不是因为它不需要算法能力,而是它更看重你写出来的代码能不能在真实业务系统里落地、扛得住账务核对和极端数据量。

我当时判断这套题的思路是这样:凡是能进到这类公司的笔试,基本默认你不是零基础,所以选择题里一定会埋一些“看起来会、实则容易错”的Java坑点;同时SQL题一定会给足分数,因为金融业务里报表统计、流水查询、数据核对全是SQL活。把这个逻辑想清楚,后面复习的方向自然就清晰了。

1.2 这套卷子的题型分布和整体节奏

按照当时的考试印象,这套开发类笔试题(三)大致分成了四个板块:选择题、程序阅读题、编程题、SQL题。选择题覆盖了Java基础、数据结构和操作系统基础知识,大概占30%左右的比重;程序阅读题给一段代码让你写出输出结果,主要考Java内存模型、String的特性、集合操作这些细节;编程题是手写代码,链表和字符串处理出现的频率最高;SQL题通常放在最后,但分值占比不低。

整个笔试时间大概两个小时,节奏其实蛮紧的。选择题如果犹豫太久,后面的编程题就会非常赶。我的经验是:选择题平均每题不超过一分钟,遇到拿不准的就先凭第一印象标一个,最后有时间再回头纠结;程序阅读题要仔细,因为输出格式差一个字符都算错;编程题优先做自己有把握的,宁可写得简单正确,也不要为了秀操作写一个自己都调试不明白的复杂解法。

这套题的难度梯度其实很合理:基础题覆盖大多数认真准备过的人,中档题拉开差距,最后有一两道稍微带点弯的题去筛出真正基础扎实的人。所以复盘这套题,真正有用的不是找出“标准答案”,而是理解每道题背后的考察意图。

2. 核心考点逐个拆解:从语言细节到数据结构和数据库

2.1 Java集合与多线程:最容易被选择题“阴”到的点

Java这块是选择题的重灾区,原因在于Java的知识点太碎了。笔试里反复出现的基本就是这几个点:final、finally、finalize三兄弟的区别;String、StringBuilder、StringBuffer的差异;HashMap底层结构在不同JDK版本中的变化;ArrayList和LinkedList分别在什么场景下用;异常处理里的checked exception和runtime exception。

以HashMap为例,这道题几乎年年出现。2015年那个时间点,JDK 7和JDK 8都有人用,所以HashMap的底层实现其实是分版本的:JDK 7是数组加链表,JDK 8变成了数组加链表加红黑树。笔试如果问“HashMap在什么情况下链表会转红黑树”,答案不是“元素超过8个”这么简单,而是“链表长度达到8且数组长度达到64”。这个细节我曾经以为自己会,结果真到笔试就懵了。所以我的建议是:复习Java集合的时候,不要只看“能用”,要顺着源码把“为什么这样设计”搞清楚。

多线程那边常考的是synchronized和volatile的区别、Thread和Runnable的关系、线程池的参数含义。这些内容在金融IT的业务系统里确实用得上,因为交易系统本身就是典型的多线程并发场景。笔试不会让你写一个完整的生产者消费者模型,但选择题里会问“volatile能否保证原子性”“synchronized锁的是对象还是方法”这类基础判断题。这类题目没什么技巧,就是靠平时积累。我当时是把《Java并发编程实战》的前几章快速过了一遍,重点记了synchronized锁升级、volatile的可见性、ThreadLocal的使用场景,基本够用。

2.2 数据结构与算法:考的是基础牢不牢,不是会不会难题

算法题在这套笔试卷子里占的分量不算最重,但几乎必有。考察范围集中在链表、栈、队列、二叉树、字符串、排序查找。说实话,这些内容在计算机专业课里都是最基础的部分,但笔试现场手写代码就是另一回事了。链表反转、二分查找、快速排序、二叉树前中后序遍历,这几道题是出现频率最高的“熟面孔”。

我个人的判断是:金融IT笔试的算法题目的不是考你有多聪明,而是考你“基础到底有没有打扎实”。一个平时认真写过代码的人,链表反转这种题应该在三五分钟内写得干净利落;如果连链表反转都要想半天,说明代码量积累不够,面试官自然会怀疑你的工程能力。所以在准备这类笔试的时候,我建议把LeetCode上easy和medium里关于链表、树、字符串的题目刷一遍,重点不是题量,而是把每种经典解法写到闭着眼都能默写的程度。

说到排序,快排几乎是必背内容。当时笔试有一道题是手写快速排序并分析时间复杂度,我建议写的时候把partition函数抽出来,代码结构清晰一点,容易得分。其实面试官看的不仅仅是结果对不对,还会留意你的编码习惯——缩进是否规范、变量命名是否清晰、代码里有没有充分的注释。这些细节在笔试里虽然不直接加分,但主观题改卷的时候一定会影响印象分。

2.3 SQL查询:金融IT笔试的隐藏大头

很多应届生容易忽略SQL,因为在学校里SQL课上得少,或者写了几个简单的select就以为自己会了。但金融IT笔试绝对不是这样,SQL题的分值占比经常会超出你的预期。因为金融IT系统每天产生的核心数据就是大量结构化的交易流水、账户信息、客户资料,所有统计报表和业务核对都要靠SQL来查。所以笔试题里基本必考多表连接、聚合函数、分组统计、子查询和排序分页。

拿我当时复习的经验来说,SQL的优先级要提到和算法同样高的位置。笔试不会出那种背教科书上的基础语法题,而是给你两张表、三张表,让你写一个实际业务场景的查询。比如查“每个部门工资最高的员工”“近一个月累计交易金额超过一定阈值的客户”“按产品分组统计平均收益再筛选排序”。这类题目看着不难,但实际写到纸上,很多人会在GROUP BY和HAVING的组合上卡住,或者漏掉空值处理。

复盘这套题里的SQL部分,我最大的感受是:SQL写不对的原因往往不是语法不会,而是没有理解SQL的执行顺序。FROM先加载表,然后WHERE过滤行,再GROUP BY分组,接着HAVING过滤组,SELECT投影列,最后ORDER BY排序——这个逻辑顺序搞清楚,很多题目就能迎刃而解。这个点我后面会结合具体题例再细讲。

3. 按真题思路复盘:三道代表性题目的完整解题过程

3.1 链表反转:迭代和递归两个版本怎么选

链表反转是这套笔试里很典型的编程题。题目通常是这样:给定一个单向链表,将其反转,返回反转后的头节点。这个题目看起来简单,但现场手写的时候,很多人会栽在指针操作顺序上。我先给出迭代版本,这是笔试时最推荐写的版本,代码简单、不容易错,而且空间复杂度是O(1)。

class ListNode { int val; ListNode next; ListNode(int x) { val = x; } } public ListNode reverseList(ListNode head) { ListNode prev = null; ListNode curr = head; while (curr != null) { ListNode nextTemp = curr.next; // 先保存下一个节点 curr.next = prev; // 当前节点指向前一个节点 prev = curr; // 前一个节点移动到当前 curr = nextTemp; // 当前节点移动到下一个 } return prev; // 最后prev就是反转后的头节点 }

为什么循环里第一件事就是保存nextTemp?因为当执行curr.next = prev这一步后,当前节点的next指针就变了,如果没有提前把原来的下一个节点存下来,后面的节点就丢失了。这个“先保存、再修改、后移动”三步法是链表操作的核心思路。笔试里只要把这三步写清楚,链表反转基本就拿到分了。

递归版本其实更“优雅”一点,思路是递归地把子链反转,然后把当前节点的next的next指向自己,再把当前节点的next置空:

public ListNode reverseListRecursive(ListNode head) { if (head == null || head.next == null) { return head; } ListNode newHead = reverseListRecursive(head.next); head.next.next = head; head.next = null; return newHead; }

这段代码看着漂亮,但笔试现场我不推荐写递归。原因有两个:一是递归的终止条件容易写漏,一旦最后一个节点的null处理不对,栈就会溢出;二是面试官改卷时还要帮你推理递归过程,不如迭代版本直观。所以笔试里能写迭代就写迭代,能写简单的就不要炫技——这个原则在后面的编程题里同样适用。

3.2 多表关联+分组聚合:一道典型SQL的完整推演

SQL题我记得是给出了三张表,大概结构是这样:

  • student表:sid(学生ID)、sname(姓名)、class_id(班级ID)
  • course表:cid(课程ID)、cname(课程名称)
  • score表:sid(学生ID)、cid(课程ID)、grade(成绩)

题目要求:查询每门课程平均分不低于85分的课程编号和课程名称,按平均分从高到低排序。

这是一道非常典型的多表关联加分组聚合题。第一步先把表关联起来,第二步按课程分组算平均分,第三步筛选平均分满足条件的组,第四步排序。我当时的写法是这样:

SELECT c.cid, c.cname, AVG(s.grade) AS avg_grade FROM course c JOIN score s ON c.cid = s.cid GROUP BY c.cid, c.cname HAVING AVG(s.grade) >= 85 ORDER BY avg_grade DESC;

这里的关键点在于HAVING和WHERE的区别。WHERE是在分组之前过滤行,而HAVING是在分组之后过滤组。如果要筛“平均分大于等于85”这个条件,它作用的对象已经是聚合后的组了,所以必须用HAVING,不能用WHERE。这个点几乎每一年都会有人搞混,属于笔试里最典型的丢分项。

还有一点要注意的是GROUP BY的字段。SELECT里出现的非聚合列,必须全部出现在GROUP BY中。写成GROUP BY c.cid其实是不严谨的,因为c.cname不在里面,虽然MySQL的默认配置下可能不会报错,但放到Oracle或者严格的SQL模式下就会直接报错。金融IT公司后端大量用Oracle,所以笔试题默认你是按标准SQL来写的。做题的时候最好养成分组字段写全的习惯,不然即使结果对了,也可能被扣规范分。

如果再往深了展开,这道题还可以用子查询来解:

SELECT c.cid, c.cname, sub.avg_grade FROM course c JOIN ( SELECT cid, AVG(grade) AS avg_grade FROM score GROUP BY cid HAVING AVG(grade) >= 85 ) sub ON c.cid = sub.cid ORDER BY sub.avg_grade DESC;

这种写法把聚合操作放到子查询里,外层再关联课程表拿课程名称,逻辑上更清晰。但笔试时间有限,我建议用第一种JOIN加GROUP BY直写,代码量少,不容易出错。搞明白这一道题,类似“每个班级平均分最高的学生”“每个部门工资最高的员工”这类变体题就都会做了。

3.3 字符串处理:回文判断里的边界值陷阱

字符串题目在这套卷子里也出现过,其中一道是判断字符串是否为回文串,允许忽略大小写和非字母数字字符。光看这个题很简单,但坑点全在边界处理上。比如字符串为空怎么处理?只有空格怎么处理?大小写不一致怎么办?包含标点符号怎么办?

我当时的解题思路是使用双指针,一个从左往右,一个从右往左,跳过非字母数字字符,统一转成小写再比较。核心代码如下:

public boolean isPalindrome(String s) { if (s == null) { return true; } int left = 0; int right = s.length() - 1; while (left < right) { while (left < right && !Character.isLetterOrDigit(s.charAt(left))) { left++; } while (left < right && !Character.isLetterOrDigit(s.charAt(right))) { right--; } if (Character.toLowerCase(s.charAt(left)) != Character.toLowerCase(s.charAt(right))) { return false; } left++; right--; } return true; }

第一个要注意的点是s == null的判断。虽然题目一般不会给null,但笔试现场多写一个判空不会错,反而能体现你的代码防御性。第二个点是内层while循环里一定要加上left < right这个条件,否则如果字符串全是非法字符,left会一路加出数组边界,产生越界异常。第三个点是Character.isLetterOrDigit这个方法,它完美地解决了跳过空格和标点的问题,不需要自己手动维护一个“合法字符集合”。

为什么字符串题在金融IT笔试里出现频率高?因为金融系统里大量处理报文、协议、指令数据,字符串的解析和校验是日常开发最基本的能力。这道题的逻辑本身不难,但它能看出一个人写代码时是不是把各种边界情况都考虑全了——这恰恰是金融IT开发最看重的工程素养。

4. 考场应对:时间分配、答题顺序和踩坑记录

4.1 选择题的判断和取舍策略

选择题做得顺不顺,直接影响后面做题的心态。我的经验是拿到卷子先花半分钟扫一遍全部题目,心里对题量有个底,再开始逐题做。选择题遇到完全不会的,不要在一道题上纠结超过两分钟,先按直觉选一个,在题号上做个标记,等做完后面的大题再回头想。

多选题要特别小心。很多试卷的多选题规则是“少选得部分分、多选错选不得分”,这种情况下策略就很清晰:不确定的选项不要选,只选自己有把握的。比如一道多选题问Java中哪些类是线程安全的,如果你只确定Hashtable是线程安全,那就只选它,宁可得一半分也不要因为多选一个Vector结果整道题零分。这个策略是我考了多场笔试后总结出来的,对提高总分非常有效。

还有一个细节是注意题干里的否定词。Java里“下面哪个说法是错误的”“哪个关键字不能用于异常处理”,这些否定词特别容易被看漏。我当时有个习惯,读到“错误”“不能”“不属于”这些词的时候,拿笔在纸上圈出来,算是给自己一个强制提醒。

4.2 编程题在纸上怎么调试最稳

笔试是手写代码,没有编译器,没有报错提示,所以“纸上调试”能力就成了一个很关键的技能。我的习惯是,拿到编程题先不要急着写码,先在草稿纸上画一个简单的输入样例,然后用大脑模拟一遍代码执行的流程。比如链表反转题,先画三个节点的链表,然后一步步执行循环,把prev、curr、nextTemp的变化写下来,每一步都确定没问题了再落笔写正式答案。

这里分享一个我练出来的习惯:写代码之前,先写注释、再写函数签名、再写主体逻辑。函数签名写对了,返回值类型和参数类型就不会错;注释把思路描述清楚了,后面的代码即使在细节上有所疏漏,改卷老师也看得懂你的意图。如果时间充裕,我会在代码末尾补一小段测试样例的描述,比如“输入1->2->3,输出3->2->1”,这算是给改卷人一个明确的验证路径。

边界条件永远是编程题最大的坑。判空、判数组长度为零、判断是否溢出——这些在计算机里写代码很容易处理,但在纸上经常被忽略。我在笔试中吃过一次亏:写二分查找的时候没考虑数组为空的情况,白白丢了一部分分数。从那以后,我养成了“写任何循环之前先想循环会不会越界”的习惯。

4.3 考场上几个容易让整张卷子崩掉的动作

第一个崩点:死在第一道难题上。笔试一开始,如果第一道选择题就比较难,纠结时间一长,整个节奏就乱了。我的做法是遇到卡壳题直接跳过,先把能拿的分拿稳,回头再来收拾残局。记住笔试的目标不是“满分”,而是在有限时间内“拿到尽可能多的分”。

第二个崩点:代码写到一半发现思路错了,把整页划掉重写。这样不仅浪费时间,还容易让卷面变得乱七八糟。解决方法是写代码前先想清楚算法骨架,最好能在草稿纸上先把大致逻辑写一遍,再抄到正式答题区。如果写到一半真的发现思路错了,不要整段划掉,用箭头或序号把新的逻辑补在旁边,至少让改卷人能看到你的思考过程。

第三个崩点:SQL题没有看清表结构就开写。SQL题的表名、字段名、类型、主外键关系都在题目描述里,有时候还会存在同名字段,比如student表里有sid,score表里也有sid,直接写select sid就会产生歧义。我见过不少同学因为没加表别名导致SQL报错。所以写SQL之前,先把表结构抄到草稿纸上,标出关联字段,再动手写语句,准确率会高很多。

5. 复盘之后:针对金融IT校招准备的几条建议

5.1 按优先级拉一张备考清单

复盘完这套题,我按优先级拉了一张考前准备清单。如果时间有限,建议按以下顺序分配精力:

优先级知识点准备建议
高Java集合框架HashMap、ArrayList、LinkedList源码通读一遍,重点关注底层结构和扩容机制
高SQL多表查询每天动手写5道JOIN+GROUP BY题目,理解执行顺序
高链表和字符串算法LeetCode easy/medium刷50道左右,重点练反转、合并、去重、回文
中Java多线程与异常掌握synchronized、volatile、线程池核心参数,以及异常处理流程
中操作系统基础进程线程区别、死锁条件、内存管理基础概念
低设计模式单例、工厂、观察者等高频模式,了解应用场景即可

之所以把Java集合和SQL排在最前面,是因为它们出题频率最高、实用性最强,而且短期内通过强化训练提升效果最明显。算法题虽然重要,但短期内想从“会”到“熟练”需要大量时间,所以排在第三优先级。操作系统和网络这类知识,选择题里可能会遇到,但占比不高,不用花太多时间背大而全的概念。

5.2 我踩过的坑,你尽量别踩

说来惭愧,我第一次参加这种金融IT笔试的时候,就栽在SQL上。当时只觉得算法题难,把大量时间花在刷链表和二叉树上,结果到了考场上,SQL题一道都不会做。什么GROUP BY、HAVING、子查询,平时写过但完全不熟练,一紧张连表关联都写错,最后那道大分值SQL题基本白卷。痛定思痛之后,我才开始重视SQL专项训练。所以你们现在准备笔试,一定要反过来,把SQL放在和算法同等重要的位置,甚至还要再高一点。

另一个坑是光看不练。很多人复习Java集合,把源码分析文章翻了一遍又一遍,觉得“这下总该会了吧”,结果笔试考到“HashMap什么时候会转为红黑树”,还是答不全。原因很简单,阅读输入和主动输出是两种完全不同的能力。我后来的做法是,每看完一个知识点,就闭上眼睛默想一遍,如果能把关键点复述出来,才算真正掌握。Java的话术类题目,可以在本子上默写几遍,确保考场上能顺畅写出来。

还有一个容易被忽略的点:手写代码的熟练度。平时在IDE里写代码,有自动补全,有编译报错提示,写起来非常顺畅;但在笔试纸上,没有这些辅助工具,拼写错误、分号漏写、花括号不配对都是常事。我的建议是在考前做一些“纸上编程”练习——打开一个空白的文本编辑器,关闭所有语法高亮和自动补全,把一些经典题的代码完整敲出来,这个过程能模拟笔试的真实状态,非常有效。

复盘完这套题,我最大的感受是金融IT方向的笔试不追求题目的“高精尖”,而是特别看重基本功的熟练度。Java集合、SQL查询、链表和字符串处理,这些在很多人眼里属于“太基础了不值得花精力”的内容,恰恰是这类笔试拉开差距的地方。准备的时候不用总想着去碰那些难题压轴题,把基础题做稳做对,就已经超过了大多数人。最后再分享一个小技巧:笔试现场发下来草稿纸后,先把SQL执行顺序和链表反转的三步法列在纸上,算是一个“外部记忆”的兜底方案,真遇到紧张卡壳的时候,瞄一眼就能迅速找回思路。

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

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

立即咨询