大厂面试题
目录
ArrayList 和 LinkedList 的区别是什么?
python 装饰器是什么?其作用是什么? 装饰器的原理与实现?
三种等待方式分别是什么,有什么区别?显式等待与隐式等待的区别?
mysql 几个存储引擎,innodb 和 MyISAM 区别
主从底层数据同步机制、binglog、redolog、undolog 区别
为什么使用 redis,redis 五种数据类型,如何测试 redis 的,项目中如何应用的
selenium框架的driver调用quit方法和调用close方法的区别是什么?
如何查看日志里面有 error 关键字的日志记录,与这个记录前后三行的日志信息
进程和线程是操作系统中最基本的概念。
进程是操作系统中资源分配的基本单位。每个进程拥有独立的内存空间和系统资源,包括文件句柄、网络连接等。每个进程都有自己的地址空间,在进程间不共享内存,进程间通信需要通过进程间通信机制来实现。进程可以创建子进程,子进程和父进程共享一部分数据,或者复制父进程的所有数据,但是子进程的数据空间是独立的。
线程是进程内部的执行单位,一个进程可以创建多个线程,线程共享进程的地址空间和系统资源。线程与进程不同的是,线程不拥有独立的内存空间,不支持单独的调度和资源管理,而是由进程来负责调度和管理。线程可以共享进程的全局变量和静态变量,但是每个线程都有自己的栈和局部变量,使得线程之间的数据相互独立。
总体来说,进程和线程的主要区别在于:
- 资源管理:进程是系统资源的分配和调度的基本单位,线程是进程内部任务调度和执行的基本单位。
- 内存空间:每个进程有自己独立的内存空间,线程共享进程的地址空间。
- 开销:创建和撤销进程的开销大,包括内存空间的分配和初始化、资源申请和释放等;线程的开销较小,创建和撤销的速度较快。
总的来说,线程是基于进程内部实现的一种轻量级机制,可以实现更细粒度的并发控制,提高系统的并发性能。
HashMap 和 HashTable 的区别
HashMap 和 HashTable 都是 Java 中的哈希表实现,他们最大的区别在于线程安全性、性能和迭代器的一致性。
1. 线程安全性:
- HashMap 不是线程安全的,多个线程可以同时访问同一个 HashMap 实例,需要自行保证线程安全。
- HashTable 是线程安全的,其中的方法都是通过 synchronized 关键字实现同步的,但是会导致性能下降。
2. 性能:
- 由于 HashTable 所有方法都是同步的,所以它的性能不如 HashMap。
- 当然,如果需要线程安全的哈希表,使用 ConcurrentHashMap 比 HashTable 更好。
3. 迭代器的一致性:
- HashMap 的迭代器是 fail-fast 迭代器,如果在迭代器遍历的过程中对 HashMap 进行了修改,就会抛出 ConcurrentModificationException 异常。
- HashTable 的迭代器是 Enumeration 迭代器,它是安全,但是它能够检测到在迭代进行中对哈希表所作的改变,但是不能支持同步,并且迭代器是不能移除元素的。
除此之外,HashMap 允许 key 和 value 为 null,而 HashTable 不允许。HashMap 的初始容量为 16,而 HashTable 的初始容量为 11。HashMap 的负载因子为 0.75,而 HashTable 的负载因子为 0.75。
SpringBoot 框架的优缺点
Spring Boot 框架是一种适合构建微服务应用的快速开发框架,其优点包括:
1. 快速构建和部署:相对于传统的 Java web 应用,Spring Boot 可以快速构建,因为它可以自动配置和封装大量的配置和组件,让开发者聚焦于业务逻辑的编写,同时也能够保证应用能够快速部署。
2. 自动配置:Spring Boot 能够根据外部配置自动配置自身的一些组件,例如数据源、Web 服务器、模板引擎、缓存等,简化了配置的繁琐,同时也提高了开发的效率。
3. 微服务支持:Spring Boot 框架支持用于构建微服务应用的 Spring Cloud,可以实现服务注册与发现、服务链路追踪、断路器等微服务功能。
4. 高度集成:Spring Boot 可以轻松地集成其他常用的 Java 技术,如 Spring、Hibernate、MyBatis、Thymeleaf 等,同时也支持一些非 Java 技术,如 Groovy、Scala 等。
5. 易于测试:Spring Boot 框架支持测试驱动开发,可以使用 MockMvc 进行 Web 开发的单元测试,也可以使用 JUnit、Mockito 等常见测试框架进行单元测试和集成测试。
其缺点主要包括:
1. 初学门槛高:Spring Boot 框架的学习曲线相对比较陡峭,需要了解较多的 Spring 相关知识和技术栈。
2. 复杂性:Spring Boot 框架对于复杂应用的支持相对较弱,因为过多集成和自动配置会增加代码复杂度和系统复杂度。
3. 内存占用:由于集成了较多的组件和自动配置,Spring Boot 应用在启动时会消耗一定的内存,特别是在微服务应用场景下同时启动大量的微服务实例时,占用的内存较高
蚁群算法
(Ant Colony Algorithm,简称 ACA)是一种基于模拟蚂蚁觅食行为而提出的求解最优化问题的算法。其产生于对蚂蚁在自然界中觅食行为的研究,通过模拟蚂蚁在寻找食物的过程中的信息交流和协作行为,从而实现优化问题的求解。
在蚁群算法中,模拟了一个由一些蚂蚁组成的群体,每个蚂蚁走过一条路径时会留下一些信息素,这些路径被覆盖的程度取决于蚂蚁走过该路径所获得的收益(比如食物的多少),信息素又会对蚂蚁的选择产生影响,即选择留有更多信息素的路径概率较大。这样,随着蚂蚁不断反复走过这些路径,信息素量逐渐积累,最终演化出最优路径。
蚁群算法主要有以下几个基本要素:
1.蚂蚁:代表了寻找最优解的个体,每个个体按照一定的规则移动,记录下它所走过的路径和路径的质量。
2.信息素:记录了路径的质量,信息素的强度影响了蚂蚁选择的概率。
3.启发函数:直接或间接地影响蚂蚁选择向主流方向移动的概率。
4.更新规则:用于更新信息素的强度,一般包括局部信息素更新和全局信息素更新。
蚁群算法的优点
1.全局优化:能够全局快速找到最优解。
2.适用范围广:能够适应多种求解问题。
3.通用性强:蚁群算法的核心思想可以应用于其他的算法中。
蚁群算法的缺点包括:
1.算法参数的选择比较复杂。
2.需要较多的计算资源。
3.局部最优问题较难解决。
4.并行处理的效果不是很好。
算法:是否知道
堆排序(Heap Sort)是一种基于比较的排序算法,采用堆数据结构实现。堆是一个完全二叉树,分为大根堆和小根堆。在大根堆中,父节点的值大于等于其子节点的值;在小根堆中,父节点的值小于等于其子节点的值。
堆排序的基本思想是:将待排序序列转化成一个堆,然后将堆顶元素与堆底元素交换位置,之后从堆顶重新调整堆,再将堆顶元素与堆底元素交换位置,重复以上步骤直到整个序列有序。可以采用不断删除堆顶元素的方法得到有序序列。
具体的排序流程如下:
1. 将待排序序列构建成一个大根堆。
2. 将堆顶元素(即序列中的最大值)与序列最后一个元素交换位置。
3. 将除序列最后一个元素外的剩余元素再构建成一个大根堆。
4. 重复步骤 2 和 3 直到整个序列有序。
堆排序的时间复杂度为 O(n log n),是一种稳定的排序算法。
由于堆排序需要频繁地交换数据,因此其常数因子较大,不适合排序较小的数据集合。此外,堆排序的排序过程是不稳定的,可能会改变相同元素之间的相对位置关系。
Linux 打包指令
在 Linux 环境中,打包指令使用 tar 命令来实现,具体的指令格式为:
```
tar [选项] [文件/目录]
```
常用的选项包括:
- `-c`:创建新的归档文件(打包文件)
- `-v`:显示指令执行过程
- `-f`:指定归档文件名称
- `-z`:打包同时使用 gzip 压缩,建议一般都加上这个选项
- `-j`:打包同时使用 bzip2 压缩
- `-x`:从归档文件中提取文件
- `-C`:指定提取路径
打包命令示例:
1. 将文件打包成归档文件
```
tar -czvf archive.tar.gz file1 file2 ...
```
其中:
- archive.tar.gz 为归档文件名称
- file1、file2... 为要打包的文件或目录名称
该命令会将指定的文件或目录打包成归档文件,并使用 gzip 压缩。打包后的文件名为 `archive.tar.gz`。
2. 将归档文件解压缩到指定路径
```
tar -xzvf archive.tar.gz -C /path/to/dir
```
其中:
- archive.tar.gz 为归档文件名称
- /path/to/dir 为解压缩的目标路径
该命令会解压缩指定的归档文件到指定的目录中。-C 选项后面必须跟上解压缩的目录名。
Wait 和 Sleep 的区别
Wait和Sleep都是等待某个条件满足之后再执行的函数调用,它们的主要区别在于所属的模块和应用场景。
Wait通常是指在操作系统提供的线程同步机制中使用,主要用于线程间的同步和互斥操作。Wait函数可以将当前线程挂起,直到某个条件得到满足,然后重新唤醒该线程并继续执行。在调用Wait函数时,会在同步对象(如互斥锁或信号量)上等待某个事件(如被释放或信号发生)发生,直到条件得到满足。此时,操作系统会唤醒该线程,并将其从等待队列中移除,然后再把CPU资源分配给该线程,使其继续执行。因此,Wait函数可以用于实现线程间的同步和互斥操作,保证线程的顺序执行,避免资源的竞争和争用。
Sleep函数通常是指在应用程序开发中使用,在需要延迟一段时间后再执行某个操作时使用。Sleep函数可以将当前线程挂起一段指定的时间(以毫秒为单位),然后再继续执行。在调用Sleep函数时,操作系统会把该线程挂起,将CPU资源分配给其他线程或进程,然后在等待指定的时间后再重新唤醒该线程,使其继续执行。因此,Sleep函数主要用于在应用程序中控制线程的调度,实现线程的延时操作,避免CPU资源的浪费。
总的来说,Wait函数常常用于多线程间的同步和互斥,而Sleep函数主要用于控制线程的调度和延时操作。需要根据具体的应用场景来选择相应的函数调用。
性能测试指标有哪些?
性能测试的常见指标有:响应时间、并发数、吞吐量、tps、点击数、错误率和资源利用率。
TPS是指系统每秒钟能够处理的事务和交易的数量,它是衡量系统处理能力的重要指标
一、响应时间
指的是用户从客户端发起一个请求开始,到客户端接收到从服务器端返回的结果,整个过程所耗费的时间。
不包括前端页面的处理时间和渲染时间。
这也是客户最能只管感受到的,比如页面卡顿、无响应等。
二、并发数
并发用户数,指某一时刻同时向服务器发送请求的用户数。
注意是服务器不是同一个接口,可以是多个接口。
三、吞吐量
指的是单位时间内处理的客户端请求数量,直接体现软件系统的性能承载能力。
又分为每秒事务数(TPS)和每秒查询数(QPS):
每秒事务数(TPS):服务器每秒处理的事务请求数量;
每秒查询数(QPS):服务器每秒处理的指定请求数量;
区别:
事务请求:一个点击,可以包含多个请求,比如:一个编辑按钮,包含查询请求,如果里面有下拉菜单,菜单的数据又是一个请求。那么一个事务里就有2个请求。
指定请求:就单只一个请求。
如何事务里只有一个请求,那么TPS=QPS
四、点击数
点击数:指客户端向服务器发送请求时,所有的页面资源元素,包括:图片、链接、框架css、js等,的请求总数量。
注意:
只有web项目才有此指标
点击数不是页面上的一次点击
性能测试中什么情况内存过高,但 CPU 使用率不高?
在性能测试中,出现内存过高,但 CPU 使用率不高的情况可能是由以下几个原因导致的:
1. 内存泄漏:当应用程序中存在内存泄漏时,内存使用量会不断增加,当内存使用量到达系统上限时,就会导致内存过高的情况。因为内存泄漏导致的内存占用不属于CPU工作导致,所以CPU使用率不高。
2. 内存碎片:内存碎片是指已被使用的内存块中间出现的空闲内存块,应用程序在申请内存时,如果无法找到足够大的连续内存块,就会出现内存不足的情况。由于内存碎片问题不属于CPU工作导致,所以CPU使用率不高。
3. 内存缓存和缓存管理:当应用程序非常频繁地访问相同的内存地址时,系统会将这些数据缓存起来,加快访问速度。缓存管理系统会监控应用程序的内存使用情况,根据需要对缓存进行调整,但这些处理不需要CPU参与,所以即便内存占用很高,CPU使用率也不会很高。
总的来说,如果出现内存过高但 CPU 使用率不高的情况,应考虑是否存在内存泄漏、内存碎片等问题,并及时调整应用程序的内存使用情况以避免内存占用过高
性能测试中什么情况 CPU 使用率高,但内存占用不高?
在性能测试中,出现 CPU 使用率高,但内存占用不高的情况可能是由以下几个原因导致的:
1. CPU 密集型任务:当应用程序执行的任务需要大量使用 CPU 资源而并不需要占用大量内存时,就会出现 CPU 使用率高,但内存占用不高的情况。
2. 缓存和缓存管理:某些应用程序和操作系统会把常用资源缓存下来来加速访问,这些缓存可能是文件、数据库记录、网络请求等,当这些资源被频繁的访问时,就会导致 CPU 使用率增加,但内存占用并不高。
3. 多线程处理:当应用程序使用多线程处理任务时,单个线程的 CPU 使用率虽然不高,但是多个线程并发执行,就会导致总的 CPU 使用率高。
总的来说,如果出现 CPU 使用率高,但内存占用不高的情况,应该考虑应用程序执行的任务类型、是否存在缓存、是否使用了多线程等因素,针对性优化 CPU 使用率。如果 CPU 性能过高导致服务器负载过大,应该考虑优化应用程序的算法、减少 CPU 资源占用。
TCP 和 UDP的区别?
TCP 传输控制协议:面向连接 ;一对一可靠性传输;面向字节流是数据报处理的最小单位;首部消耗20字节;效率低,不具备实时性
UDP 用户数据报协议:面向无连接;支持一对多,多对一,一对一,多对多,不可靠传输,仅保证全部传输过去,面向报文不可分割是数据报处理的最小单位;首部消耗8字节;具有实时性;UDP 适合一次性传输较小数据的网络应用,如 DNS,SNMP 等。
App 的测试工具知道哪些?
以下是常用的 App 测试工具:
1. Appium:一款跨平台自动化 App 测试软件,支持 iOS、Android、Windows 等多个平台,具有多语言支持和丰富的测试库。
2. Calabash:一个 Ruby 开发的框架,用于测试 iOS 和 Android App,支持混合应用程序测试,可以在所有主流移动设备上运行。
3. Selendroid:一个自动化测试工具,适用于 Android 应用程序,支持 Android 2.3 至 8.0 版本。
4. Robotium:一款基于 Java 的自动化测试框架,用于测试 Android 应用程序,提供简单易用的 API 和强大的功能。
5. TestFlight:一款由苹果公司提供的测试工具,用于 iOS 应用程序的内部测试和 beta 版本发布。
6. Firebase Test Lab:Google 提供的移动应用程序测试平台,支持 Android 和 iOS 应用程序的自动化测试、兼容性测试、性能测试等。
7. Espresso:由 Google 开发的测试框架,适用于 Android 应用程序的自动化测试,提供简单易用的 API 和高效的测试结果。
总的来说,在选择 App 测试工具时,需要根据自己的需求考虑应用程序的具体测试需求、适用平台、语言环境等因素,选择适合自己的测试工具
哪些设计模式,在工具开发当中有用到什么测试模式?
SQL 和 MySQL 的区别
SQL是一种用于操作数据库的语言
MySQL是一个可用的开源数据库管理系统之一
SQL用于访问,更新和操作数据库中的数据
MySQL用于管理数据库中的数据
SQL是结构化查询语言
MySQL是一个使用MYSQL存储,检索,修改和管理数据库的RDBMS
SQL是一种查询语言,而MYSQL是数据库软件
数据库事务
事务是由一条或多条SQL语句组成的逻辑执行单元, 可以比喻成一个容器, 里面放的就是一堆SQL语句, 这些语句要么全部执行成功, 要么一个都无法执行成功
悲观锁和乐观锁
什么是悲观锁?使用场景是什么?
悲观锁总是假设最坏的情况,认为共享资源每次被访问的时候就会出现问题(比如共享数据被修改),所以每次在获取资源操作的时候都会上锁,这样其他线程想拿到这个资源就会阻塞直到锁被上一个持有者释放。
也就是说,共享资源每次只给一个线程使用,其它线程阻塞,用完后再把资源转让给其它线程。
像 Java 中synchronized和ReentrantLock等独占锁就是悲观锁思想的实现。
悲观锁通常多用于写多比较多的情况下(多写场景),避免频繁失败和重试影响性能。
什么是乐观锁?使用场景是什么?
乐观锁总是假设最好的情况,认为共享资源每次被访问的时候不会出现问题,线程可以不停地执行,无需加锁也无需等待,只是在提交修改的时候去验证对应的资源(也就是数据)是否被其它线程修改了(具体方法可以使用版本号机制或 CAS 算法)。
在 Java 中java.util.concurrent.atomic包下面的原子变量类就是使用了乐观锁的一种实现方式 CAS 实现的。
乐观锁通常多于写比较少的情况下(多读场景),避免频繁加锁影响性能,大大提升了系统的吞吐量。
如何实现乐观锁?
乐观锁一般会使用版本号机制或 CAS 算法实现,CAS 算法相对来说更多一些,这里需要格外注意
MySQL 的优缺点
MySQL是一种流行的关系型数据库管理系统,其优缺点如下:
优点:
开源免费:MySQL是一种开源的软件,可以免费下载和使用。
可扩展性:MySQL可以扩展到支持数百万个表和数百个连接。
高性能:MySQL具有出色的性能,可以处理大量的并发查询和事务处理。
跨平台:MySQL可以在多种操作系统上运行,包括Windows、Linux和MacOS等。
可靠性:MySQL具有高可靠性,能够保证数据的完整性和一致性。
可定制性:MySQL具有高度可定制性,可以根据不同的应用程序和需求进行自定义配置。
缺点:
不支持完全事务:MySQL不支持完全事务,这意味着在某些情况下,可能会出现数据不一致的问题。
不支持复杂的查询:MySQL不支持复杂的查询,这可能会导致查询速度变慢或查询结果不准确。
安全性:MySQL在安全性方面存在一些问题,因为它不支持强制访问控制或加密。
数据库管理:MySQL需要一定的数据库管理技能,包括备份和恢复、调优和维护等。
不支持分布式事务:MySQL不支持分布式事务,这可能会导致数据一致性的问题。
总之,MySQL是一种广泛使用的关系型数据库管理系统,具有出色的性能、可扩展性和可靠性等优点,但在某些方面还存在一些缺点需要注意。
做接口测试框架的实现时,遇到哪些问题?是如何解决的?
负责的业务测试链路
常用的团队管理模型
ArrayList 和 LinkedList 的区别是什么?
- ArrayList 和 LinkedList 存储的数据都是线性存储,元素可重复,并且有先后放入次序;
- ArrayList 底层数据结构为数组,可进行动态扩容,每次扩容1.5倍,非常适合随机访问的业务场景
- LinkedList 底层数据结构为节点,不是一个连续的,非常适合元素插入、删除的业务场景:
在 Python 中,函数怎么传入可变参数
- 如果函数需要支持传入可变参数,前提是将函数的形参前面加上一个或两个*号
- 可变的位置参数通常使用*args表示,调用时按照位置传入实参即可,所有接收到的实参会被收集成一个元组对象。
- 可变的关键字参数通常使用**kwargs表示,调用时按照key=value的格式传入实参即可,所有接收到的实参会被收集成一个字典对象。
is 与 == 的区别
- is 是比较两个对象的内存地址是否相等,== 是比较两个对象的内容是否相等。id() 方法可以查看对象的内存地址
- 关于小整形对象[-5,256]范围内的对象,在全局解释器范围内会被重复使用,永远不会被GC回收:
json 和 dict 的区别
- JSON 是一种用于在系统应用之间进行数据传输的文本格式,而 Python 语言中的 dict 是一种内存中数据结构。
- 由于 JSON 内容是文本,因此在其中查找一个 key 的时间复杂度是 O(n),而 dict 使用哈希值,时间复杂度是 O(1),所以查找键的效率比 JSON 高效很多。
- JSON 的键仅支持字符串格式,必须是双引号包围。而 dict 的键支持任何可哈希的对象作为键,包括元组,自定义类等等
- JSON 的值的格式要求是有效的 JSON 类型,包括数组、对象、字符串、浮点数、布尔值和 null。而 dict 字典的值可以是 Python 中任何数据类型,包括整数、浮点数、字符串、布尔值、None、列表、元组、集合和字典。:
怎么强制杀死 tomcat 进程
- 首先我们可以通过ps或者netstat的相关命令找到Tomcat进程的id
- 使用kill命令杀掉该进程后,就能重新启动新的进程了,可以编写一个脚本把查找进程与杀死进程结合实现便捷杀进程操作。
- windows系统
- 首先通过netstat找到Tomcat进程的pid
- 通过taskkill把找到的pid杀掉:
Python 中迭代器与生成器分别是什么
- 联系
- 生成器是迭代器的子类,因此生成器是一个迭代器。
- 生成器是创建迭代器的一种简便方式
- 区别
- 迭代器可以通过定义一个类来实现,而生成器不需要定义成类;
- 生成器的语法中可以使用 yield 表达式,但迭代器中不可以;
- 生成器的语法更加简练,而自定义的迭代器类代码较多:
python 装饰器是什么?其作用是什么? 装饰器的原理与实现?
- 本质就是封装了一个闭包函数,在函数、方法或者类的定义上方添加@装饰器名称进行使用。
- 优化代码的可读性,可维护性:
元组和列表的区别
- 列表是可变的,而元组是不可变的
- 列表支持很多内置方法,而元组则很少
- 列表占用更多的内存,元组内存开销较小:
三种等待方式分别是什么,有什么区别?显式等待与隐式等待的区别?
类型 | 使用方式 | 原理 | 适用场景 |
直接等待 | time.sleep(等待时间)) | 强制线程等待 | 调试代码,临时性添加 |
隐式等待 | driver.implicitly_wait(等待时间) | 在时间范围内,轮询查找元素 | 解决找不到元素问题,无法解决交互问题 |
显式等待 | WebDriverWait(driver实例, 最长等待时间, 轮询时间).until(结束条件) | 设定特定的等待条件,轮询操作 | 解决特定条件下的等待问题,比如点击等交互性行为 |
面向对象和面向过程的区别
面向对象和面向过程是两种不同的编程思想,它们的主要区别在于:
- 抽象程度不同:面向过程的编程思想是以过程为中心,强调的是解决问题的步骤和方法,注重的是算法和数据结构的设计。而面向对象的编程思想是以对象为中心,强调的是对象的行为和属性,注重的是对象之间的交互和关系。
- 数据和方法的封装:面向对象的编程思想将数据和方法封装在对象中,通过对象之间的交互来实现程序的功能。而面向过程的编程思想则将数据和方法分开处理,通过函数的调用来实现程序的功能。
- 继承和多态性:面向对象的编程思想支持继承和多态性,可以通过继承来扩展已有的类,通过多态性来实现不同对象之间的交互。而面向过程的编程思想则不支持继承和多态性。
- 代码的复用性:面向对象的编程思想通过类的封装和继承来实现代码的复用性,可以减少代码的重复编写。而面向过程的编程思想则需要重复编写相似的代码来实现相同的功能。
总的来说,面向对象的编程思想更加灵活、可扩展、易维护,适用于大型复杂的软件系统的开发;而面向过程的编程思想则更加直观、简单、易于理解,适用于小型的程序开发。
Python自动化实现思路
Python自动化测试常用于Web应用、移动应用、桌面应用等的测试
Python自动化实现思路通常分为以下几步:
1. 确定自动化测试的范围和目标:
首先需要明确需要进行自动化测试的范围和目标,包括测试场景、测试用例、测试数据等。
2. 选择自动化测试工具和框架:
根据测试目标和需求,选择适合的自动化测试工具和框架,例如:Selenium、Appium、Requests等。
3. 编写测试用例:
根据测试目标和需求,编写自动化测试用例,包括测试场景、测试步骤、预期结果等。
4. 封装测试用例和测试数据:
将编写好的测试用例和测试数据进行封装,使其具有可重用性和可扩展性。
5. 执行测试用例:
使用自动化测试工具和框架执行测试用例,记录测试结果和测试日志。
6. 分析测试结果:
根据测试结果和日志进行测试结果分析,确定测试是否通过或失败,并记录测试缺陷。
7. 优化测试用例和测试框架:
根据测试结果和反馈优化测试用例和测试框架,提高自动化测试的效率和稳定性。
8. 部署和使用:
将自动化脚本部署到服务器或本地计算机,并使用定时任务等方式进行定时运行和监控,以实现长期稳定的自动化任务。在部署过程中,需要考虑如何保护数据安全、如何进行任务调度和监控、如何进行错误处理和恢复等问题,以确保自动化任务的可靠性和安全性。在使用过程中,需要及时记录和分析自动化任务的运行情况,以便进行优化和改进。
通过购物车使用Python实现自动化的思路:
以下是一个简单的购物车自动化测试的实现思路和测试链条,其中包括接口自动化和UI自动化:
1. 需求分析
首先,需要了解购物车的功能需求,包括添加商品、删除商品、结算商品等操作,以及需要验证的功能点和边界条件等。
2. 测试用例设计
根据需求分析,设计相应的测试用例,包括正常场景和异常场景的测试用例。
如:
- 添加商品:测试添加一个或多个商品到购物车,验证购物车中的商品数量和价格是否正确。
- 删除商品:测试从购物车中删除一个或多个商品,验证购物车中的商品数量和价格是否正确。
- 结算商品:测试结算购物车中的商品,验证结算金额是否正确,并且验证结算后购物车中的商品数量是否正确。
3. 接口自动化
对于购物车的接口,可以使用Python的requests库进行接口自动化测试。具体实现步骤如下:
- 安装requests库
- 编写接口测试用例,包括请求参数、请求方法、请求头、请求体、响应结果等信息。
- 对于需要登录的接口,可以使用Python的requests.Session来维持会话状态。
- 对于需要验证接口性能的接口,可以使用Python的time库来计算接口响应时间等指标。
4. UI自动化
对于购物车的UI界面,可以使用Python的Selenium库进行UI自动化测试。具体实现步骤如下:
- 安装Selenium库和对应的浏览器驱动,例如:ChromeDriver。
- 编写UI自动化测试用例,包括打开网页、定位元素、操作元素、断言结果等信息。
- 对于需要登录的页面,可以使用Selenium的Cookies机制来维持会话状态。
- 对于需要验证页面性能的测试用例,可以使用Python的time库来计算页面加载时间等指标。
5. 集成测试
将接口自动化和UI自动化测试集成在一起,构建一个完整的测试链条。例如:先进行接口自动化测试,验证接口的正确性和稳定性;然后进行UI自动化测试,验证页面的正确性和稳定性;最后进行集成测试,验证整个购物车的流程和性能。
6. 持续集成
使用持续集成工具,例如:Jenkins,将购物车自动化测试集成到持续集成流程中,实现自动化测试的自动执行和结果分析。可以设置定时触发或者通过Git提交来触发自动化测试的执行。
主键和外键的重要区别
Key | 主键 | 外键 |
Basic | 它用于唯一地识别表中的数据。 | 它用于维护表之间的关系。 |
Null | 它不可能是NULL。 | 它可以接受NULL值。 |
重复的 | 两条或多条记录不能有相同的主键。 | 它可以为一个外键属性携带重复的值。 |
Index | Primary有聚类索引。 | 默认情况下,它不是聚类索引。 |
Tables | 可以在临时表上定义主键约束。 | 它不能被定义在临时表上。 |
自动化测试中使用过的测试框架,并解释它们的优缺点。
框架名称 | 用途 | 优点 | 缺点 |
pytest | Python编写的测试框架,用于单元测试和集成测试 | (1)支持参数化测试、测试结果输出丰富、易于扩展、可定制性强 (2) 与Python语言紧密结合,能够充分发挥Python语言的优势 | (1)与Python语言紧密结合,对非Python项目的支持有限 (2)对初学者有一定门槛 |
Selenium | 用于Web界面测试,支持多种浏览器 | (1)支持多种编程语言,有丰富的API,容易上手 (2) 支持多种浏览器和平台,适用于多种测试需求 (3) 支持并行测试,提高测试效率 | (1) 需要依赖浏览器驱动,部署和配置比较繁琐 (2) 容易受到前端界面变更的影响,稳定性需要保证 |
Appium | 用于移动应用测试,支持多种移动平台 | (1) 支持多种编程语言,易于使用 (2) 支持多种移动平台和设备,适用于多种测试需求 (3) 对移动应用性能和稳定性进行全面监控 | (1) 需要依赖设备或模拟器,配置比较繁琐 (2) 对测试环境和设备要求比较高 |
Requests | 用于HTTP请求的测试框架,支持API测试 | (1) 语法简单,易于上手 (2) 支持多种HTTP请求方式和参数设置 (3) 支持对请求和响应进行断言 | (1)不支持多线程请求 (2) 对复杂HTTP请求的支持有限 |
JUnit 5 | 用于Java编写的单元测试框架 | (1) 支持参数化测试、断言丰富、可扩展性强 (2) 对Java语言的支持非常好,与Java开发的项目完美结合 (3) 支持并行测试,提高测试效率 | (1) 对非Java语言的支持有限 (2)对初学者有一定门槛 |
TestNG | 用于Java编写的测试框架,支持单元测试和集成测试 | (1)支持参数化测试、测试结果输出丰富、易于扩展、可定制性强 (2)对Java语言的支持非常好,与Java开发的项目完美结合 - 支持并行测试,提高测试效率 | (1) 对非Java语言的支持有限 (2)对初学者有一定门槛 |
Rest-Assured | 用于API测试,支持多种HTTP请求方式 | (1) 支持流畅的API语法,易于阅读和编写 (2) 支持多种HTTP请求方式 (3)支持多种断言方式和数据驱动测试。 | (1)对于一些高级特性(如异步测试)支持不够完善。 |
链表都有哪几类,对应的特点是什么
单向链表、双向链表、循环链表、双向循环链表
1、单向链表(Singly linked list):
特点:
每个节点只有一个指针指向下一个节点,最后一个节点指向 NULL。单向链表只能顺序遍历,不能回溯。插入和删除节点的时间复杂度为 O(1),但是访问特定节点的时间复杂度为 O(n)。
实际运用场景:
单向链表常用于实现栈、队列和哈希表等数据结构。例如,在实现一个队列时,可以使用单向链表作为底层数据结构。在队列的尾部添加元素时,只需要在链表的末尾插入一个新节点;在队列的头部删除元素时,只需要将链表的头节点指针指向下一个节点即可。单向链表还可以用于实现基数排序、拓扑排序和 Dijkstra 算法等算法。
2、双向链表(Doubly linked list):
特点:
每个节点同时有指向前一个节点和下一个节点的指针。因此,双向链表可以前后遍历。插入和删除节点的时间复杂度为 O(1),但是每个节点需要额外存储一个指针,增加了空间复杂度。
实际运用场景:
双向链表常用于实现 LRU 缓存淘汰算法、LRU-K 缓存淘汰算法和快速排序等算法。例如,在实现 LRU 缓存淘汰算法时,可以使用双向链表作为底层数据结构。当缓存中的某个数据被访问时,可以将该数据所在的节点移动到链表的末尾,这样,最近访问的数据就位于链表的末尾,最少访问的数据就位于链表的头部。
3、循环链表(Circular linked list):
特点:
最后一个节点指向第一个节点,形成一个循环。循环链表可以用于实现队列和环形缓冲区等数据结构。
实际运用场景:
循环链表常用于实现音乐播放器、游戏中的循环地图和环形缓冲区等场景。例如,在实现一个音乐播放器时,可以使用循环链表来管理播放列表。当播放到最后一首歌时,可以自动跳转到第一首歌,从而形成一个循环播放的效果。
4、双向循环链表(Doubly circular linked list):
特点:
同时具有双向链表和循环链表的特点。
实际运用场景:
双向循环链表可以同时具有双向链表和循环链表的特点,常用于实现哈希表和 LRU 缓存淘汰算法等数据结构和算法。例如,在实现哈希表时,可以使用双向循环链表来处理哈希冲突。当多个键映射到同一个哈希桶时,可以使用双向循环链表将它们连接起来,形成一个链表。当需要查找某个键时,只需要遍历该哈希桶对应的链表即可。双向循环链表还可以用于实现 LRU 缓存淘汰算法,它可以在 O(1) 的时间复杂度内将最少访问的数据删除,并将新的数据插入到链表的末尾。
冷启动、暖启动、热启动、首屏启动,分别是什么?
启动性能指标是用于衡量应用程序启动速度的关键指标。以下是各种启动性能指标的定义:
- 冷启动:冷启动是指应用程序在第一次运行时启动的时间。在冷启动期间,应用程序必须加载和初始化其所有组件和资源,这可能需要一定的时间。
- 暖启动:暖启动是指应用程序在已经运行一段时间后重新启动的时间。在暖启动期间,应用程序可能会使用缓存的数据和组件,因此启动速度可能会比冷启动更快。
- 热启动:热启动是指应用程序在已经运行并保持在后台时重新启动的时间。在热启动期间,应用程序可以直接从缓存中加载已经存在的组件和数据,因此启动速度通常非常快。
- 首屏启动:首屏启动是指应用程序在启动后显示其主屏幕或首屏所需的时间。这通常是用户感知到的启动时间的主要指标之一,因为它反映了用户可以开始与应用程序进行交互的时间。
这些指标是衡量应用程序启动性能的关键指标,开发人员可以使用它们来优化应用程序的启动时间,提高用户体验。
怎么搭建接口自动化框架的
使用requests框架作为底层请求库,使用pytest作为测试执行库,使用allure作为测试报告库,使用类似于page object模式编写使用api object模式将三者有机的结合在一起
Python的高阶函数
python的高阶函数有map,reduce,filter,sorted
map将传入的函数应用列表中的每个元素
reduce将根据传入的函数将列表中的所有元素归并为一个元素结果
filter根据传入的函数过滤列表中的元素
sorted根据传入的函数来对列表中的元素进行排序
[0到9]用切片获取奇数
[range(10)][1::2]
从第一个元素开始取,每隔两个取一次,直到最后一个元素
接口幂等怎么测试
接口幂等使用重复测试的方法来实现,即对同一个接口在1s中同时发送n个相同的请求,看返回的结果是否相同
tcp 拥塞算法、滑动窗口、重传机制、粘包和拆包
滑动窗口协议(Sliding Window Protocol)、重传机制详情见
TCP 滑动窗口/快速重传机制Shawei的博客-CSDN 博客_tcp 快速重传机制 。
拆包 :TCP 直接将应用层数据包(可以认为就是一个数组)发给接收方,并且根据 TCP 协议,TCP 会将每个发送的数据包编号(序列号),发送完一个序列号后,接收端收到会回复该序列号,代表已经被接受,but 接收端有自己的 TCP 缓存区,它会将多个包积累在一起再进行处理,这样的结果是导致包与包之间 “无缝连接”,即所谓的” 粘包 “
粘包:针对此问题,就有了一些解决办法:哪每个包长度固定:这样接收端就可以每隔一定长度进行拆包,但缺点是浪费资源,加入头部信息:每个数据包前加入该数据包中数据的长度值,这样接收端从缓存中读取时,通过读该头部信息,知道了每个包的长度,这样就能拆包
浏览器输入百度网址发生了什么?DNS 解析过程
这个问题比较宽泛,整个流程也比较长,涉及到网络 7 层模型、dns 解析、tcp/ip 协议簇,三次握手、负载均衡、集群架构、数据库,linux 系统状态、进程切换等等方面,看你自己对哪块比较熟悉,重点去说
cookies,session 鉴权机制?为什么要引入这套机制?
引入原因:HTTP 是无状态的协议(对于事务处理没有记忆能力,每次客户端和服务端会话完成时,服务端不会保存任何会话信息):每个请求都是完全独立的,服务端无法确认当前访问者的身份信息,无法分辨上一次的请求发送者和这一次的发送者是不是同一个人。所以服务器与浏览器为了进行会话跟踪(知道是谁在访问我),就必须主动的去维护一个状态,这个状态用于告知服务端前后两个请求是否来自同一浏览器。而这个状态需要通过 cookie 或者 session 去实现
三范式是什么
第一范式 (确保每列保持原子性)、第二范式 (确保表中的每列都和主键相关)、第三范式 (确保每列都和主键列直接相关,而不是间接相关)
sql 是怎么优化的
show variables like ‘%quer%’; 查询慢查询日志相关的设置,找出慢查询的 sql ,用 explain 查询 sql 的执行计划,该加索引的加索引(要知道索引正确使用场景如下面试题),尽量少 连接查询、select *、避免类型转换,减少回表次数。
索引的概念、类型,优缺点分析、索引应用场景和索引失效场景
索引是帮助 mysql 高效获取数据的数据结构
优点:
a)可以保证数据库表中每一行的数据的唯一性,
b)可以大大加快数据的检索效率,
c)加速表与表之间的连接,
d)在使用分组和排序子句进行数据检索时,同样可以显著减少查询中分组和排序的时间。
f)通过使用索引对数据进行排序,降低数据排序的成本,降低 cpu 的消耗,可以在时间查询的过程中,使用优化隐藏器,提高系统的性能。
缺点:
a) 创建索引和维护索引要耗费时间,这种时间随着数据量的增加而增加。
b) 索引会占据磁盘空间。
c) 以表中的数据进行增、删、改的时候,索引也要动态的维护,这就降低了整数的维护速度。
索引类型:
主键索引:索引列中的值是唯一的并且不允许有空值
普通索引:mysql 的基本索引类型,没有什么限制,允许有重复值和空值
唯一索引:索引列中的值是唯一的,但是允许有空值
还有其他索引 譬如全文索引、空间索引、前缀索引等不常见
mysql 几个存储引擎,innodb 和 MyISAM 区别
MySQL 有多种存储引,MyISAM、InnoDB、MERGE、MEMORY(HEAP) 等
InnoDB 和 MyISAM 区别:
1). InnoDB 支持事务,MyISAM 不支持事务。这是 MySQL 将默认存储引擎从 MyISAM 变成 InnoDB 的重要原因之一;
2). InnoDB 支持外键,而 MyISAM 不支持。对一个包含外键的 InnoDB 表转为 MYISAM 会失败;
3). InnoDB 是聚集索引,MyISAM 是非聚集索引。聚簇索引的文件存放在主键索引的叶子节点上,因此 InnoDB 必须要有主键,通过主键索引效率很高。但是辅助索引需要两次查询,先查询到主键,然后再通过主键查询到数据。因此,主键不应该过大,因为主键太大,其他索引也都会很大。而 MyISAM 是非聚集索引,数据文件是分离的,索引保存的是数据文件的指针(就是物理地址)。主键索引和辅助索引是独立的 。
注意:MyISAM 无论是主键还是非主键索引 ,data 存储的都是这条数据的物理地址(地址指针),innodb 主键索引的 data 就是这条数据,非主键索引的 data 是主键 id
mysql 事务隔离级别、MVCC 是什么
MVCC ,Multi-Version Concurrency Control,多版本并发控制。MVCC 是一种并发控制的方法,一般在数据库管理系统中,实现对数据库的并发访问;在编程语言中实现事务内存
数据库锁类型,什么是数据库死锁,如何避免
从数据库系统角度分为三种:排他锁、共享锁、更新锁。
从程序员角度分为两种:一种是悲观锁,一种乐观锁,等等
避免死锁方式:
结构化数据建模:基于范式原则初级建模
热点业务排解:挖出核心业务模型
应用拆解:降低时间片复杂度
提升性能:优化代码,集群、超时机制、回滚机制
主从底层数据同步机制、binglog、redolog、undolog 区别
redo log:确保事务的持久性。防止在发生故障的时间点,尚有脏页未写入磁盘,在重启 mysql 服务的时候,根据 redo log 进行重做,从而达到事务的持久性这一特性。undo log:回滚日志保存了事务发生之前的数据的一个版本,可以用于回滚,同时可以提供多版本并发控制下的读(MVCC),也即非锁定读 binlog:二进制日志作用:用于复制,在主从复制中,从库利用主库上的 binlog 进行重播,实现主从同步。 用于数据库的基于时间点的还原
数据放哪的?数据驱动怎么做的?关键字驱动怎么做的
看情况,如果是灵活的数据,建议放在 excel 里面,做数据驱动,如果是账号、密码这种修改很少的数据,可以考虑放在配置文件中,如果是那种一成不变的可以写死(尽量别这么做)。
关键字驱动:测试用例的步骤 (元素) 和用例分离。关键字驱动表示把项目中的一些逻辑封装成关键字 (一个函数名)。例如 login、 register、order 进行设置变量(Set Viriable),调用不同的关键字组合实现不同的业务逻辑,从而驱动测试用例执行。
数据驱动:数据和用例步骤分离,通过 excel、yaml 等文件保存数据。数据驱动是把测试用例里面的数据提取到 excel 或者 yaml 文件里面,然后通过改变 excel 或 yaml 中的数据驱动测试用例执行。
内存泄露和内存溢出有什么区别
内存溢出(Out Of Memory):就是申请内存时,JVM 没有足够的内存空间。通俗说法就是去蹲坑发现坑位满了。
内存泄露(Memory Leak):就是申请了内存,但是没有释放,导致内存空间浪费,通俗点就是占着那啥不那啥。
为什么使用 redis,redis 五种数据类型,如何测试 redis 的,项目中如何应用的
基于内存查询效率高,高并发情况下保护数据库,string、hash、list、set、zset 五中数据类型,项目中主要用于请求 token 保存和失效,防重分布式锁,冷数据(改动量小)保存,幂等性校验等等。
redis 穿透,击穿,雪崩机制
击穿:当 Redis 某个热 key(比如首页广告)过期或者因为某些异常原因导致于无法从缓存中获取,导致大量的并发访问数据库而崩溃
可以通过如下的测试步骤进行复现:获取热 key 的列表(与运维沟通后获取)。模拟热 key 失效的场景(比如登陆 Redis,直接将热 key 删除)。查看研发是否有对应的容错机制(降级或熔断),从而能保证主要服务的正常运行。
解决办法
1、接口层添加校验,如用户鉴权校验;id做基础校验,指定接口的请求方式,只接受一种或几种 的请求方式。
2、对缓存取不到的数据,在数据库中也没有取到,这时可以将key-value写成key-null,缓存有效时间可以设置30秒(设置太长对导致正常情况下也无法使用),这样可以防止攻击用户反复用同一个id暴力攻击
3、布隆过滤器
缓存穿透就是指:用户不断发起请求缓存和数据库中都没有的数据。在正常的请求过程中,如果在缓存(Redis)中没有查到信息,则直接向数据库进行查询,查询到之后,数据库会讲数据信息同步到缓存(Redis)中,以便下次查询。
通过如下的测试步骤进行复现:不停访问对应服务的接口,传递一个不存在的数据的查询请求。查看研发是否有对应的容错机制,从而能保证不会有大量的请求打在数据库上
解决办法
1、互斥锁,保证同一时间只有一个业务线程更新缓存,未能获取互斥锁的请求,要么等待锁释放后重新读取缓存,要么就返回空值或者默认值。
2、不给热点数据设置过期时间,由后台异步更新缓存,或者在热点数据准备要过期前,提前通知后台线程更新缓存以及重新设置过期时间。
雪崩:表示在某一时间段,缓存集中失效,导致请求全部走数据库,有可能搞垮数据库,使整个服务瘫痪
使缓存集中失效的原因:
1、雪崩就是指缓存中大批量热点数据过期后系统涌入大量的查询请求,因为redis数据已经失效,请求就会渗透到数据库会导致数据库造成查询堵塞甚至宕机
2、redis宕机
解决办法
1、让redis数据永不过期,这种方式最可靠的,最安全的但是占空间,内存消耗大,并且不能保持数据最新,所以需要根据具体的业务逻辑来做
2、将缓存失效时间分散开,比如每个key的过期时间都是随机的,防止同一时间大量数据过期的现象发生,就不会出现同一时间全部请求都落在数据库。
3、因为redis宕机导致缓存雪崩的问题,可以启动服务熔断机制,暂停业务应用对缓存服务的访问,直接返回错误,但是暂停了业务应用访问缓存系统,全部业务都无法正常的工作
4、创造redis集群,对数据库进行读写分离
深拷贝和浅拷贝的区别
1.浅拷贝:对原对象的值进行拷贝,本质上还是对原对象的地址进行引用。浅拷贝的值或是原对象的值发生变化,新生成的对象的值也会随着变化
2、深拷贝:对原对象的地址进行拷贝,新拷贝了一份与原来的地址不同的对象,修改原对象里的值不会对新的对象造成影响
break、continue、pass是什么,有什么区别
在编程语言中,break、continue、pass是一些控制流程的关键字,它们的作用和区别如下:
1、break: 在循环语句(for、while、do-while)或者 switch语句中使用,用于跳出当前循环或者 switch语句,继续执行下面的代码。
2、continue: 在循环语句(for、while、do-while)中使用,用于跳过当前循环中的剩余语句,直接进入下一次循环。
3、pass: 在Python等语言中使用,用于占位,表示不做任何操作,通常用于占位,让代码可以编译通过,后续再来完善实现。
它们的区别如下:
1、break 和 continue 是用于循环语句的控制流程,而 pass 是用于占位的关键字。
2、break 是用于跳出整个循环或者 switch语句,而 continue 是用于跳过当前循环中的剩余语句,直接进入下一次循环。
3、break 和 continue 可以结合条件语句使用,用于更精确的控制循环或 switch语句的执行流程,而 pass 是不需要结合条件语句使用的。
当面试官问到这个问题时,我会给出以上的解释,并举例说明它们的使用场景。例如,break 可以用于遍历数组时,找到目标元素后跳出循环;continue 可以用于过滤数组中不需要的元素,直接跳过处理;pass 可以用于占位,在开发过程中,为了不影响整个程序的正常运行,可以使用 pass 来占位。
如何开展性能测试?性能测试的流程是什么样子
1)性能需求分析
2)制定性能测试计划
3)编写性能测试方案
① 设计测试场景。
② 定义具体事务操作。
③ 针对每个场景,明确监控对象和可能的性能瓶颈点:监控对象:比如TPS、平均响应时间、击率、并发连接数、CPU、内存、IO等。可能的性能瓶颈点:比如数据库查询、Web务器服务转发、应用服务器等。
④ 定义测试策略:明确性能测试的类型、执行顺序、加压方式(压测需要)。
⑤ 选取性能测试工具。
⑥ 明确硬件配置和软件配置:硬件配置:服务器的CPU配置、内存配置、硬盘存储配置、集群环境下还要包括集群节点的数量配置等。软件配置:操作系统、应用版本、参数配置和网络配置。
4)编写性能测试案例,对压测场景细化。
① 描述预置条件:满足啥条件性能测试案例才可以执行。
②详细描述案例执行的步骤,包括:测试脚本的录制和编写脚本的调试;脚本的执行过程(比如如何加压、每个加压的过程持续多久等);要观察和记录的性能指标;需要明确性能曲线的走势;需要监控哪些性能指标等。
③ 描述性能测试预期需要达到的结果,比如:TPS需要达到多少;平比响应时间需要控制到多少以内;服务器资源的消耗需要控制在多少以内等。
5)搭建性能测试环境
6)构造性能测试数据
7)编写性能测试脚本
8)执行性能测试场景(案例)
9)分析性能测试结果,编写性能测试报告
10)系统性能瓶颈分析与性能调优
SQL语句中where与 having的区别
WHERE用于筛选整个表中的记录,HAVING用于筛选聚合函数(如COUNT, SUM, AVG)筛选分组后的记录。
存在以下几点差异:
1.一般情况下,WHERE 用于过滤数据行,而 HAVING 用于过滤分组。
2.WHERE 查询条件中不可以使用聚合函数,而 HAVING 查询条件中可以使用聚合函数。
3.WHERE 在数据分组前进行过滤,而 HAVING 在数据分组后进行过滤 。
4.WHERE 针对数据库文件进行过滤,而 HAVING 针对查询结果进行过滤。也就是说,WHERE 根据数据表中的字段直接进行过滤,而 HAVING 是根据前面已经查询出的字段进行过滤。
5.WHERE 查询条件中不可以使用字段别名,而 HAVING 查询条件中可以使用字段别名。
SQL语句中IN与EXISTS的区别
IN 用于查询一个值是否存在于一个集合中,而 EXISTS 用于判断子查询是否返回任何行。它们的使用场景和作用不同,可以根据需要选择使用哪种关键字。
解释//、%、* *运算符
// 这是一个除法运算符,它返回除法的整数部分。例如:5 // 2 = 2,10//2=5
% 返回除法的余数。例如:5 % 2 = 1
**(幂)-它对运算符执行指数计算。a ** b表示a的b次方。例如:5 ** 2 = 25、10 ** 4 = 10000
硬链接和软链接的区别
1、定义不同
软链接又叫符号链接,这个文件包含了另一个文件的路径名。可以是任意文件或目录,可以链接不同文件系统的文件。
硬链接就是一个文件的一个或多个文件名。把文件名和计算机文件系统使用的节点号链接起来。因此我们可以用多个文件名与同一个文件进行链接,这些文件名可以在同一目录或不同目录。
2、限制不同:硬链接只能对已存在的文件进行创建,不能对目录进行创建,也不能交叉文件系统进行硬链接的创建;
软链接可对文件或目录创建,支持交叉文件系统,还可对不存在的文件或目录创建软链接;
3、影响不同:删除一个硬链接文件并不影响其他有相同inode号的文件。而删除软链接并不影响被指向的文件,但若被指向的原文件被删除,则相关软连接被称为死链接。
4、命令不同:创建软链接使用ln -s 源文件 目标文件,注意其中源文件必须是绝对路径;创建软链接使用ln 源文件 目标文件。
如何使用Linux命令杀死后台执行的任务
ps -ef|grep 用户名
显示服务器上,与该用户名有关的任务
kill -s 9 任务号
强制杀死编号为任务号的任务
使用递归与非递归的方式实现二分查找
Linux命令- ps -ef 与 ps -au 区别
ps -ef用于查看全格式的全部进程,ps -aux也是用于查看进程。
ps -ef和ps aux,这两者的输出结果差别不大,但是展示样式不一样
aux是BSD风格,显示的项目有:USER , PID , %CPU , %MEM , VSZ , RSS , TTY , STAT , START , TIME , COMMAND
-ef是System V风格,显示的项目有:UID , PID , PPID , C , STIME , TTY , TIME , CMD。
COMMADN列如果过长,aux会截断显示,而ef不会
元素明明定位到了,点击无效(也没报错),如果解决?
方法一:页面上有的时候元素点了没有反应(比如时间日期组件),可以通过 js 操作
方法二:有的页面中按钮属性加载较慢,虽然能定位到这个元素,但还未加载出可点击属性,点了没有反应,这时可以使用显式等待,封装一个方法,如果点了没有反应,则利用显式等待,等一段时间再点一次,如果在显等的时间内,点了都没有反应,则抛出异常
如何通过子元素定位父元素
- 方法一:通过 element/.. 定位父结果,例如:
# 查找节点的父节点
$x('//*[@id="site-logo"]/..')
- 方法二:通过 parent::*定位父元素,例如:
# 查找节点的父节点
$x('//*[@id="site-logo"]/parent::*')
selenium框架的driver调用quit方法和调用close方法的区别是什么?
- quit:所有的浏览器窗口退出
- close:只关闭当前的浏览器标签页,如果当前浏览器标签页剩下最后一个,则所有标签页面退出
如何查看日志里面有 error 关键字的日志记录,与这个记录前后三行的日志信息
grep -C 3 "keyword" file_path
grep:文本搜索工具,可以接收管道传来的数据,这里是读取的文件的数据
-C n:将匹配到关键字的前后n行一同输出
“keyword”:预期被匹配到的关键字,在egrep或-E参数作用下,可以使用正则表达式
file_path:将文件内容作为输入
左连接,右链接,内链接分别是什么
内连接:获取两个表中字段匹配关系的记录,也就是两张表的交集。可以通过主外键关系做为条件来去除无用信息
左连接:先查询出左表,以左表为主,然后查询右表,右表中满足条件的显示出来,不满足条件的显示 NULL。
有连接:先把右表中所有记录都查询出来,以右表为主,然后查询左表,左表中满足条件的显示出来,不满足的显示 NULL。
Linux 中如何查看内存使用率
- top # top 命令监视进程和Linux整体性能,可以看到内存使用情况
- free -k -c 5 # free是专门查看当前系统内存的使用情况的工具,-k 是以千字节为单位,-c N 是按设定或默认的时间间隔重复打印,直到 N 次后自动退出
- vmstat -s # vmstat(虚拟内存统计)指令能对虚拟内存、进程、CPU等的整体情况进行监视,-s 显示详情
- cat /proc/meminfo 这个文件保存着内核使用内存情况的各种信息。是了解Linux系统内存使用状况的主要接口,free、vmstat等命令就是通过它获取数据的
Python的垃圾回收机制
- Python使用了两种内存分配策略:一种是引用统计,另一种是垃圾回收。
- 引用统计策略是当指向一个对象的引用统计为0,那么对象称之为内存垃圾,所占的内存被立即释放。
- 垃圾回收策略是通过三代垃圾收集器来跟踪内存中的所有对象。对于每一代,如果对象的数量超过对应的阈值,垃圾收集器将触发回收过程。
Pytest 的内置 fixture 有哪些
- pytest fixture 是一种使用@pytest.fixture定义的,通常在具体的测试函数之前或是之后运行的函数
- 可以使用pytest --fixtures查看 pytest 的所有 fixture 清单
- 常用的内置fixture有:
- request:用来获取测试函数请求信息
- capsys:用来访问被捕获的系统输出
- tempdir:用来获取一个临时目录:
MySQL 中删除语句有哪些
- 使用 delete 语句删除表中的行,如果不指定行可以删除表中的所有数据
- 使用 drop 语句可以删除数据库和整个表,包括表结构
- 使用 alter 语句可以删除表中的列和索引
- 使用 truncate 语句可以删除表中的数据,但是会保留表结构:
pycharm 简单的数据库管理
数据库创建方法
1)在pycharm的右上角找到‘database'选项卡
2)打开选项卡,按‘alt+insert'键,选择Data Source。
3)为数据库连接取一个名称,选择一个JDBC driver files。如果没有这个文件,pycharm可以自动下载。
4)选择一个JDBC driver class,mysql默认为:com.mysql.jdbc.Driver。oracle默认为:oracle.jdbc.OracleDriver
5)编写Database URL,示例:
myql:jdbc:mysql://localhost:3306
jdbc:oracle:thin:@localhost:1521:server
6)填写用户名和密码。
7)点击Test Connection测试连接。
8)根据提示信息修改错误,知道提示连接成功。
9)OK