求职 记一次高级测试岗位面试经历

大海 · 2018年10月23日 · 最后由 phoenix 回复于 2023年10月08日 · 5096 次阅读
  • 面试岗位:测试开发/高级测试工程师/自动化测试工程师
  • 面试次数:N 轮
  • 坐标:苏州

笔试面试的内容没有全部写全,有的已经记不得了。只贴通用性的技术相关的笔试面试题,至于说测试理论和团队管理的问题,没有写出来,都是大同小异,也没什么实际的参考价值。

  1. 直接手写一个 python 类
  2. 直接手写一个构造函数
  3. 紧接着上面的代码,直接手写,补充完整代码,要求对列表中的人进行排序,并筛选出分数大于 80 的人的名单,组成一个新的列表显示出来。
class Person:
    def __init__(self, name, gender, age):
        self.name = name
        self.gender = gender
        self.age = age


class Student(Person):
    def __init__(self, name, gender, age,score):
        super(Student, self).__init__(name, gender, age)
        self.score = score

People = [kathy, Jim, John, Alice, Leo]

  1. python 的高阶函数有哪些,分别都有什么作用?
  2. 简单说说生成器,迭代器,装饰器是什么,都有哪些作用?
  3. Python 中,如何将字符串转化为整型?
  4. TCP 三次握手和四次挥手,请分别直接写出来
  5. HTTP 常见的状态码有哪些?都是什么含义?
  6. webdriver 的核心原理是什么?
  7. appium 是什么?主要用来做什么的?它的核心原理是什么?
  8. selenium1 和 selenium2 的区别是什么,为何要抛弃 selenium1?它有什么缺陷?
  9. 常见的元素定位方法有哪些?
  10. 直接手写一个冒泡排序和快速排序,时间复杂度是多少?空间复杂度是多少?是否稳定?
  11. 如何查询 Linux 后台日志,直接写出命令
  12. 如何查看当前进程?
  13. Dockerfile 是什么?如何去创建一个 Dockerfile?
  14. Python 有没有垃圾回收机制?它又是通过什么来的?
  15. 熟悉 TESTNG,那请说一下 TESTNG 的用法?
  16. 熟悉 JAVA,那请直接手写一个单例模式?
  17. 数据库增删改查,手写 SQL
  18. redis 是做什么用的?elasticsearch 是什么?做什么用的?
  19. 接口测试怎么做的?如果存在接口依赖关系,怎么做?
  20. 元祖和列表的区别是什么?
  21. Python 中,arg 和*kwarg 分别代表什么含义,都有哪些作用?
  22. 写过爬虫,那请说一下常见的反爬机制有哪些?如果是动态加载的页面,看不到数据,如何去进行爬取?

ChatGPT2023年7月12日补充答案:

1、Python 的高阶函数包括:

  • map(func, iterable):对可迭代对象中的每个元素应用函数,并返回一个新的迭代器。
  • filter(func, iterable):根据函数的返回值是 True 还是 False 来过滤可迭代对象中的元素,并返回一个新的迭代器。
  • reduce(func, iterable[, initializer]):对可迭代对象中的元素进行累积运算,返回一个结果。
  • sorted(iterable[, key][, reverse]):对可迭代对象进行排序,并返回一个新的列表。

2、生成器(Generator)是一种特殊的迭代器,它可以用于按需生成数据,而不是一次性生成所有数据。迭代器(Iterator)是访问集合元素的一种方式,它提供了一个统一的接口来遍历容器对象的元素。装饰器(Decorator)是 Python 中用于在不改变原函数代码的情况下,给函数动态添加功能的一种语法。

  • 生成器可以使用普通函数的形式定义,使用 yield 关键字来暂停和恢复函数的执行,生成器函数返回的是一个生成器对象,可以通过调用 next() 来逐步获取生成器的值。
  • 迭代器通过实现iter() 和next() 这两个特殊方法,使得对象可以按照一定的顺序返回集合的元素。
  • 装饰器可以使用 @ 语法来装饰函数,在函数调用前后添加额外的功能,例如日志记录、性能分析等。

3、将字符串转化为整型可以使用 int() 函数,例如:num = int("123")。如果字符串不能被正确转化为整型,则会抛出 ValueError 异常。

4、TCP 三次握手和四次挥手:

  • 三次握手:
    • 客户端发送 SYN 包,进入 SYN_SENT 状态。
    • 服务器端接收到 SYN 包,发送 SYN+ACK 包,进入 SYN_RCVD 状态。
    • 客户端接收到 SYN+ACK 包,发送 ACK 包,建立连接,进入 ESTABLISHED 状态。
  • 四次挥手:
    • 客户端发送 FIN 包,进入 FIN_WAIT_1 状态。
    • 服务器端接收到 FIN 包,发送 ACK 包,进入 CLOSE_WAIT 状态。
    • 服务器端关闭连接,发送 FIN 包,进入 LAST_ACK 状态。
    • 客户端接收到 FIN 包,发送 ACK 包,进入 TIME_WAIT 状态。
    • 等待一段时间后,客户端关闭连接,进入 CLOSED 状态,服务器端接收到 ACK 包后也进入 CLOSED 状态。

5、HTTP 常见的状态码包括:

  • 200 OK:请求成功。
  • 301 Moved Permanently:永久重定向。
  • 302 Found:临时重定向。
  • 400 Bad Request:请求错误。
  • 404 Not Found:资源未找到。
  • 500 Internal Server Error:服务器内部错误。

6、webdriver 的核心原理是通过与浏览器进行通信,控制浏览器的行为和获取浏览器中的信息。它通过自动化驱动程序,如 ChromeDriver、GeckoDriver 等,与浏览器建立连接,并通过命令传递操作指令给浏览器。

7、Appium 是一个开源的移动应用自动化测试框架,主要用于自动化测试移动应用程序。它可以用于测试 iOS 和 Android 平台上的原生应用、混合应用和移动网页应用。Appium 的核心原理是通过发送特定的命令到移动设备或模拟器上来进行操作,如模拟点击、输入文本等。

8、Selenium1 和 Selenium2(也称为 Selenium WebDriver)的区别在于:
Selenium1 采用的是基于 JavaScript 的自动化测试框架,通过模拟用户的操作来进行测试。它可以与各种浏览器交互,但是与浏览器的通信是通过 JavaScript 脚本实现的。因此,Selenium1 的性能较慢,并且对浏览器的兼容性有限。

Selenium2(WebDriver)是一个基于原生浏览器的自动化测试框架。它直接与浏览器进行通信,而不是通过 JavaScript 脚本。通过浏览器的原生支持,Selenium WebDriver 可以更快地执行测试操作,并且具有更好的兼容性。

所以为了提高性能和扩展性,Selenium 社区决定抛弃 Selenium1 并转向 Selenium WebDriver。

Selenium1 的缺陷包括:

  • 性能较慢:Selenium1 的测试执行速度较慢,因为它需要通过 JavaScript 与浏览器进行通信。
  • 兼容性有限:Selenium1 对各种浏览器的支持有限,无法满足多平台、多浏览器的需求。
  • 受 JavaScript 限制:Selenium1 的测试脚本需要使用 JavaScript 语言编写,对非开发人员来说不够直观和易用。

通过使用 Selenium WebDriver,这些问题得到了解决,并提供了更好的性能、更广泛的浏览器支持以及更友好的 API,使得自动化测试变得更加高效和便捷。

9、常见的元素定位方法包括:

  • ID 定位:使用元素的 ID 属性进行定位,通过find_element_by_id()方法进行操作。
  • Name 定位:使用元素的 Name 属性进行定位,通过find_element_by_name()方法进行操作。
  • Class Name 定位:使用元素的 Class 属性进行定位,通过find_element_by_class_name()方法进行操作。
  • Tag Name 定位:使用元素的标签名进行定位,通过find_element_by_tag_name()方法进行操作。
  • Link Text 定位:使用链接文本进行定位,通过find_element_by_link_text()方法进行操作。
  • Partial Link Text 定位:使用链接的部分文本进行定位,通过find_element_by_partial_link_text()方法进行操作。
  • CSS Selector 定位:使用 CSS 选择器进行定位,通过find_element_by_css_selector()方法进行操作。
  • XPath 定位:使用 XPath 表达式进行定位,通过find_element_by_xpath()方法进行操作。

10、冒泡排序的实现:

def bubble_sort(arr):
    n = len(arr)
    for i in range(n - 1):
        for j in range(n - i - 1):
            if arr[j] > arr[j + 1]:
                arr[j], arr[j + 1] = arr[j + 1], arr[j]
时间复杂度最好情况下是O(n)即列表已经是有序的最坏情况下是O(n^2)即列表逆序排序平均情况下是O(n^2)
空间复杂度O(1)

快速排序的实现:

def quick_sort(arr):
    if len(arr) <= 1:
        return arr
    pivot = arr[len(arr) // 2]
    left = [x for x in arr if x < pivot]
    middle = [x for x in arr if x == pivot]
    right = [x for x in arr if x > pivot]
    return quick_sort(left) + middle + quick_sort(right)
时间复杂度最坏情况下是O(n^2)即列表已经是有序或逆序排序平均情况下是O(nlogn)
空间复杂度最坏情况下是O(n)平均情况下是O(logn)

这两个算法都是稳定的,即相等元素的相对顺序在排序前后保持不变。

11、查询 Linux 后台日志的命令可以使用tail命令,例如:

tail -n 100 /path/to/logfile

这个命令将显示日志文件的最后 100 行内容。

12、查看当前进程的命令可以使用ps命令,例如:

ps aux

这个命令将显示当前系统的所有进程列表。

13、Dockerfile 是用于构建 Docker 镜像的文本文件,它包含了一系列指令和配置,用于定义镜像的构建流程。通过 Dockerfile,可以自动化地构建、部署和管理 Docker 镜像。

创建一个 Dockerfile 的步骤:

  1. 在一个空白目录下创建一个名为 Dockerfile 的文件。
  2. 编辑 Dockerfile 并编写所需的指令,例如 FROM、RUN、COPY 等。
  3. 保存 Dockerfile。
  4. 使用docker build命令来构建镜像,例如docker build -t image_name:tag .

14、Python 有垃圾回收机制,它的垃圾回收是通过引用计数和循环垃圾回收来实现的。

  • 引用计数:Python 中的每个对象都有一个引用计数器,用来记录有多少个引用指向该对象。当引用计数为 0 时,表示该对象不再被使用,可以被回收。
  • 循环垃圾回收:Python 中通过循环垃圾回收(Cycle Garbage Collection)来处理循环引用的情况,即一组对象之间互相引用形成了一个循环,导致引用计数不为零,无法被回收。循环垃圾回收器会定期扫描内存中的对象,并检查是否存在循环引用的情况。如果发现某个对象不再可达(没有其他对象引用它),则将其回收。

15、TESTNG 是一个功能强大的 Java 测试框架,它提供了丰富的注解、断言和报告功能,使得测试编写、执行和管理更加灵活和方便。下面是一些 TESTNG 的用法:

  • 定义测试:

    • 使用@Test注解来标记测试方法。
    • 使用@BeforeSuite@AfterSuite@BeforeTest@AfterTest等注解来标记测试套件级别和测试级别的前置条件和后置操作方法。
    • 使用@DataProvider注解来提供测试数据。
  • 配置测试:

    • 使用@BeforeClass@AfterClass@BeforeMethod@AfterMethod等注解来标记测试类和测试方法级别的前置条件和后置操作方法。
    • 使用@Parameters注解来定义测试方法的参数。
  • 执行测试:

    • 使用TestNG.xml配置文件来指定执行的测试套件、测试类、测试方法等。
    • 在命令行使用testng命令来执行 TestNG 测试。
  • 断言和报告:

    • 使用 TestNG 提供的断言方法来验证测试结果,如assertEquals()assertTrue()等。
    • TestNG 提供了丰富的报告功能,可以生成详细的测试报告,包括测试结果、错误信息等。

通过使用 TESTNG,可以实现灵活的测试编写和管理,提高测试的可读性和可维护性,同时还能生成详尽的测试报告,方便问题追踪和分析。

16、JAVA 单例模式的实现可以有多种方式,以下是一种常见的基于懒汉式的单例模式示例代码:

public class Singleton {
    private static Singleton instance;

    private Singleton() {
        // 私有构造方法
    }

    public static synchronized Singleton getInstance() {
        if (instance == null) {
            instance = new Singleton();
        }
        return instance;
    }
}

在这个示例中,构造方法被声明为私有,以防止类的外部实例化。通过 getInstance() 方法获取类的唯一实例。在第一次调用 getInstance() 时,会创建一个新的实例。之后的调用将直接返回已创建的实例。需要注意的是,由于线程安全问题,getInstance() 方法使用了 synchronized 关键字来保证线程安全性。

17、以下是一个简单的示例,手写增删改查的 SQL 语句:

  • 插入数据:
INSERT INTO table_name (column1, column2, column3,...) VALUES (value1, value2, value3,...)
  • 查询数据:
SELECT column1, column2, ... FROM table_name WHERE condition
  • 更新数据:
UPDATE table_name SET column1 = value1, column2 = value2, ... WHERE condition
  • 删除数据:
DELETE FROM table_name WHERE condition

其中,table_name 是表名,column1, column2 等是列名,value1, value2 等是对应的值,condition 是查询或删除的条件。

请根据实际情况替换表名、列名、值和条件。

18、Redis 是一种开源的高性能键值对存储数据库,通常被用作缓存、消息队列或临时数据存储等。Redis 支持多种数据结构,如字符串、哈希表、列表、集合和有序集合等,具有快速读写性能、持久化、发布 - 订阅等特性。

Elasticsearch 是一个开源的分布式搜索和分析引擎,基于 Apache Lucene 构建。它支持全文搜索、结构化搜索、分布式搜索、实时搜索等功能。Elasticsearch 主要用于构建实时的应用程序,如日志分析、复杂的搜索应用程序、数据挖掘等。

19、接口测试通常需要发送 HTTP 请求,并验证服务器的响应是否符合预期。常见的做法是使用测试框架,如 JUnit 或 TestNG,并结合某种 HTTP 客户端库,如 Apache HttpClient 或 OkHttp,来进行自动化测试。

如果存在接口依赖关系,可以使用以下几种方法来解决:

  1. 串行依赖:按照接口依赖的顺序进行测试,确保前一个接口的结果可以作为后一个接口的输入。

  2. 并行依赖:使用多线程或并发测试框架,同时发送多个接口请求,并在所有请求完成后验证结果。

  3. 模拟依赖:使用模拟工具或框架,如 Mockito 或 WireMock,来模拟依赖接口的返回结果,以便独立进行测试。

具体的方法取决于具体的测试场景和需求。

20、元组(Tuple)和列表(List)是 Python 中的两种不同的数据类型。

元组是一种不可变序列,它可以包含任意类型的元素,使用小括号 () 表示。元组的元素可以通过索引来访问,但不能修改。例如:

tup = (1, "a", True)
print(tup[0])  # 输出: 1

列表是一种可变序列,它可以包含任意类型的元素,使用方括号 [] 表示。列表的元素可以通过索引来访问和修改。例如:

lst = [1, "a", True]
print(lst[0])  # 输出: 1

lst[0] = 2
print(lst[0])  # 输出

21、在 Python 中,*args**kwargs是用来处理函数传入的可变数量的参数的特殊语法。

  • *args可以接收任意数量的位置参数,它将这些参数作为一个元组 (tuple) 传递给函数。通常用于不确定传入参数个数的情况。

示例代码:

def my_function(*args):
    for arg in args:
        print(arg)

my_function("Hello", "World", 2023)
# 输出: Hello
#       World
#       2023
  • **kwargs可以接收任意数量的关键字参数,它将这些参数作为一个字典 (dictionary) 传递给函数。通常用于需要接收可变数量的关键字参数的情况。

示例代码:

def my_function(**kwargs):
    for key, value in kwargs.items():
        print(key, value)

my_function(name="John", age=25, city="New York")
# 输出: name John
#       age 25
#       city New York

argskwargs只是约定俗成的命名,你也可以使用其他的参数名,但通常建议遵循这两个命名约定。

22、常见的反爬机制有以下几种:

  • User-Agent 识别:通过检查请求的 User-Agent 头部信息,来判断请求是否来自浏览器。常见的解决方法是在 HTTP 请求的头部中添加一个合法的 User-Agent。

  • IP 封禁:如果爬虫频繁请求某个 IP 地址,可能被目标网站的防爬系统封禁该 IP。解决方法可以使用代理 IP,轮流切换 IP 地址,以避免封禁。

  • 页面解析限制:网站可能通过 JavaScript、验证码、动态生成的内容等方式来阻止爬虫获取数据。解决方法是模拟浏览器行为,使用工具如 Selenium 来自动化解析 JS 和处理验证码。

  • 请求频率限制:网站可能会限制单位时间内的请求次数,超过限制可能会导致封禁 IP 或返回错误页面。解决方法是使用合理的请求间隔时间,模拟人类操作的频率。

对于动态加载的页面,可以使用以下几种方法进行爬取:

  • 分析 XHR 请求:动态加载的数据通常是通过异步请求 (XHR/AJAX) 获取的。可以通过浏览器开发者工具 (Network 面板) 或者抓包工具查看网页的请求,找到 XHR 请求的 URL 和参数,模拟发送请求来获取数据。

  • 使用动态渲染技术:使用工具如 Selenium 或 Pyppeteer 模拟浏览器行为,完全加载和渲染页面后再提取数据。

  • 解析 JavaScript 代码:有些页面使用 JavaScript 动态生成数据,可以使用 JavaScript 解释器如 PyExecJS 来执行网页中的 JavaScript 代码,并提取所需数据。

需要根据具体情况选择合适的方法来应对反爬机制和动态加载页面。注意在爬取数据时要遵守网站的规则,避免对网站造成不必要的压力和干扰。

如果觉得我的文章对您有用,请随意打赏。您的支持将鼓励我继续创作!
最佳回复

高级测试、自动化测试和测试开发,从成本角度讲,一般公司不会设置 3 个岗位,时代在变化,用人成本也在变化,要跟上时代

大海 回复

我也发现了,目前他们的招聘启示就是不区分高级测试、自动化测试和测试开发的,招聘的人不懂测试具体怎么实施,很多觉得三者是一致的。

共收到 37 条回复 时间 点赞

对面高级测试岗位还问冒泡排序的面试官表示不解

表示都还不会,感谢分享😀

匿名 #3 · 2018年10月23日

多少薪资的岗位啊 惊讶的发现我居然都知道 😊

一个测试理论的问题都没?数据库的问题也没?这么神奇

什么公司? 面试的这么细?

chen 回复

测试理论大同小异,就不写了。

前几天也面试来着,面试官想问我 python,我直接回复不会,直接话头断了,哈哈

僅樓主可見
bruce 回复

A 接口依赖 B 接口,或者 A 接口依赖第三方接口这种关系

僅樓主可見
11楼 已删除
僅樓主可見
大海 #13 · 2018年10月23日 Author
bruce 回复

我的回答和你说的基本上是一样的,目前常用的也就这几种方法

槽神 回复

大佬准备换工作了?

大海 回复

用 mock 来解除依赖吧

好可怕,好多都不会

问什么快速排序,根本记不住。每次面试前看看而已,要问就问哪种排序算法比较快嘛。

问的这么细,实际中都能用到吗

blackcoffee 回复

大佬只是定期面试,keep fresh

槽神 回复

优秀

。。。。。我不明白问这么细有什么用

真没觉得哪个问题问的细了……考察基本功啊,别问有啥用了,这体现你工作扎实程度和学习能力

楼主,没人问项目么?
项目用什么说什么,技术带来价值,你这问的也太杂了点吧。。。

大海 #24 · 2018年10月23日 Author
magicyang 回复

这是肯定要问的,只是没啥参考价值,就不写了

大海 回复

我个人觉得更考察项目吧,我就觉得问题太杂了,就算 30% 甚至更多回答的不太好,也不会影响大佬拿 OFFER 吧。。。

大海 #26 · 2018年10月23日 Author
magicyang 回复

我到现在都不清楚对方是面的测试开发,高级测试还是自动化测试,这三者并没有一个很明确的区分。

gallon 回复

面试造航母实际拧螺丝。

是要找个会造航母的人来拧螺丝

题目还好,日常基本都会用到。Dockerfile 我回答不出来,很少用。

面试不都是按照你的简历上的东西问的吗,比如你说你会 Node ,他肯定会问你 Node 有关的问题,你写过自动化框架,他也会问你是如何设计的,我要是没写我会 Java ,估计他也不会问 Java 有关的吧。

基本全会,但是还没有达到测试开发的水平

TCP、Dockerfile、java 不会,其他的大概了解,感觉狠狠的落后于第一梯队了啊

robert 回复

招聘的其实不只是高级测试,而是初级测试开发

大海 回复

我也发现了,目前他们的招聘启示就是不区分高级测试、自动化测试和测试开发的,招聘的人不懂测试具体怎么实施,很多觉得三者是一致的。

高级测试、自动化测试和测试开发,从成本角度讲,一般公司不会设置 3 个岗位,时代在变化,用人成本也在变化,要跟上时代

我真的觉得,如果你说是 web 端测试,最好的方法是自己写一个 web,面试遇到的那些问题就不会阻碍到了。也好像面试官展示,我自己写了个,直接介绍你的 web 内容。

李秋 回复

一般是一个岗位负责全部

哪家公司啊,这得开多少工资啊?

需要 登录 後方可回應,如果你還沒有帳號按這裡 注册