千锋教育-做有情怀、有良心、有品质的职业教育机构

手机站
千锋教育

千锋学习站 | 随时随地免费学

千锋教育

扫一扫进入千锋手机站

当前位置:首页  >  应聘面试  >  软件测试面试题  > 7软件测试算法面试题详解_千锋教育

7软件测试算法面试题详解_千锋教育

来源:千锋教育
发布人:cli
时间: 2026-07-01 17:25:22 1782897922

前言:算法题在测试面试中的价值

在软件测试面试中,算法题并非为了考察你能否写出一个完美的搜索引擎,而是为了评估你的逻辑思维、代码质量意识以及问题拆解能力。一个优秀的测试工程师,应该能写出健壮、可测试的代码,并能从测试角度思考边界条件。本文精选7道高频算法面试题,从测试视角进行拆解,每道题都包含问题分析、代码实现、测试用例设计三个核心部分。

1. 字符串反转:基础中的陷阱

问题:实现一个函数,将输入的字符串反转。例如输入"hello",返回"olleh"。

测试思维拆解:这道题看似简单,但测试人员需要思考的边界条件包括:空字符串、单字符、包含空格、包含特殊字符、Unicode字符等。

代码实现(Python):

python
def reverse_string(s: str) -> str:

if not isinstance(s, str):

raise TypeError("Input must be a string")

return s[::-1]

测试用例设计:

  • ►正常输入:assert reverse_string("hello") == "olleh"
  • ►空字符串:assert reverse_string("") == ""
  • ►单字符:assert reverse_string("a") == "a"
  • ►包含空格:assert reverse_string("ab cd") == "dc ba"
  • ►包含数字:assert reverse_string("123") == "321"
  • ►包含特殊字符:assert reverse_string("!@#") == "#@!"
  • ►Unicode字符:assert reverse_string("你好") == "好你"
  • ►异常输入:try: reverse_string(123); except TypeError: pass

2. 两数之和:从暴力到哈希

问题:给定一个整数数组和一个目标值,找出数组中和为目标值的两个数的下标。假设每种输入只会对应一个答案。

测试思维拆解:需要覆盖数组长度、重复元素、负数、目标值不存在等情况。同时要思考,如果存在多个解,函数应该如何处理?题目假设唯一解,但测试人员需要验证这个假设。

代码实现(Python):

python
def two_sum(nums: list, target: int) -> list:

if not isinstance(nums, list) or not isinstance(target, int):

raise TypeError("Invalid input types")

seen = {}

for i, num in enumerate(nums):

complement = target - num

if complement in seen:

return [seen[complement], i]

seen[num] = i

return []

测试用例设计:

  • ►正常解:assert two_sum([2, 7, 11, 15], 9) == [0, 1]
  • ►负数参与:assert two_sum([-3, 4, 3, 90], 0) == [0, 2]
  • ►重复元素:assert two_sum([3, 3], 6) == [0, 1]
  • ►无解:assert two_sum([1, 2, 3], 10) == []
  • ►空数组:assert two_sum([], 5) == []
  • ►单元素数组:assert two_sum([1], 1) == []
  • ►异常输入:try: two_sum("abc", 5); except TypeError: pass

3. 回文数判断:空间与时间平衡

问题:判断一个整数是否是回文数。回文数是指正序和倒序读都是一样的整数。

测试思维拆解:面试官可能期望你写出不将整数转为字符串的解法。测试人员需要关注负数、0、以0结尾的数、大整数等边界。

代码实现(Python):

python
def is_palindrome(x: int) -> bool:

if not isinstance(x, int):

raise TypeError("Input must be an integer")

if x < 0 or (x % 10 == 0 and x != 0):

return False

reversed_half = 0

while x > reversed_half:

reversed_half = reversed_half * 10 + x % 10

x //= 10

return x == reversed_half or x == reversed_half // 10

测试用例设计:

  • ►正回文:assert is_palindrome(121) == True
  • ►非回文:assert is_palindrome(123) == False
  • ►负数:assert is_palindrome(-121) == False
  • ►以0结尾:assert is_palindrome(10) == False
  • ►0本身:assert is_palindrome(0) == True
  • ►一位数:assert is_palindrome(7) == True
  • ►大整数:assert is_palindrome(1234567890987654321) == True
  • ►异常输入:try: is_palindrome(1.5); except TypeError: pass

4. 有效括号:栈的经典应用

问题:给定一个只包括 '(',')','{','}','[',']' 的字符串,判断字符串是否有效。有效条件:左括号必须用相同类型的右括号闭合,且顺序正确。

测试思维拆解:这道题考察栈数据结构的理解。测试人员需要覆盖嵌套、不匹配、顺序错误、空字符串等情况。

代码实现(Python):

python
def is_valid_brackets(s: str) -> bool:

if not isinstance(s, str):

raise TypeError("Input must be a string")

bracket_map = {')': '(', '}': '{', ']': '['}

stack = []

for char in s:

if char in bracket_map.values():

stack.append(char)

elif char in bracket_map:

if not stack or stack.pop() != bracket_map[char]:

return False

else:

return False # 非法字符

return not stack

测试用例设计:

  • ►有效嵌套:assert is_valid_brackets("({[]})") == True
  • ►无效顺序:assert is_valid_brackets("([)]") == False
  • ►左括号多余:assert is_valid_brackets("(()") == False
  • ►右括号多余:assert is_valid_brackets("())") == False
  • ►空字符串:assert is_valid_brackets("") == True
  • ►单字符:assert is_valid_brackets("(") == False
  • ►包含非法字符:assert is_valid_brackets("(a)") == False
  • ►长字符串:assert is_valid_brackets("()" * 1000) == True

5. 合并两个有序数组:双指针技巧

问题:给你两个按非递减顺序排列的整数数组 nums1 和 nums2,合并 nums2 到 nums1 中,使合并后的数组同样按非递减顺序排列。假设 nums1 有足够的空间。

测试思维拆解:面试中常见的是原地合并,从后往前遍历可以避免覆盖。测试人员需要关注空数组、全重复、一个数组远大于另一个等情况。

代码实现(Python):

如果 nums2 还有剩余

nums1[:p2 + 1] = nums2[:p2 + 1]

text

**测试用例设计**:

正常情况

nums1 = [1, 2, 3, 0, 0, 0]

merge_sorted(nums1, 3, [2, 5, 6], 3)

assert nums1 == [1, 2, 2, 3, 5, 6]

nums2为空

nums1 = [1]

merge_sorted(nums1, 1, [], 0)

assert nums1 == [1]

nums1为空

nums1 = [0, 0, 0]

merge_sorted(nums1, 0, [1, 2, 3], 3)

assert nums1 == [1, 2, 3]

全重复

nums1 = [1, 1, 1, 0, 0, 0]

merge_sorted(nums1, 3, [1, 1, 1], 3)

assert nums1 == [1, 1, 1, 1, 1, 1]

一个元素

nums1 = [5, 0]

merge_sorted(nums1, 1, [3], 1)

assert nums1 == [3, 5]

text

<div style="margin:24px 0;border:1px solid #E3F2FD;border-radius:8px;background:#FAFAFA;overflow:hidden;"><div style="display:flex;align-items:center;gap:12px;padding:12px 20px;background:linear-gradient(135deg,#E3F2FD,#BBDEFB);"><span style="width:36px;height:36px;background:#2196F3;color:#fff;border-radius:50%;display:inline-flex;align-items:center;justify-content:center;font-weight:bold;font-size:16px;flex-shrink:0;">6. </span><span style="font-size:17px;font-weight:700;color:#1565C0;">最长公共前缀:字符串数组的共性</span></div><div style="padding:16px 20px;"><p><strong>问题</strong>:编写一个函数来查找字符串数组中的最长公共前缀。如果不存在公共前缀,返回空字符串 ""。</p>
<p><strong>测试思维拆解</strong>:这道题考察字符串处理。测试人员需要覆盖空数组、单字符串、无公共前缀、所有字符串相同、大小写敏感等情况。</p>
<p><strong>代码实现(Python)</strong>:</p>
<div style="margin:16px 0;border-radius:8px;overflow:hidden;border:1px solid #E0E0E0;"><div style="background:#263238;color:#B0BEC5;padding:6px 16px;font-size:12px;font-family:Consolas,monospace;"><span style="text-transform:uppercase;letter-spacing:1px;">python</span></div><pre style="background:#1E272E;color:#E0E0E0;padding:16px 20px;margin:0;overflow-x:auto;font-size:14px;line-height:1.7;font-family:Consolas,"Courier New",monospace;"><code>def longest_common_prefix(strs: list) -&gt; str:
    if not isinstance(strs, list):
        raise TypeError("Input must be a list")
    if not strs:
        return ""
    
    prefix = strs[0]
    for s in strs[1:]:
        while not s.startswith(prefix):
            prefix = prefix[:-1]
            if not prefix:
                return ""
    return prefix</code></pre></div>
<p><strong>测试用例设计</strong>:</p>
<ul style="list-style:none;padding-left:0;margin:12px 0;">
<li style="position:relative;padding:4px 0 4px 24px;line-height:1.8;"><span style="color:#2196F3;font-weight:bold;position:absolute;left:4px;">&#9658;</span>正常情况:<code style="background:#F3E5F5;color:#6A1B9A;padding:1px 6px;border-radius:3px;font-size:0.9em;font-family:Consolas,monospace;">assert longest_common_prefix(["flower", "flow", "flight"]) == "fl"</code></li>
<li style="position:relative;padding:4px 0 4px 24px;line-height:1.8;"><span style="color:#2196F3;font-weight:bold;position:absolute;left:4px;">&#9658;</span>无公共前缀:<code style="background:#F3E5F5;color:#6A1B9A;padding:1px 6px;border-radius:3px;font-size:0.9em;font-family:Consolas,monospace;">assert longest_common_prefix(["dog", "racecar", "car"]) == ""</code></li>
<li style="position:relative;padding:4px 0 4px 24px;line-height:1.8;"><span style="color:#2196F3;font-weight:bold;position:absolute;left:4px;">&#9658;</span>空数组:<code style="background:#F3E5F5;color:#6A1B9A;padding:1px 6px;border-radius:3px;font-size:0.9em;font-family:Consolas,monospace;">assert longest_common_prefix([]) == ""</code></li>
<li style="position:relative;padding:4px 0 4px 24px;line-height:1.8;"><span style="color:#2196F3;font-weight:bold;position:absolute;left:4px;">&#9658;</span>单字符串:<code style="background:#F3E5F5;color:#6A1B9A;padding:1px 6px;border-radius:3px;font-size:0.9em;font-family:Consolas,monospace;">assert longest_common_prefix(["hello"]) == "hello"</code></li>
<li style="position:relative;padding:4px 0 4px 24px;line-height:1.8;"><span style="color:#2196F3;font-weight:bold;position:absolute;left:4px;">&#9658;</span>所有相同:<code style="background:#F3E5F5;color:#6A1B9A;padding:1px 6px;border-radius:3px;font-size:0.9em;font-family:Consolas,monospace;">assert longest_common_prefix(["test", "test", "test"]) == "test"</code></li>
<li style="position:relative;padding:4px 0 4px 24px;line-height:1.8;"><span style="color:#2196F3;font-weight:bold;position:absolute;left:4px;">&#9658;</span>大小写敏感:<code style="background:#F3E5F5;color:#6A1B9A;padding:1px 6px;border-radius:3px;font-size:0.9em;font-family:Consolas,monospace;">assert longest_common_prefix(["abc", "ABC"]) == ""</code></li>
<li style="position:relative;padding:4px 0 4px 24px;line-height:1.8;"><span style="color:#2196F3;font-weight:bold;position:absolute;left:4px;">&#9658;</span>包含空字符串:<code style="background:#F3E5F5;color:#6A1B9A;padding:1px 6px;border-radius:3px;font-size:0.9em;font-family:Consolas,monospace;">assert longest_common_prefix(["", "b"]) == ""</code></li>
</ul></div></div>
<div style="margin:24px 0;border:1px solid #E3F2FD;border-radius:8px;background:#FAFAFA;overflow:hidden;"><div style="display:flex;align-items:center;gap:12px;padding:12px 20px;background:linear-gradient(135deg,#E3F2FD,#BBDEFB);"><span style="width:36px;height:36px;background:#2196F3;color:#fff;border-radius:50%;display:inline-flex;align-items:center;justify-content:center;font-weight:bold;font-size:16px;flex-shrink:0;">7. </span><span style="font-size:17px;font-weight:700;color:#1565C0;">数组中的多数元素:摩尔投票算法</span></div><div style="padding:16px 20px;"><p><strong>问题</strong>:给定一个大小为 n 的数组,找到其中的多数元素。多数元素是指在数组中出现次数大于 ⌊ n/2 ⌋ 的元素。假设数组非空,且多数元素总是存在。</p>
<p><strong>测试思维拆解</strong>:这道题可以用哈希表或排序解决,但最优解是摩尔投票算法(空间O(1))。测试人员需要覆盖数组长度为1、2、所有元素相同、不同元素数量相等(但题目保证多数元素存在)等情况。</p>
<p><strong>代码实现(Python)</strong>:</p></div></div>
    # 验证阶段(虽然题目保证存在,但测试中应验证)
    if nums.count(candidate) > len(nums) // 2:
        return candidate
    raise ValueError("No majority element found")

测试用例设计:

python
# 正常情况
assert majority_element([3, 2, 3]) == 3
assert majority_element([2, 2, 1, 1, 1, 2, 2]) == 2

# 单元素
assert majority_element([1]) == 1

# 两元素相同
assert majority_element([5, 5]) == 5

# 所有相同
assert majority_element([7, 7, 7, 7]) == 7

# 大数组
nums = [1] * 1000 + [2] * 999
assert majority_element(nums) == 1

总结:测试视角下的算法面试

这7道题覆盖了字符串、数组、栈、双指针、哈希表等核心数据结构与算法。在面试中,除了写出正确代码,测试人员应额外展示以下能力:

1. 边界思考:主动提出并测试空输入、单元素、越界等场景

2. 异常处理:对非法输入给出明确的错误处理

3. 代码可测性:函数设计应便于单元测试,避免全局状态

4. 性能意识:能分析时间/空间复杂度,并解释为什么选择某种解法

算法面试不是终点,而是展示你作为测试工程师逻辑严谨性的起点。掌握这些基础题,结合测试思维,你将在面试中脱颖而出。

tags:
声明:本站稿件版权均属千锋教育所有,未经许可不得擅自转载。
10年以上业内强师集结,手把手带你蜕变精英
请您保持通讯畅通,专属学习老师24小时内将与您1V1沟通
免费领取
今日已有369人领取成功
刘同学 138****2860 刚刚成功领取
王同学 131****2015 刚刚成功领取
张同学 133****4652 刚刚成功领取
李同学 135****8607 刚刚成功领取
杨同学 132****5667 刚刚成功领取
岳同学 134****6652 刚刚成功领取
梁同学 157****2950 刚刚成功领取
刘同学 189****1015 刚刚成功领取
张同学 155****4678 刚刚成功领取
邹同学 139****2907 刚刚成功领取
董同学 138****2867 刚刚成功领取
周同学 136****3602 刚刚成功领取
相关推荐HOT