ARTICLE DETAIL

资讯详情

深耕网站视觉设计与运营推广的一线实战洞察。

恒生开发岗笔试第七卷解析:Java、C/C++、数据库与算法考点全梳理

恒生开发岗笔试第七卷解析:Java、C/C++、数据库与算法考点全梳理 恒生公司做金融IT的应该都不陌生证券、基金、银行这些机构的核心交易系统背后经常有它的影子。2015年秋招那会儿开发类岗位的笔试是线上统考题量不小、覆盖面很广、时间又卡得紧。我翻到这套第七卷的题目时第一反应是难度不算变态但坑非常多——Java基础、C/C、数据结构、数据库、Linux几乎全考了一遍。如果你正准备金融科技方向或者传统IT开发岗的秋招笔试这套题很值得认真刷一遍因为它很典型地代表了“大厂开发岗基础能力笔试”的出题思路不考偏题怪题专考你平时最容易忽略的细节。我打算把这张卷子的考点按板块拆开从Java基础、数组与指针到Linux命令、数据库、数据结构和算法小题每个部分都讲讲真题还原、背后的原理、容易踩的坑最后再分享一些我在刷题过程中的排查心得。1. 整套试卷的出题逻辑和答题策略1.1 恒生开发岗笔试到底想考察什么很多同学拿到这种综合卷子就慌觉得知识点太杂。其实你反过来想对方在短时间内要筛选出适合做金融系统开发的人最看重的就三件事第一语言基本功扎不扎实第二常见数据结构算法能不能写对第三Linux和数据库这些工程技能有没有上手经验。金融系统对稳定性要求极高代码里一个数组越界、一个空指针、一个事务没提交都可能造成线上事故所以笔试里反复出现的也就是这些东西。这套第七卷的题型分布也很明显选择题占了将近一半考概念和细节填空题补少量语法点两道简答题问数据库事务和进程通信最后一道编程题是数组操作的变体。整套题没有超纲内容但只要你某个基础点没吃透做起来就会反复卡壳。1.2 答题时我在心里预估的时间分配我个人的经验是选择题每道控制在1分半以内不会的先跳过千万不要在一道题上死磕。简答题留出15到20分钟因为需要写清楚原理。最后一题编程题至少留25分钟不光要把代码写出来还要自己在本子上过一遍边界条件。试卷整体的阅读量不小题目序号排到六十多道如果前面磨蹭太久后面代码题基本没时间写丢分会非常惨。2. Java基础题看似送分实际全是细节2.1 构造函数与初始化顺序的经典考法这套卷子有关键的几道Java选择题都是围绕构造和初始化展开的。比如有一个例子父类和子类都有静态代码块和构造方法问创建子类对象时输出顺序是什么。很多人凭记忆背结论但没理解为什么换一种问法就懵了。其实顺序就一句话父类静态代码块 → 子类静态代码块 → 父类普通代码块 → 父类构造方法 → 子类普通代码块 → 子类构造方法。静态代码块只在类加载时执行一次实例代码块在每次new的时候都会执行。我当年做题时直接写过一个小Demo验证这里建议你也写一遍比死记硬背有效得多class Parent { static { System.out.println(parent static); } { System.out.println(parent instance); } public Parent() { System.out.println(parent constructor); } } class Child extends Parent { static { System.out.println(child static); } { System.out.println(child instance); } public Child() { System.out.println(child constructor); } } public class Main { public static void main(String[] args) { new Child(); } }执行结果就是按照上面说的顺序。把这段代码亲手跑一遍以后遇到变形题也能一眼看穿。2.2 继承、重载与重写的坑继承和重载是Java选择题里的常客。这套题里有一道是问父类有一个方法public void foo(String s)子类里定义public void foo(Object o)这算不算重写很多新手会犹豫。答案是这不算重写因为参数列表不同这属于重载。重写要求方法名、参数列表、返回值类型完全一致访问修饰符不能更严格。还有一个容易被忽略的点是重写的“返回值类型可以变窄”。比如父类返回Object子类重写时可以返回String这是协变返回类型合法。但如果父类方法是private的子类写一个同名同参的方法就不算重写那只是子类自己的新方法因为private方法在父类中不可见。这些细节笔试里特别爱考因为很多人都是“看着眼熟选的时候犹豫”。2.3 finally块的一票否决制有一道题很典型方法里try块中写了return 1finally块中写return 2问返回值是多少。答案是2因为finally块的return会覆盖try块的return。但更阴险的考法是try块里return之前finally里只修改变量但不写return。比如public static int test() { int x 1; try { return x; } finally { x 2; } }这种情况返回值还是1因为return语句在返回前已经把x的当前值1保存下来了finally里改变x不会影响已经确定好的返回值。这里的关键是“基本类型返回值传值对象引用返回值传引用”如果finally里修改的是对象内容那么返回的对象状态就会受影响。这套卷子里就有一道对象版本的变形题不仔细想真容易错。3. 数组与指针C语言考点里的重灾区3.1 数组名和指针到底有什么区别试卷里有一道C语言题int a[5]; int *p a;问sizeof(a)和sizeof(p)各是多少。很多人只记住了“数组名就是指针”结果两个都填了4或者8。但正确答案是sizeof(a)在整个数组对象上求大小是5 * sizeof(int)sizeof(p)才是指针本身的大小32位平台是4字节64位平台是8字节。这里的本质区别是数组名是一个地址常量不是变量不能执行a或a p这类操作而指针是变量可以重新赋值。编译器在大多数表达式中会把数组名“退化”为指向首元素的指针但在sizeof和取地址的场景下数组名仍然保留数组的身份。这是笔试最经典的陷阱之一几乎是每年必考。3.2 sizeof和strlen的对照陷阱C语言部分还考了一道字符串相关的题char s[] hello;问sizeof(s)和strlen(s)分别是多少。正确答案是6和5因为字符串字面量在末尾隐式带一个\0sizeof把它算进去了strlen只统计到第一个\0之前。我见过很多同学在这里掉坑因为他们只记了“strlen是字符数sizeof是大小”这个表面结论却没注意\0的存在。还有一道延伸题如果把char s[]改成char *s hello那么sizeof(s)就只返回指针大小了而strlen(s)依然是5。那时候我们常说光是这一个知识点就能编出十几道题核心其实都是“编译器视角”和“运行逻辑”的区别。3.3 指针加减和内存越界的边界判断编程题里还出现过一道数组反转的题目要求在int *指针方式下原地反转数组。这题写起来不难但边界条件很容易出问题。比如用双指针void reverse(int *arr, int n) { int *left arr; int *right arr n - 1; while (left right) { int tmp *left; *left *right; *right tmp; left; right--; } }这里要注意的是arr n - 1指向最后一个元素而不是arr n。如果写成right arr n后面解引用*right就已经越界了属于未定义行为。笔试里虽然没有让你实际运行但阅卷时看到这种写法会直接扣分因为金融系统开发中对数组越界是零容忍的。我在刷题时习惯每个循环都检查一遍边界条件再往下写这个习惯现在工作后也一直在用。4. Linux与数据库金融开发的基本功考察4.1 高频Linux命令你会几个Linux题目在这套卷子里不算多但很有代表性。有一道问想查看某个进程的CPU和内存占用用什么命令。选项里出现了ps、top、free、df。正确答案是top它是动态刷新地显示系统资源ps是静态快照free只看内存df看磁盘。还有一道是问在日志文件里查找包含“ERROR”的行并统计数量命令应该是grep ERROR app.log | wc -l。这类基础命令对做过实际项目的人来说很简单但对只在学校里写过代码的同学就会有点陌生。我的建议是平时练习时别只在本机跑Java尽量在Linux虚拟机上操作一遍把文件查找、权限修改、进程管理、日志排查这几类命令练熟。金融公司的生产环境基本都是Linux笔试考这些说明他们招的不是只会写业务代码的人而是能独立部署排查问题的开发。4.2 SQL语句里的分组与聚合别把条件放错地方数据库部分有一道SQL题让我印象很深有一张订单表orders(user_id, amount, create_time)要求查询“每个用户订单总金额超过1000元”的用户ID和总金额。很多同学一上来就把WHERE amount 1000写上去了但这是错的因为题目要求的是“每个用户的总金额超过1000”不是每笔订单超过1000。正确写法是SELECT user_id, SUM(amount) AS total FROM orders GROUP BY user_id HAVING total 1000;这个考点考的就是WHERE和HAVING的区别WHERE在分组前过滤原始行HAVING在分组聚合后过滤结果集。还有一题问ORDER BY和GROUP BY的执行顺序记住一个完整SELECT语句的逻辑执行顺序基本就够应付了先FROM再WHERE再GROUP BY再HAVING再SELECT再ORDER BY最后LIMIT。4.3 事务四大特性不只会背ACID还得会解释简答题里有一道是“简述数据库事务的ACID特性并说明各自解决什么问题”。这题看起来是所有数据库书上的第一课但很多人的回答就是四个单词各写一句话拿不到什么分。阅卷希望看到的是你理解每个特性的意义原子性事务里的操作要么全部成功要么全部回滚解决“做一半”的问题。一致性事务执行前后数据都要满足业务规则和约束解决“数据逻辑被破坏”的问题。隔离性并发事务之间不能互相干扰解决“同时写数据出错”的问题。持久性事务提交后数据修改要永久保存解决“系统故障后丢数据”的问题。我当时还补充了一句原子性、隔离性和持久性最终都是为了服务于一致性数据库通过undo log保证原子性通过锁和MVCC保证隔离性通过redo log保证持久性。如果能在答案里写出这个层次说明你不仅背了概念还理解过MySQL内部机制这在实际面试里是明显的加分项。5. 数据结构与算法小题控制复杂度的基本功5.1 用两个栈实现队列考察的是抽象思维算法小题里有一道特别经典的题用两个栈实现一个队列的入队和出队操作。很多人第一次见都会卡住因为栈是后进先出队列是先进先出两者天然相反。解法也不难往入队栈stackIn里压数据出队时先看stackOut是否为空如果为空就把stackIn的所有元素弹出并压入stackOut然后从stackOut弹出顶部元素。这样做的核心思想是“负负得正”两次后进先出正好变成先进先出。这道题我认为考察的不仅仅是能不能写对代码而是你有没有“用基础数据结构组合解决新问题”的抽象能力。笔试时间那么紧如果平时没练过这道题现场推导也能推出来但会消耗很多时间。所以经典题一定要提前过一遍像“两个栈实现队列”“两个队列实现栈”“链表反转”这类题应该达到条件反射的水平。5.2 二叉树层序遍历考的是队列应用不是递归二叉树相关的题笔试里出现的是层序遍历要求按层输出节点值。很多同学刚开始想递归但层序本质上是用队列的广度优先遍历每访问一个节点就把它左右孩子依次入队。核心代码框架不复杂public ListListInteger levelOrder(TreeNode root) { ListListInteger res new ArrayList(); if (root null) return res; QueueTreeNode queue new LinkedList(); queue.offer(root); while (!queue.isEmpty()) { int size queue.size(); ListInteger level new ArrayList(); for (int i 0; i size; i) { TreeNode node queue.poll(); level.add(node.val); if (node.left ! null) queue.offer(node.left); if (node.right ! null) queue.offer(node.right); } res.add(level); } return res; }这里有个细节在遍历某一层时queue.size()是动态变化的所以必须先取快照int size queue.size()否则会把下一层节点也当成当层节点处理。我一直觉得这种题考的不是你会不会用队列而是你够不够细心能不能发现这种隐蔽的坑。5.3 排序算法复杂度背诵之外要懂“什么时候用哪个”这张卷子还有一道选择题下列排序算法中平均时间复杂度是O(n log n)的是哪些。选项有冒泡、插入、快排、堆排、归并。答案自然是快排、堆排、归并。但如果你只背了复杂度下一道题可能就露怯了问“数据量很大内存装不下需要对外部文件排序应该用哪种排序算法的思想”。正确答案是归并排序它天然适合外部排序因为可以分段读入内存、分别排序后再进行多路归并。这类题目说明出题人不满足于你“背表”还希望你能在真实场景里做出选择。我的经验是复习排序时不要只看复杂度表一定要动手写一遍快排、归并和堆排理解每一趟排序后数组变成了什么样这样题目怎么变都难不倒你。6. 易错题复盘刷这张卷子踩过的坑6.1 选择题里的“反向提问”这套卷子有很多题是反向提问比如“下列说法不正确的是”“以下哪项是错误的”。我刷题时因为先入为主记得某个对的结论一看到眼熟的选项就选了结果题目问的是“不正确”白白丢分。应对方法是刷题时把题干的否定词圈出来养成习惯就不会中招。我那会儿每次做选择题都先问自己它是在问“对的”还是“错的”6.2 编程题的边界条件最后一道编程题实际上考查的是旋转数组的二分查找题面是一个有序数组被旋转了一次给定目标值要求找到其下标。如果没提前做过这题现场容易纠结。核心思路是每次二分时判断哪一半是有序的再判断目标值是否在那一段范围内。public int search(int[] nums, int target) { int left 0, right nums.length - 1; while (left right) { int mid left (right - left) / 2; if (nums[mid] target) return mid; if (nums[left] nums[mid]) { if (target nums[left] target nums[mid]) { right mid - 1; } else { left mid 1; } } else { if (target nums[mid] target nums[right]) { left mid 1; } else { right mid - 1; } } } return -1; }这个代码的边界条件是nums[left] nums[mid]时要用判断目标是否在左半段时也注意等号。我当年写的时候漏了等号结果遇到两个元素的情况就出错。这种细节靠眼睛是看不出来的必须手写测试用例去验证比如nums [3, 1], target 1这类边界。6.3 金融业务题的回答思路最后还有一道简答题大概意思是交易系统日终清算时发现对账不平请列出可能原因和排查思路。很多人看到这种题就懵了觉得课程里没学过。其实这类题考的是工程思维。你可以从数据流的角度拆解先看原始交易数据有没有丢再看计算逻辑有没有错比如利息四舍五入方式不一致再看数据库事务有没有漏提交或回滚最后看文件传输或消息队列有没有重发丢包。按数据流顺序层层排查即使不懂金融业务也能组织出有逻辑的答案。我后来面其他金融公司时这类“业务数据对不上”的情景题也经常出现提前建立排查框架非常有用。写在最后的一点个人心得整套卷子刷下来我最明显的感受是它没有一道题超纲但每一道题都在逼你回头补基础。现在的笔试越来越重视细节和工程实践单纯靠考前突击刷题很难拿高分真正有用的还是平时多写、多跑、多总结。我给正在准备秋招的同学一个小建议与其刷五十套新题不如把一套典型的卷子反复做三遍。第一遍正常做第二遍把每道错题对应的知识点搞懂第三遍尝试不看答案把每道题背后的原理讲给旁边的人听。能把别人讲明白了这个知识点才真正是你的。
返回列表