2023.12.6 字节跳动软件测试实习生(生活服务方向)
字节跳动软件测试实习生(生活服务方向)
2023.12.6 一面
先来了一段自我介绍
由于是第一次面试没什么经验所以面试官先给我说了说工作后希望的态度转变,比如不要有学校思维期待时间比较灵活,工作以结果以任务为导向,当天要求上线的产品必须要上线(应该类似于要主动加班)。
之后问我是不是cs的学生有没有相关测试经历, 学过什么语言擅长那种等等(我说c++,python,java都用过但是最熟的是python结果最后有一个问题我还不会)
然后问了我一些专业问题
- 计算机网络有哪几层(她说的是七层但是我学的是五层最后回答上来四层)(×)
七层:
- 物理层(Physical Layer)
- 数据链路层(Data Link Layer)
- 网络层(Network Layer)
- 传输层(Transport Layer)
- 会话层(Session Layer)
- 表示层(Presentation Layer)
- 应用层(Application Layer)
五层:
- 物理
- 链路
- 网络
- 运输
- 应用
- Python装饰器(×)
在Python中,装饰器是一种用于修改或扩展函数或方法行为的一种技术。装饰器通常是函数,它接受一个函数作为参数,并返回一个新的函数,以实现对原函数的修改或增强。装饰器在代码中的应用可以使得代码更加简洁、可复用,并提供一种灵活的方式来修改或扩展函数的功能。
- 深拷贝与浅拷贝的区别(× 编译原理当时还没学完就说还没学)
深拷贝(Deep Copy)和浅拷贝(Shallow Copy)是在编程中用于复制对象的两种不同方式。它们之间的主要区别在于复制对象时是否复制对象内部的引用以及引用指向的对象。
浅拷贝(Shallow Copy):
- 只复制对象本身,不复制对象内部的引用。
- 复制的新对象和原对象共享内部的可变对象(例如列表、字典)。
- 使用浅拷贝的方式,修改新对象的内部可变对象会影响原对象。
深拷贝(Deep Copy):
- 复制对象本身,并且递归复制对象内部的所有引用指向的对象。
- 复制的新对象和原对象完全独立,修改新对象的内部可变对象不会影响原对象。
- 进程间通信机制(×)
进程间通信(Inter-Process Communication,IPC)是指在不同进程之间进行数据交换和共享信息的机制。在多进程的系统中,由于每个进程有独立的地址空间,因此需要特定的机制来实现进程间的通信。以下是一些常用的进程间通信机制:
-
管道(Pipe):
- 描述: 管道是一种半双工的通信机制,它可以在两个进程之间传递数据。
- 特点: 管道是单向的,分为匿名管道和命名管道,适用于有亲缘关系的进程。
-
消息队列(Message Queue):
- 描述: 消息队列是一种通过消息传递进行通信的机制,允许不同进程之间传递数据。
- 特点: 消息队列是一种异步通信方式,消息被存储在队列中,进程可以按照一定的规则进行读取和发送。
-
共享内存(Shared Memory):
- 描述: 共享内存允许多个进程访问同一块物理内存区域,从而实现数据共享。
- 特点: 共享内存是一种高效的通信方式,但需要通过信号量等机制来实现进程间的同步。
-
信号量(Semaphore):
- 描述: 信号量是一种用于控制多个进程对共享资源的访问的同步机制。
- 特点: 信号量可以用来解决共享内存中多个进程访问冲突的问题,通过对信号量的操作来实现进程的同步和互斥。
-
套接字(Socket):
- 描述: 套接字是一种通用的进程间通信方式,不仅可以用于不同主机之间的通信,也可以在同一主机上的不同进程之间通信。
- 特点: 套接字提供了一种灵活的通信方式,可以通过网络进行远程通信,也可以在本地进行进程通信。
-
文件映射(Memory Mapping):
- 描述: 文件映射允许多个进程共享同一文件的内容,将文件映射到进程的地址空间中。
- 特点: 文件映射可以实现高效的数据共享,进程可以直接读写内存中的数据,而无需进行数据的拷贝。
选择适当的进程间通信机制取决于具体的应用需求和场景,不同的机制有各自的优势和适用性。在设计多进程系统时,通常会根据任务的性质和数据共享的需求选择合适的 IPC 机制。
- 进程与线程的区别(✔)
进程(Process)和线程(Thread)是操作系统中用于执行程序的两个基本概念,它们有一些重要的区别:
-
定义:
- 进程: 是程序在执行过程中的一个实例。每个进程都有独立的内存空间、系统资源,相互之间不直接共享。
- 线程: 是进程中的一个执行单元,是CPU调度和分派的基本单位。线程在同一个进程内共享相同的内存空间和系统资源。
-
资源分配:
- 进程: 每个进程有独立的地址空间和系统资源,彼此独立,相互不干扰。
- 线程: 同一进程内的线程共享相同的地址空间和系统资源,包括文件描述符、信号处理等。
-
通信和同步:
- 进程: 进程间通信相对复杂,需要使用进程间通信(IPC)机制,如管道、消息队列、共享内存等。
- 线程: 线程之间可以通过共享的内存直接进行通信,但需要考虑同步的问题,以避免竞态条件等并发问题。
-
切换代价:
- 进程: 进程切换的代价较高,因为需要保存和恢复整个进程的状态,包括内存空间、寄存器等。
- 线程: 线程切换的代价相对较低,因为线程共享相同的地址空间,切换时只需要保存和恢复线程私有的寄存器即可。
-
创建和销毁开销:
- 进程: 创建和销毁进程的开销相对较大,涉及到内存分配、初始化等操作。
- 线程: 创建和销毁线程的开销相对较小,因为线程共享进程的地址空间。
-
独立性:
- 进程: 进程是独立的执行单位,一个进程的崩溃通常不会影响其他进程。
- 线程: 线程是进程的一部分,一个线程的崩溃可能会影响同一进程内的其他线程。
-
适用场景:
- 进程: 适用于需要独立执行、相互隔离、稳定性要求较高的场景。
- 线程: 适用于需要并发执行、共享数据、资源开销较小的场景。
在实际应用中,进程和线程各有其优势和适用场景,开发者根据具体需求选择合适的并发模型。在某些情况下,同时使用进程和线程(多进程多线程)来充分利用多核处理器和提高系统性能。
- TCP与UDP的区别(✔)
TCP(Transmission Control Protocol)和UDP(User Datagram Protocol)是两种不同的传输层协议,用于在计算机网络中实现数据传输。它们之间有一些重要的区别:
-
连接性:
- TCP: 提供面向连接的服务,通过三次握手建立连接。在数据传输前,需要先建立连接,然后再进行数据传输,最后释放连接。
- UDP: 是一种面向无连接的协议,不需要在传输数据前建立连接,直接发送数据包。每个数据包独立存在,互相之间没有关联。
-
可靠性:
- TCP: 提供可靠的数据传输。通过序号、确认和重传机制来确保数据的可靠性,保证数据按顺序到达且不丢失。
- UDP: 不提供可靠性保证。数据包可能会丢失或者乱序,不进行重传。
-
流量控制和拥塞控制:
- TCP: 包含流量控制和拥塞控制机制,通过动态调整窗口大小和使用慢启动等算法来适应网络状况,防止过多的数据注入网络导致拥塞。
- UDP: 不提供流量控制和拥塞控制,数据包可能会因为网络拥塞而丢失。
-
数据量:
- TCP: 适用于大量数据传输,因为它可以分段传输大数据并确保完整性。
- UDP: 适用于小量数据传输,因为它不提供数据分段和完整性保证。
-
延迟:
- TCP: 由于连接的建立和维护,以及流量控制和拥塞控制的机制,可能会引入一定的延迟。
- UDP: 由于是无连接的,通常具有较低的延迟。
-
应用场景:
- TCP: 适用于要求可靠传输、顺序传输、流量控制和拥塞控制的应用,如网页浏览、文件传输、邮件等。
- UDP: 适用于实时性要求较高、数据量较小,且可以容忍一定数据丢失的应用,如音频和视频流、在线游戏。
总体而言,选择使用TCP还是UDP取决于应用的需求和性质。 TCP适用于对数据可靠性要求较高的场景,而UDP适用于对实时性要求较高且可以容忍一定数据丢失的场景。
- Linux常用的指令问了两个但是只回答上来一个是ps,另外一个忘记了(×)
在 Linux 系统中,ps
(process status)指令用于显示当前运行进程的状态信息。ps
命令的使用格式如下:
ps [options]
ps aux
: 显示所有用户的所有进程信息,包括用户、PID(进程ID)、CPU利用率、内存利用率等。ps -ef
: 显示所有进程的全面信息,包括父进程ID(PPID)、进程状态等。ps -e
: 显示系统上所有正在运行的进程的基本信息。ps -u username
: 显示指定用户的进程信息。ps -p pid
: 显示指定进程ID的进程信息。ps -o
: 允许用户自定义显示的列。可以指定想要显示的列,如ps -o pid,user,cmd
。ps -H
: 显示进程的层次关系(树状结构),包括父进程和子进程。ps --forest
: 以树状结构显示进程层次关系。
Linux查看端口号的指令
-
netstat命令:
netstat -tulpn
该命令会列出所有正在运行的服务及其对应的端口号。其中,
-t
表示显示TCP端口,-u
表示显示UDP端口,-l
表示仅显示监听的端口,-p
表示显示进程名称,-n
表示显示数字形式的端口号。 -
ss命令:
ss -tulpn
类似于
netstat
,ss
命令也用于查看套接字统计信息。上述选项与netstat
的选项相同,分别表示TCP端口、UDP端口、监听状态、进程名称和数字形式的端口号。 -
lsof命令:
lsof -i
该命令会列出所有打开的文件,包括网络连接。通过
-i
选项,你可以过滤出与网络相关的信息。 -
查看特定端口是否被占用(例如,端口号为8080):
lsof -i :8080
-
使用
ss
和grep
来查找特定端口号(例如,端口号为80):
ss -tulpn | grep :80
- 写了一段SQL代码,从给有姓名,钱数,id的表中筛出来钱数大于表中平均钱数的人的名字(✔)
SELECT name
FROM your_table
WHERE money > (SELECT AVG(money) FROM your_table);
- 设计抖音的点赞功能的测试用例(✔算是吧 毕竟回答了6,7条)
设计抖音点赞功能的测试用例需要覆盖各种情况,确保功能在不同条件下正常工作。以下是一些可能的测试用例:
-
基本点赞功能测试:
- 用户在观看视频时,尝试给视频点赞。
- 验证点赞数是否正确增加。
- 验证用户的点赞状态是否正确显示。
-
取消点赞功能测试:
- 用户在观看视频时,给视频点赞,然后取消点赞。
- 验证点赞数是否正确减少。
- 验证用户的点赞状态是否正确更新。
-
重复点赞测试:
- 用户多次连续给同一视频点赞。
- 验证点赞数是否只增加一次。
-
多视频点赞测试:
- 用户在观看多个视频时,分别给不同视频点赞。
- 验证各个视频的点赞数是否正确增加。
-
非登录状态点赞测试:
- 验证是否需要登录才能进行点赞操作。
- 如果需要登录,验证在未登录状态下进行点赞的行为。
-
网络状态测试:
- 在网络正常的情况下进行点赞操作。
- 在网络不稳定或断开的情况下进行点赞操作。
-
点赞通知测试:
- 确保用户在点赞后能收到相关的通知。
- 验证通知内容是否正确。
-
视频作者收到点赞通知测试:
- 确保视频作者在其视频被点赞后能收到通知。
- 验证通知内容是否正确。
-
大量点赞测试:
- 模拟大量用户对同一视频进行点赞。
- 验证系统在大量点赞时的性能和稳定性。
-
异常输入测试:
- 尝试使用无效的视频ID进行点赞。
- 尝试在点赞时输入特殊字符或非法字符。
-
同步点赞信息测试:
- 验证用户在不同设备上点赞操作是否同步。
- 确保在一个设备上的点赞状态能在其他设备上正确反映。
-
反复刷新测试:
- 用户在短时间内多次刷新页面,验证点赞数和点赞状态是否正确。
这些测试用例涵盖了点赞功能的各个方面,包括基本功能、边界条件、异常情况、性能和用户体验等方面。
- 写一段字符串转int的代码要符合软件测试的标准想到各种情况,就是实现string转int的类函数10min后验收(写了测试不合法字符,转int越界了等共计三种情况吧,最后面试官说不行 没有判断第一位正负号的问题)
def str_to_int(s):
if not s:
return 0
s = s.strip() # 去除首尾空格
if not s:
return 0
sign = 1
result = 0
i = 0
# 处理正负号
if s[0] == '-':
sign = -1
i += 1
elif s[0] == '+':
i += 1
# 转换数字部分
while i < len(s) and s[i].isdigit():
result = result * 10 + int(s[i])
i += 1
result *= sign
# 处理溢出情况
INT_MAX = 2**31 - 1
INT_MIN = -2**31
result = max(min(result, INT_MAX), INT_MIN)
return result
# 测试用例
print(str_to_int("42")) # 42
print(str_to_int(" -42")) # -42
print(str_to_int("4193 with words")) # 4193
print(str_to_int("words and 987")) # 0
print(str_to_int("-91283472332")) # -2147483648 (溢出情况)
print(str_to_int("")) # 0 (空字符串)
print(str_to_int(" ")) # 0 (只有空格)
print(str_to_int("+1")) # 1 (带正号)
print(str_to_int(" +0 123")) # 0 (包含非数字字符)
- 快排的思想(✔)
选择基准值(Pivot): 从待排序的数据中选择一个基准值。选择基准值的方式可以有多种,常见的方法包括选择第一个元素、最后一个元素、中间元素,或者随机选择一个元素。
划分操作(Partition): 将待排序的数组按照基准值进行划分,使得基准值左边的元素都小于基准值,右边的元素都大于基准值。同时,基准值所在的位置在最终排序结果中也是正确的。
递归排序: 对基准值左右两侧的子数组分别进行递归排序。对左右子数组的排序过程,仍然采用选择基准值和划分的操作。
合并结果: 递归过程会将左右子数组排序完成,最终合并得到完整的有序数组。
之后让我问了问她有没有什么相关问题
我问了两个:
- 如果录取了什么时候入职有统一时间吗?(实习生按天结工资,什么时候来什么时候入职)
- 入职可以开实习证明吗?(可以)
总结:
一面还是过了,通知下周专业的二面(很慌)
由于一点工作经验也没有在面试时就特别被动,然后由于只准备了一早上啥也没看到就靠之前学的一点老底子来撑过来(虽然之前学的也很烂),总之还是要在面试前认真准备一下,复习一些经典的问题之类的。
12.15 二面
上来先寒暄了十分钟左右,自我介绍后问了问基本情况成绩排名以及自己的课外情况。
然后写了一道简单的语法题: 找出在两个字符串中共同出现的字符,并且分别找出其出现的次数。 但令我难绷的是面试官在那以后几十就再也没关过代码页面,也不知道自己以后的答案怎么样
接下来就是问了问基本的问题了
- python的集合是什么? (×)我把集合和字典记混了还以为他问的是一种没见过的数据结构
在Python中,集合(Set)是一种无序、可变的数据类型,用于存储不重复的元素。集合的主要特点是元素之间没有顺序关系,并且每个元素都是唯一的。
Python中的集合用大括号 {}
表示,其中的元素之间用逗号分隔。
- 学过Linux吧那么要读取一个文件后十行中含有字符串“abc”的行该用什么命令? (√?)
命令回答对了但是awk的print出错了
cat filename | awk 'END {for (i=NR-9;i<=NR;i++) print $0}' | grep .
还有一种更好的实现方法tail
命令但是我第一时间没想起来
cat filename | tail -n 10 | grep "abc"
- c++的虚函数是什么在什么地方会应用到虚函数? (√)
在C++中,虚函数(Virtual Function)是为了支持面向对象编程(Object-Oriented Programming)中的多态性(Polymorphism)而引入的一种机制。虚函数允许在基类中声明一个函数,然后在派生类中对该函数进行重写(覆盖)。通过虚函数,可以在运行时根据实际对象的类型来调用相应的函数实现,这就是动态多态性。
虚函数通常应用于以下场景:
-
多态性: 当希望以统一的方式处理不同类型的对象时,可以使用虚函数实现多态性,通过基类指针或引用调用派生类的特定函数。
-
框架和库设计: 在设计框架和库时,虚函数使得用户能够通过继承和重写来定制框架的行为,而不需要修改框架的源代码。
-
接口和抽象类: 虚函数用于定义接口和抽象类,它们包含虚函数的声明但没有提供具体的实现。
- 数据库中索引有什么作用? 在数据库中有几类索引? (×)
只回答出索引的作用寄。
索引在数据库中起到加速查询和提高检索效率的作用。通过使用索引,数据库系统可以更快速地定位到包含特定值的行,而不必扫描整个表。索引类似于书籍的目录,可以根据关键词(索引键)快速找到特定内容(表中的行)。
在数据库中,主要有以下几类索引:
-
主键索引(Primary Key Index): 主键是唯一标识表中每一行的字段,主键索引用于加速主键的检索。数据库系统会自动为主键创建索引,确保主键的唯一性和快速检索。
-
唯一索引(Unique Index): 唯一索引确保某一列或一组列的值是唯一的,类似于主键索引,但允许有一个NULL值。唯一索引可用于加速唯一性检查,提高查询效率。
-
聚簇索引(Clustered Index): 聚簇索引决定了数据在物理存储上的顺序,表中的数据按照聚簇索引的顺序进行存储。一个表只能有一个聚簇索引,通常是主键索引。由于数据存储的物理顺序与索引顺序一致,聚簇索引的使用可以提高范围查询的性能。
-
非聚簇索引(Non-clustered Index): 非聚簇索引的数据存储顺序与索引顺序不一致,每个索引项包含指向实际数据行的指针。一个表可以有多个非聚簇索引。非聚簇索引通常用于加速检索而不影响数据的物理存储顺序。
-
复合索引(Composite Index): 复合索引是由表中多个列组合而成的索引。复合索引可以提高涉及复合索引列的查询性能,但同时也增加了索引的维护成本。
-
全文索引(Full-Text Index): 用于全文搜索的索引,支持在文本字段上进行全文本搜索。全文索引通常用于处理大量文本数据,如文章、博客等。
-
空间索引(Spatial Index): 用于处理空间数据类型(如几何对象)的索引。空间索引可以加速空间查询,例如地理信息系统(GIS)中的地理位置查询。
还有个1,2道题我记不清了就这样吧
- python的闭包是什么?
闭包(Closure)是指在一个函数内部定义的函数,并且这个内部函数可以访问外部函数的局部变量。闭包使得内部函数拥有了外部函数的作用域,即使外部函数已经执行完毕,内部函数仍然可以访问外部函数的变量。在 Python 中,闭包通常用来实现一种数据封装和保护的机制。
之后就是一些观念性的问题了,
- 你怎么认识软件测试工程师这个岗位从哪里了解到这类知识的?(回答被指出有些片面)
- 你是选择这个岗位的动机是什么为什么不试试后端开发岗位?(我也想但不是后端开发的把我拒了或者还没给我面试吗? 我回答的可能让面试官有点不开心,因为我说后端开发难度大,于是他在后面多次强调测试难度也大,甚至快结束面试还专门强调这一点)
- 你觉得一个合格软件测试工程师需要具备什么?
- 分析一下你为什么适合这个岗位?
- 如果你打算在这个岗位深造的话你会对你的未来有什么规划?
最后就是反问环节:
- 测试的具体要和什么人或者团队对接,对接流程有什么?
- 如果我参加工作那么会负责一个新的开发项目的测试还是从别人那里接手呢?
- 如果参加工作那么会不会有人带着培训几天呢?
总结:
二面比较失败有几个简单的问题都没答上来导致后期心态有点炸裂面试官的问题回答的也避重就轻片面的反应测试岗难度低,让面试官有点不开心。就冲这些回答就算是把我拒了也认了,12.16还在等通知……
果然没过hhhh
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· winform 绘制太阳,地球,月球 运作规律
· 超详细:普通电脑也行Windows部署deepseek R1训练数据并当服务器共享给他人
· 上周热点回顾(3.3-3.9)
· AI 智能体引爆开源社区「GitHub 热点速览」
· 写一个简单的SQL生成工具