逐渐找回信心,慢慢变得更强。成事在天,谋事在人。
Q:如何用堆结构存取中位数?

写这个帖子的小姐姐水平太高了,能把这个问题写的让我醍醐灌顶。
如果要动态存取中位数,可以用两个堆来实现:一个大顶堆,一个小顶堆。
具体这样设计:
-
大顶堆存较小的一半数据(堆顶是这一半的最大值)
-
小顶堆存较大的一半数据(堆顶是这一半的最小值)
中位数怎么取?
-
如果两个堆的元素数量相等,中位数就是两个堆顶的平均值
-
如果大顶堆比小顶堆多一个元素,中位数就是大顶堆的堆顶
-
如果大顶堆比小顶堆少一个元素,中位数就是小顶堆的堆顶
新数怎么插入?
-
第一步,确定插哪边:正常情况下,比大顶堆堆顶小就进大顶堆,比大顶堆堆顶大就进小顶堆
-
第二步,平衡数量 :插入后检查两个堆的大小。如果大顶堆比小顶堆多超过1个,就把大顶堆的堆顶移到小顶堆;反过来也一样。保证两个堆的数量差不超过1
这样,无论插入多少个数,都能在 O(log n) 时间内完成插入,O(1) 时间拿到中位数。
Q:怎样在一个链表里判断是否有环,最多只能使用线性复杂度?

为什么"单指针 + 记录"不行?
你说的这种方法,本质上需要记住之前走过的所有位置。链表节点在内存中没有编号,你无法知道"这个地址之前见没见过",除非:
-
修改节点:给节点加一个"已访问"标记。但这样会破坏原链表,而且如果链表是只读的就不能改。
-
用哈希表 :存储所有见过的节点地址。这样空间复杂度就是 O(n) ,而快慢指针是 O(1)。
"线性复杂度"通常不只是指时间 O(n),面试官往往也期望空间是 O(1)。 快慢指针的优雅之处就在于:不用记住历史,只用两个指针的相对速度来判断。
Q:黑白测试的区别?
黑盒测试把程序看作黑盒子,只关心输入输出是否符合需求,不关心内部怎么实现。白盒测试需要看源代码,检查每条语句、每个分支是否都被执行过。黑盒测试更适合功能验证,白盒测试更适合代码质量检查。
Q:敏捷开发和瀑布模型的区别?
"瀑布模型是线性的,需求、设计、编码、测试依次进行,适合需求明确的项目,但变更成本高。敏捷开发是迭代的,每个迭代(1-4周)都产出可工作的软件,适合需求不明确或快速变化的项目。瀑布重视文档,敏捷重视软件本身和客户反馈。"
Q:配置管理包括哪些活动?
配置管理是对软件的版本、变更、状态进行系统管理的活动集合。
配置管理主要包括五个活动:版本控制、变更控制、配置标识、配置审计和状态报告。版本控制是基础,用Git管理代码历史;变更控制管理需求变更的流程;配置标识明确哪些文件需要纳入管理;配置审计检查发布版本是否正确;状态报告记录当前配置状态。核心目标是让软件的版本可追溯、变更可控。
Q:持续集成及其特性?
持续集成是指开发人员频繁地将代码合并到主干,每次合并都自动运行构建和测试。
持续集成是开发人员频繁(每天多次)将代码合并到主干,每次合并都自动触发构建和测试。它的核心特性是:频繁提交、自动构建、自动测试、快速反馈、保持主干健康。持续集成的目标是尽早发现集成问题,降低修复成本。如果构建或测试失败,团队需要立即修复,确保主干始终是可发布状态。常用工具是Jenkins或GitLab CI。
Q:介绍一下池化?
池化是一种资源复用的技术。核心思想是提前创建一批资源放在池子里,需要时从池子借用,用完归还,而不是反复创建和销毁。
常见例子包括线程池、数据库连接池、内存池、对象池。
池化的好处是减少资源创建销毁的开销,提升系统性能;同时通过设置上限,防止资源耗尽。
主要需要解决的问题是:防止资源泄露(借了不还)、处理空池等待、回收闲置资源、控制最大数量。