# 软件测试手撕代码题 - 常见题型与实例文档
## 一、数组/列表操作类
### 题目1:找出数组中第二大的数
**题目描述**:给定一个整数数组,返回数组中第二大的数。如果不存在第二大数(如数组长度小于2或所有元素相同),返回None或特定值。
**解题思路**:遍历数组,维护最大值和次大值两个变量。注意处理重复最大值的情况。
**代码示例**:
```python
def find_second_largest(nums):
"""
找出数组中第二大的数
:param nums: 整数列表
:return: 第二大的数,不存在则返回None
"""
if len(nums) < 2:
return None
first = second = float('-inf')
for num in nums:
if num > first:
second = first
first = num
elif num > second and num != first:
second = num
return second if second != float('-inf') else None
# 测试用例
print(find_second_largest([3, 5, 1, 5, 2])) # 输出: 3
print(find_second_largest([1])) # 输出: None
print(find_second_largest([5, 5, 5])) # 输出: None
print(find_second_largest([-1, -2, -3])) # 输出: -2
```
### 题目2:数组去重
**题目描述**:给定一个数组,返回去重后的新数组,保持原顺序。
**解题思路**:使用哈希表记录已出现元素,遍历原数组,将未出现过的元素加入结果列表。
**代码示例**:
```python
def remove_duplicates(nums):
"""
数组去重,保持原顺序
:param nums: 任意元素列表
:return: 去重后的列表
"""
seen = set()
result = []
for num in nums:
if num not in seen:
seen.add(num)
result.append(num)
return result
# 测试用例
print(remove_duplicates([1, 2, 2, 3, 4, 4, 5])) # 输出: [1, 2, 3, 4, 5]
print(remove_duplicates(['a', 'b', 'a', 'c'])) # 输出: ['a', 'b', 'c']
```
### 题目3:找出数组中所有偶数
**题目描述**:给定一个整数数组,返回所有偶数组成的新数组。
**代码示例**:
```python
def find_even_numbers(nums):
"""
找出数组中的所有偶数
:param nums: 整数列表
:return: 偶数列表
"""
return [num for num in nums if num % 2 == 0]
# 测试用例
print(find_even_numbers([1, 2, 3, 4, 5, 6])) # 输出: [2, 4, 6]
print(find_even_numbers([])) # 输出: []
```
---
## 二、字符串处理类
### 题目1:判断回文字符串
**题目描述**:判断一个字符串是否是回文(正读反读都一样),忽略大小写和非字母数字字符。
**解题思路**:双指针法,一个从前往后,一个从后往前比较。
**代码示例**:
```python
def is_palindrome(s: str) -> bool:
"""
判断字符串是否是回文
:param s: 输入字符串
:return: 是否是回文
"""
# 清理字符串:转小写,只保留字母数字
cleaned = ''.join(ch.lower() for ch in s if ch.isalnum())
left, right = 0, len(cleaned) - 1
while left < right:
if cleaned[left] != cleaned[right]:
return False
left += 1
right -= 1
return True
# 测试用例
print(is_palindrome("A man, a plan, a canal: Panama")) # 输出: True
print(is_palindrome("race a car")) # 输出: False
print(is_palindrome("")) # 输出: True
```
### 题目2:统计字符出现次数
**题目描述**:统计字符串中每个字符出现的次数。
**解题思路**:使用字典(哈希表)存储字符和对应出现次数。
**代码示例**:
```python
def count_characters(s: str):
"""
统计字符串中每个字符的出现次数
:param s: 输入字符串
:return: 字符计数字典
"""
char_count = {}
for char in s:
char_count[char] = char_count.get(char, 0) + 1
return char_count
# 测试用例
print(count_characters("hello")) # 输出: {'h':1, 'e':1, 'l':2, 'o':1}
print(count_characters("测试测试")) # 输出: {'测':2, '试':2}
```
### 题目3:最长无重复字符子串
**题目描述**:给定一个字符串,找出不含有重复字符的最长子串的长度。
**解题思路**:滑动窗口法,使用哈希表记录字符最近出现的位置。
**代码示例**:
```python
def length_of_longest_substring(s: str) -> int:
"""
查找无重复字符的最长子串长度
:param s: 输入字符串
:return: 最长子串长度
"""
char_index = {} # 存储字符最近出现的位置
left = 0
max_len = 0
for right, ch in enumerate(s):
# 如果字符已出现且在窗口内,移动左指针
if ch in char_index and char_index[ch] >= left:
left = char_index[ch] + 1
char_index[ch] = right
max_len = max(max_len, right - left + 1)
return max_len
# 测试用例
print(length_of_longest_substring("abcabcbb")) # 输出: 3 ("abc")
print(length_of_longest_substring("bbbbb")) # 输出: 1 ("b")
print(length_of_longest_substring("pwwkew")) # 输出: 3 ("wke")
```
---
## 三、基础算法类
### 题目1:斐波那契数列
**题目描述**:实现斐波那契数列的第n项(F(0)=0, F(1)=1)。
**解题思路**:迭代法避免递归的重复计算。
**代码示例**:
```python
def fibonacci(n: int) -> int:
"""
计算斐波那契数列的第n项
:param n: 项数索引
:return: 第n项的值
"""
if n <= 0:
return 0
elif n == 1:
return 1
a, b = 0, 1
for _ in range(2, n + 1):
a, b = b, a + b
return b
# 测试用例
print(fibonacci(0)) # 输出: 0
print(fibonacci(1)) # 输出: 1
print(fibonacci(5)) # 输出: 5
print(fibonacci(10)) # 输出: 55
```
### 题目2:冒泡排序
**题目描述**:实现冒泡排序算法。
**解题思路**:重复遍历列表,比较相邻元素并交换位置。
**代码示例**:
```python
def bubble_sort(nums):
"""
冒泡排序
:param nums: 待排序列表
:return: 排序后的列表
"""
n = len(nums)
# 复制列表避免修改原数据
arr = nums.copy()
for i in range(n - 1):
# 标记是否发生交换
swapped = False
for j in range(n - 1 - i):
if arr[j] > arr[j + 1]:
arr[j], arr[j + 1] = arr[j + 1], arr[j]
swapped = True
# 如果本轮未交换,说明已排序完成
if not swapped:
break
return arr
# 测试用例
print(bubble_sort([64, 34, 25, 12, 22, 11, 90])) # 输出: [11, 12, 22, 25, 34, 64, 90]
print(bubble_sort([5, 1, 4, 2, 8])) # 输出: [1, 2, 4, 5, 8]
```
### 题目3:最长公共前缀
**题目描述**:查找字符串数组中的最长公共前缀。
**解题思路**:以第一个字符串为基准,逐个字符与其他字符串比较。
**代码示例**:
```python
def longest_common_prefix(strs):
"""
查找字符串数组的最长公共前缀
:param strs: 字符串列表
:return: 最长公共前缀
"""
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
# 测试用例
print(longest_common_prefix(["flower", "flow", "flight"])) # 输出: "fl"
print(longest_common_prefix(["dog", "racecar", "car"])) # 输出: ""
print(longest_common_prefix([])) # 输出: ""
```
---
## 四、简单逻辑与模拟类
### 题目1:判断质数
**题目描述**:判断一个正整数是否为质数。
**解题思路**:只需检查到√n的整数范围,排除偶数。
**代码示例**:
```python
def is_prime(n: int) -> bool:
"""
判断一个数是否为质数
:param n: 正整数
:return: 是否为质数
"""
if n <= 1:
return False
if n == 2:
return True
if n % 2 == 0:
return False
# 只需检查到 sqrt(n) 的奇数
for i in range(3, int(n**0.5) + 1, 2):
if n % i == 0:
return False
return True
# 测试用例
print(is_prime(2)) # 输出: True
print(is_prime(17)) # 输出: True
print(is_prime(20)) # 输出: False
print(is_prime(1)) # 输出: False
```
### 题目2:输出100以内所有素数
**题目描述**:输出100以内的所有素数。
**解题思路**:使用埃拉托斯特尼筛法高效求解。
**代码示例**:
```python
def find_primes_up_to_n(n: int):
"""
找出n以内的所有素数(埃拉托斯特尼筛法)
:param n: 上限
:return: 素数列表
"""
if n < 2:
return []
# 初始化标记数组,True表示是素数
is_prime = [True] * (n + 1)
is_prime[0] = is_prime[1] = False
for i in range(2, int(n**0.5) + 1):
if is_prime[i]:
# 标记i的倍数不是素数
for j in range(i*i, n + 1, i):
is_prime[j] = False
# 收集所有素数
primes = [i for i in range(2, n + 1) if is_prime[i]]
return primes
# 测试用例
print(find_primes_up_to_n(20)) # 输出: [2, 3, 5, 7, 11, 13, 17, 19]
```
### 题目3:简单计算器
**题目描述**:实现一个支持加减乘除的简单计算器。
**解题思路**:根据运算符执行相应计算,注意除零错误。
**代码示例**:
```python
def simple_calculator(num1, num2, operator):
"""
简单计算器
:param num1: 第一个数
:param num2: 第二个数
:param operator: 运算符 (+, -, *, /)
:return: 计算结果或错误信息
"""
if operator == '+':
return num1 + num2
elif operator == '-':
return num1 - num2
elif operator == '*':
return num1 * num2
elif operator == '/':
if num2 == 0:
return "错误:除数不能为0"
return num1 / num2
else:
return "错误:不支持的运算符"
# 测试用例
print(simple_calculator(10, 5, '+')) # 输出: 15
print(simple_calculator(10, 5, '-')) # 输出: 5
print(simple_calculator(10, 5, '*')) # 输出: 50
print(simple_calculator(10, 5, '/')) # 输出: 2.0
print(simple_calculator(10, 0, '/')) # 输出: 错误:除数不能为0
```
---
## 五、测试相关扩展题
### 题目1:验证邮箱格式
**题目描述**:编写函数验证字符串是否符合基本邮箱格式。
**代码示例**:
```python
import re
def validate_email(email: str) -> bool:
"""
验证邮箱格式(简化版)
:param email: 待验证的邮箱字符串
:return: 是否符合基本格式
"""
pattern = r'^[a-zA-Z0-9._%+-]+@[a-zA-Z0-9.-]+\.[a-zA-Z]{2,}$'
return bool(re.match(pattern, email))
# 测试用例
print(validate_email("test@example.com")) # 输出: True
print(validate_email("invalid.email")) # 输出: False
print(validate_email("name@domain.co.uk")) # 输出: True
```
### 题目2:统计文件行数
**题目描述**:模拟统计文本文件的行数、单词数和字符数。
**代码示例**:
```python
def count_file_content(text: str):
"""
统计文本的行数、单词数和字符数
:param text: 文本内容
:return: 包含统计信息的字典
"""
lines = text.splitlines()
words = text.split()
return {
"lines": len(lines),
"words": len(words),
"characters": len(text)
}
# 测试用例
sample_text = """Hello world!
This is a test file.
It has three lines."""
print(count_file_content(sample_text))
# 输出: {'lines': 3, 'words': 11, 'characters': 47}
```
---
## 六、练习建议
1. **理解优先**:先理解题目要求,明确输入输出
2. **边界测试**:考虑空输入、单个元素、重复元素等边界情况
3. **复杂度分析**:分析时间复杂度和空间复杂度
4. **测试驱动**:先写测试用例,再实现功能
5. **代码规范**:使用清晰变量名,添加必要注释
**推荐练习顺序**:
1. 先掌握数组/字符串基础操作
2. 再练习简单算法(排序、查找)
3. 最后尝试逻辑模拟题
4. 结合测试思维,为每个函数设计全面的测试用例
---
**文档说明**:
- 所有代码示例均使用Python语言
- 每个示例包含函数定义、注释和测试用例
- 建议在实际面试中先描述思路,再编写代码
- 完成代码后主动进行测试,展示测试思维
此文档可作为软件测试岗位手撕代码题的练习参考,建议结合实际编码环境进行练习和调试。