尧图网站设计 尧图网站设计YAOTU DESIGN
ARTICLE DETAIL

资讯详情

深耕网站设计与一线实操的经验洞察。

银行金融科技岗笔试复盘:从招行信用卡中心编程题看考察逻辑

银行金融科技岗笔试复盘:从招行信用卡中心编程题看考察逻辑 先说明一点我写这篇不是要“考古”一份2018年的笔试题而是想借这份题目聊聊银行系金融科技岗笔试背后的考察逻辑。招行信用卡中心在业内属于技术氛围很浓的地方它的秋招编程题一直有一个特点不炫技但很务实。很多题看着简单实际写起来会卡在边界条件、精度、并发这类问题上。对于现在打算进银行系技术岗的人哪怕是2025年再回头看这批题参考价值依然不小。而且最近总有读者问“2025年3月Python一级编程题是什么风格”我当时就把这批老题翻出来对比了一下发现底层思路的延续性比想象中强得多。这篇文章就把我复盘时看到的、踩过的、学到的一次讲清楚。1. 银行信用卡中心的笔试到底在考什么1.1 金融科技岗和互联网大厂考核的底层差异说句实话银行信用卡中心的笔试题型跟互联网大厂的刷题风格差别非常大。互联网公司喜欢考动态规划、图论、滑动窗口这些“算法味”很重的题而银行系更偏爱基础数据结构和业务逻辑的结合。我复盘2018年这批题时一个很明显的感受是每道题都能在信用卡中心的真实业务里找到影子。比如账单日计算、还款金额校验、积分累加、交易去重这些东西在互联网公司的题库里很少出现但在银行系统里全是日常。为什么这么考因为金融系统最看重的不是“你能否在半小时内写出一个红黑树”而是“你能否在业务规则一堆、数据量大、并发高的情况下不写错一个条件判断”。另一个差异在于代码的评判标准。银行笔试通常不只看最终结果还会看你对异常分支的处理。同一道题你用三个if堆出来也能过但代码里有没有考虑“账单日跨年”“金额为0”“重复提交”这类边界场景才是真正拉开差距的地方。这不是刁难你是银行系统真的会被这些问题搞挂。1.2 编程题背后对应的信用卡核心业务场景看题不能只看题得看到题目背后的业务系统。我梳理了一下招行信用卡中心这类笔试几乎所有题目都能落到几个核心系统模块上账务系统交易记账、账单生成、还款销账。对应日期计算、金额汇总、状态流转笔试里大量字符串、数组题就是在模拟这个。积分系统消费积分、兑换抵扣。对应排序、聚合、组合优化问题。风控系统交易拦截、异常检测。对应条件判断、规则匹配。支付与清结算幂等、对账、差错处理。对应并发控制、去重逻辑。所以你看题目虽然披着“算法题”的外衣内核全是业务模型。如果你理解了这一点解题时就会多一层“业务感”。比如看到“判断一笔还款是否重复”你第一反应不是去写一个复杂算法而是想到“幂等性”三个字然后自然就知道该用一个唯一键或状态字段去控制。这种思路靠刷LeetCode是刷不出来的。2. 2018秋招经典题目类型复盘2.1 字符串与日期处理类题目这批题里出现频率最高的一类就是日期和字符串处理。有同学可能觉得简单但其实这种题最阴。银行里面的日期计算根本不等于“两个日期相减得到天数”。举个典型场景信用卡账单日和还款日之间的时间间隔每个月可能都不一样。如果你是按“30天后”去算那2月份就直接算错。2018年的题目里就有一道类似的题让考生写一个函数输入某笔消费的入账日期输出它属于哪一期账单。很多人用硬编码的月份天数去凑一碰到闰年就露馅。字符串题也是同样的套路。比如有一个题是解析交易流水格式类似“商户名|交易金额|交易时间|交易状态”要求按商户分类汇总有效交易金额。大部分人能写出来但少数人会忽略“无效交易要过滤”这个条件。这种题考察的其实是你有没有审题的习惯而不是你会不会字符串split。2.2 数组与聚合统计类题目第二类高频题型是聚合统计。典型考法是给你一批消费明细让你按某个维度商户类型、城市、卡等级做汇总再输出Top N或者满足特定条件的记录。这类题背后对应的是信用卡中心的经营分析报表。我印象比较深的一道题是给一个二维数组每行是某用户在某个商家的消费记录需要统计出“同时在不同商家消费过且总金额超过阈值”的用户名单。听起来不复杂但如果你用嵌套循环暴力去搞数据量一上来就超时还容易重复统计。题目其实在考察你是否能想到先分组、再聚合、再过滤的分步思路。还有一类聚合题跟排序挂钩比如“按消费金额降序输出前10个商户如果金额相同按商户名升序”。这个单纯用排序能解但如果要求内存占用小呢这就涉及堆排序或者局部排序了。2018年能想到用堆的人不多但一旦想通后面面试官会觉得你的工程素养不错。2.3 数据库与事务类题目严格来说银行笔试里的“编程题”不全是写代码有一部分是写SQL或画事务流程。这跟信用卡系统天天跟数据库打交道有关。典型题目是用户有一张还款记录表需要找出“已出账单但尚未还清”的用户。很多人上来就写LEFT JOIN但没考虑“部分还款”的情况。正确做法是要先算出每笔账单已还总额再和账单应还金额对比。这类题本质上是在考分组聚合和关联查询的熟练度。事务类题目就更直接了比如“还款操作要同时更新账户余额、还款流水、账单状态如何保证一致性”。这个很难用一道编程题完整考出来所以笔试通常会给一个简化版本模拟一个扣款函数要求并发调用时不出现超扣。看到这种题你要反应出来它在考什么往锁、原子操作、唯一约束上去答分数就拿到了。2.4 规则匹配与风控类题目最后这类题最有银行特色就是风控规则匹配。信用卡中心的欺诈交易检测、异常消费拦截本质上都是大量if-else规则的组合。2018年有题目这么出给定一笔交易的特征金额、城市、是否夜间、商户类型和一组风控规则判断这笔交易是否命中风险规则。规则形如“夜间交易金额超过5000元且城市与常用城市不一致则拦截”。这类题不需要高级算法考验的是对规则优先级和覆盖关系的处理。很多考生会忽略“命中多条规则时只报第一条”或者“规则之间有冲突”的情况。恰好这是银行风控系统的真实痛点规则配置多了以后最怕的就是规则冲突和优先级混乱。所以你看银行笔试从不会考你虚的它出的每道题都是生产环境里真会炸的点。3. 三道真题还原与完整解题思路3.1 账单周期归属计算别让日期计算毁了你我先把当时比较典型的一道题还原出来题目大意每个信用卡用户有一个账单日例如每月15日。一笔消费的发生日期为date_str格式YYYY-MM-DD规定每日20:00之前的消费当天入账20:00之后的消费次日入账入账后归属最近的一个账单日所在的账单周期。要求输出该消费应归属的账单周期起始日期和结束日期。这道题我当年自己写的时候也翻了车原因就是没考虑20点时间边界。很多人把日期直接拿来算忽略了“当天入账”和“次日入账”的分界线。更隐蔽的坑是跨年和2月天数。一个稳的写法是用Python的datetime先把字符串转成日期和时间判断小时是否大于等于20决定入账日是否加1天。然后根据用户账单日判断入账日处在哪个账单周期。from datetime import datetime, timedelta def get_bill_cycle(date_str, bill_day): dt datetime.strptime(date_str, %Y-%m-%d %H:%M:%S) # 当天20:00之后的消费算次日入账 if dt.hour 20: dt dt timedelta(days1) # 判断dt的日是否超过账单日 if dt.day bill_day: cycle_start dt.replace(daybill_day) - timedelta(days1) # 向上取整到月份首日 cycle_start cycle_start.replace(day1) # 周期开始后的下一个账单日前一天是结束日 next_bill add_months(cycle_start, 1) timedelta(daysbill_day - 1) cycle_end next_bill else: cycle_start dt.replace(day1) next_bill add_months(cycle_start, 1) timedelta(daysbill_day - 1) cycle_end next_bill return cycle_start.date(), cycle_end.date()这里有个比较繁琐的地方是跨月的日期计算比如1月31日往后推一个月如果直接timedelta(days30)2月就出问题。我实际答题时干脆写了一个add_months辅助函数用“先算目标月份和年份再用min(目标账单日目标月份最后一天)”的方式处理。建议大家在考场上别偷懒这种边界多的题目拿测试用例一点一点验比一次性写完美更重要。3.2 积分累计与最优兑换背包问题的银行变体另一道让我印象深刻的题是积分兑换。大意用户有M个积分可选兑换的商品有N种每种商品需要消耗积分cost[i]同时能兑换的价值是value[i]求在积分允许范围内能获得的最大总价值。这就是经典的0-1背包问题。现在看当然不新鲜但2018年不少考生看到这道题会懵因为它披着“信用卡积分”的外衣很多人想不到用动态规划。代码其实不长def max_value(amount, costs, values): n len(costs) dp [0] * (amount 1) for i in range(n): for j in range(amount, costs[i] - 1, -1): dp[j] max(dp[j], dp[j - costs[i]] values[i]) return dp[amount]这个题真正的难点不在背包本身而在“是否识别出它是背包”。所以遇到题目先把业务描述翻译成算法模型这是特别重要的能力。我当时习惯先在草稿纸上写“积分总量背包容量每件商品积分消耗物品重量兑换价值物品价值”翻译到位了代码就是默写。有些同学会问为什么银行笔试要考背包因为信用卡积分兑换商城在真实业务中就有类似的“最优兑换”需求而且兑换规则经常带约束比如“同种商品限兑一件”“部分商品优先级强制兑换”。笔试只能考基础版但核心思想是一样的。3.3 高并发下的幂等还款不只是“加个锁”最后这道题是场景设计题但很多银行笔试会把它降维成一个编程题写一个函数输入用户ID、还款金额要求在多次调用同一笔还款流水号时只让第一次请求真正扣款后续请求直接返回成功但不重复扣款。这就是典型的幂等控制。我当时给出的解法分两步。第一步在数据库层面给还款流水号加唯一索引这是最可靠的防线。代码题里可以模拟用一个set存储已处理流水号processed set() lock threading.Lock() def repay(user_id, amount, serial_no): global processed if serial_no in processed: return {code: SUCCESS, msg: 重复请求已忽略, deducted: False} with lock: if serial_no in processed: return {code: SUCCESS, msg: 重复请求已忽略, deducted: False} # 真正执行扣款逻辑例如更新账户余额 do_deduct(user_id, amount) processed.add(serial_no) return {code: SUCCESS, msg: 还款成功, deducted: True}注意这里我用了双重检查加锁第一层判断在外面避免所有请求都抢锁第二层判断在锁里面防止两个线程同时通过第一层判断。这一步很多同学知道要加锁但会忽略一个点分布式环境下单个进程内的set和lock根本没有用。所以答题时最好补一句“生产环境应使用Redis分布式锁或数据库唯一约束”这个细节特别能体现你的工程经验。我当时面试时就是多说了这句面试官明显态度不一样了。4. 做题过程中最容易踩的坑4.1 时间边界和自然月是重灾区银行编程题十道里八道跟日期有关而日期错误几乎都出在边界。20点整算当天还是次日账单日遇到2月29日怎么处理跨年时年份要不要进位这些都是送命题。我当时的经验是所有时间类题目先写一个针对边界条件的测试集比如“2028-02-29 19:59:59”“2028-02-29 20:00:00”“2018-12-31 23:59:59”全部跑一遍再提交。不要觉得浪费时间银行笔试判分是按用例跑的边界用例通常占比很高丢一个就是几分。4.2 金额计算用浮点数等于自杀银行题只要涉及金额你就要打起十二分精神。Python里直接0.1 0.2得到0.30000000000000004这在金额计算里是不能容忍的。我看到有考生写金额汇总时用float累加最后比对结果差了一分钱整个用例挂掉。正确做法有两种一是把金额全部转成“分”为单位用整数运算二是在Python里用Decimal类型。考试的时候第一种最稳因为不用引入额外概念处理也快。def parse_amount(amount_str): # 输入 1234.56返回 123456 yuan, fen amount_str.split(.) return int(yuan) * 100 int(fen[:2].ljust(2, 0))这种转单位思路你在处理费率、利息、还款金额时会非常省心。记住一条金融代码里整数才是王道浮点数一律不用。4.3 把“通过示例用例”当成“代码正确”银行笔试平台通常会给一两个示例输入很多同学跑通了示例就提交结果实际得分很低。原因很简单示例覆盖的是正常路径而判分用例大量覆盖边界和异常路径。比如题目要求输入非法格式时返回特定错误码示例里根本没给非法输入你也就没写这段逻辑。所以拿到题目不要急着写代码先把题目里所有“如果……那么……”的条件全部列出来尤其是异常分支。建议在代码里加个validate_input函数负责检查输入这样主流程逻辑干净判分的异常用例也能兜住。4.4 并发场景没有状态意识只要题目中出现“同一笔业务被多次请求”这类描述就一定要往幂等、并发、一致性方向想。但很多同学的代码里根本没有“状态”这个概念。例如写还款函数流程是“查账单→算余额→更新状态→插入流水”。如果不加任何并发控制两个请求同时进来都查到未还款然后都去扣款就出大问题了。在笔试代码里至少要做到两种处理中的一种用锁或者用状态位先做CAS式更新。比如先执行UPDATE bill SET status REPAYING WHERE status UNPAID如果影响行数为0说明已经被别的请求处理了。这个思路写进代码里哪怕只是伪代码判卷都能看到你的工程意识。5. 从2018到2025这类题目有哪些变与不变5.1 变的是工具和语言不变的是业务建模能力我把2018年这批题和最近的笔试题目对比了一下发现题型骨架没有大变化依然是日期处理、聚合统计、幂等控制、规则匹配这四类。变的更多是语言偏好和工具栈。2018年那会儿还有不少考生用Java/C答题而现在的校招几乎默认Python首选。代码写法也从“自己实现排序算法”变成了“直接用pandas做聚合”。比如同样的“按商户统计消费总额”以前要手写字典累加现在一行df.groupby(merchant)[amount].sum()就解决了。但要注意工具变快不代表可以不理解原理。如果你不理解groupby背后的分组逻辑遇到“按商户和城市双重分组并过滤重复交易”的复合场景照样写错。顺便说一句最近不少人在问“Python2025年3月一级编程题”是什么风格我看了几份抽样题目发现它面向的虽然是入门水平但已经在用“班级成绩统计”“消费记录汇总”这类带业务背景的题目来考基本功了。这和2018年银行笔试的思路其实是一个方向把编程能力放进场景里考核。所以我一直建议基础薄弱的读者别只刷纯语法题多练“小业务场景编程题”对后续面试帮助大得多。5.2 银行笔试反而更加重视工程素养了2018年那会儿你能写出正确逻辑基本就能过。但近几年银行科技岗卷得太厉害笔试开始增加“代码风格”“可维护性”的隐形评分。同一个功能有人写成一个上百行的main函数有人拆成parse_input、validate、process、format_output几个函数后者明显得分高。我当时复盘时学到的一个很有用的习惯是哪怕笔试时间再紧也至少把代码拆成三块——输入解析、核心处理、结果格式化。这样既方便自己调试也方便判卷人看。核心处理函数尽量做到无副作用不依赖全局变量传入参数、返回结果。你写的时候可能觉得多花了两分钟但换来的代码清晰度收益远大于那两分钟。5.3 给现在求职者的准备路线建议如果要我给一个准备银行系技术岗笔试的实用路线大概是这个顺序先把“日期时间处理”练到闭着眼睛都能写尤其是datetime、timedelta、字符串格式化和大小月判断。再刷“聚合统计类”题目重点练习字典、Counter、defaultdict、groupby做到不假思索。然后专门练“去重与幂等”场景题理解set、锁、唯一索引、CAS更新这几个概念的区别和适用场景。有余力再看动态规划背包、最长子序列这类经典题型就够了不需要刷偏难怪题。最后一定要做几次“带业务背景”的模拟题不要只刷裸算法题。这个顺序未必适合所有人但对我自己带过的同学来说普遍反馈“路线走完银行系笔试基本不慌”。尤其是第3步很多人忽略但银行笔试特别吃这一套。6. 一次复盘带来的实际收获说实话我当年秋招时第一次做这类题栽了不少跟头尤其是日期题和幂等题。但后来进入金融科技领域回头看发现当年踩的那些坑几乎都是生产环境真实踩过的坑的预演。这让我养成了一个习惯每做完一道题不问“我解没解出来”而是问“这道题背后对应的是哪个真实系统的哪一类问题”。把题目当成业务系统的切片去解思路会清楚很多。最后分享一个写代码时的小技巧也是这批题教会我的凡是有业务含义的数字不要直接裸写在代码里哪怕是账单日20点这种看似固定的值。你可以在开头定义成常量比如CUTOFF_HOUR 20。这个习惯在笔试里可能只是让代码好看但进了项目里它就是少出bug的保命符。银行系统里规则经常变所有魔数都是定时炸弹。早点养成这个习惯比多刷一百道题都值。
返回列表