Python+Pytest+Allure+Git+Jenkins接口自动化框架

news2024/11/14 8:44:10
一、接口基础

接口测试是对系统和组件之间的接口进行测试,主要是效验数据的交换,传递和控制管理过程,以及相互逻辑依赖关系。其中接口协议分为HTTP,RPC,Webservice,Dubbo,RESTful等类型。

接口测试流程

1、需求评审,熟悉业务和需求

2、开发提供接口文档

3、编写接口测试用例

4、用例评审

5、提测后开始测试

6、提交测试报告

两种常见的 HTTP 请求方法:GET 和 POST

二、项目说明

本框架是一套基于Python+Pytest+Requests+Allure+Jenkins而设计的数据驱动接口自动化测试的框架。

技术栈

Python、Pytest、Requests、Pactverity、Excel、Json、Mysql、Allure、Logbook、Git、Jenkins

三、接口测试框架结构图
在这里插入图片描述
四、项目功能

Python+Pytest+Allure+Jenkins接口自动化框架,实现Excel或Json维护测试用例,支持数据库操作,利用封装的请求基类调取相应的测试用例接口,获取配置文件中的环境地址与环境变量,

结合Pytest进行单元测试,使用LogBook进行记录日志,并生成allure测试报告,最后进行Jenkins集成项目实现集成部署,并发送测试报告邮件。

五、代码设计与功能说明

1、工具类封装

1.1、log日志

项目中的log日志是logbook进行日志记录的,方便测试开发调试时进行排错纠正或修复优化。日志可选择是否打印在屏幕上即运行时是否在终端输出打印。日志格式输出可调整。

handle_log.py部分源码

 
  1. def log_type(record, handler):

  2. 2 log = "[{date}] [{level}] [{filename}] [{func_name}] [{lineno}] {msg}".format(

  3. 3 date=record.time, # 日志时间

  4. 4 level=record.level_name, # 日志等级

  5. 5 filename=os.path.split(record.filename)[-1], # 文件名

  6. 6 func_name=record.func_name, # 函数名

  7. 7 lineno=record.lineno, # 行号

  8. 8 msg=record.message # 日志内容

  9. 9 )

  10. 10 return log

  11. 11 # 日志存放路径

  12. 12 LOG_DIR = BasePath + '/log'

  13. 13 print(LOG_DIR)

  14. 14 if not os.path.exists(LOG_DIR):

  15. 15 os.makedirs(LOG_DIR)

  16. 16 # 日志打印到屏幕

  17. 17 log_std = ColorizedStderrHandler(bubble=True)

  18. 18 log_std.formatter = log_type

  19. 19 # 日志打印到文件

  20. 20 log_file = TimedRotatingFileHandler(

  21. 21 os.path.join(LOG_DIR, '%s.log' % 'log'), date_format='%Y-%m-%d', bubble=True, encoding='utf-8')

  22. 22 log_file.formatter = log_type

  23. 23

  24. 24 # 脚本日志

  25. 25 run_log = Logger("global_log")

  26. 26 def init_logger():

  27. 27 logbook.set_datetime_format("local")

  28. 28 run_log.handlers = []

  29. 29 run_log.handlers.append(log_file)

  30. 30 run_log.handlers.append(log_std)

  31. 31 return ""

打印在终端的日志,如下图所示。

在这里插入图片描述

同时运行项目后,会在项目文件log中自动生成一个以当天日期命名的log文件。点击log日志文件可查看日志详情即项目运行时所记录的日志或报错日志。如下图所示。

在这里插入图片描述

1.2、配置文件

项目中涉及到一些配置文件如username、password或环境变量时,我们可通过配置文件来获取配置值。通过配置文件中key与value的定义来确定获取配置文件的值。

handle_init.py部分源码

 
  1. class HandleInit:

  2. 2 # 读取配置文件

  3. 3 def load_ini(self):

  4. 4 file_path = BasePath + "/config/config.ini"

  5. 5 cf = configparser.ConfigParser()

  6. 6 cf.read(file_path, encoding='UTF-8')

  7. 7 return cf

  8. 8

  9. 9 # 获取ini里面对应key的value

  10. 10 def get_value(self, key, node=None):

  11. 11 if node == None:

  12. 12 node = 'Test'

  13. 13 cf = self.load_ini()

  14. 14 try:

  15. 15 data = cf.get(node, key)

  16. 16 logger.info('获取配置文件的值,node:{},key:{}, data:{}'.format(node, key, data))

  17. 17 except Exception:

  18. 18 logger.exception('没有获取到对应的值,node:{},key:{}'.format(node, key))

  19. 19 data = None

  20. 20 return data

获取配置文件中的值日志如下图所示。

在这里插入图片描述

1.3、Api接口请求

获取相关测试用例及接口用例配置,记录请求相关参数的日志,定义Allure测试报告的步骤。

handle_apirequest.py部分代码

 
  1. class ApiRequest:

  2. 2 def api_request(self, base_url, test_case_data, case_data):

  3. 3 get_name = None

  4. 4 get_url = None

  5. 5 get_method = None

  6. 6 get_headers = None

  7. 7 get_cookies = None

  8. 8 get_case_name = None

  9. 9 get_case_params = None

  10. 10 response_data = None

  11. 11 try:

  12. 12 get_name = test_case_data['config']['name']

  13. 13 get_url = base_url + test_case_data['config']['url']

  14. 14 get_method = test_case_data['config']['method']

  15. 15 get_headers = test_case_data['config']['headers']

  16. 16 get_cookies = test_case_data['config']['cookies']

  17. 17 except Exception as e:

  18. 18 logger.exception('获取用例基本信息失败,{}'.format(e))

  19. 19 try:

  20. 20 get_case_name = case_data['name']

  21. 21 get_case_params = case_data['params']

  22. 22 except Exception as e:

  23. 23 logger.exception('获取测试用例信息失败,{}'.format(e))

  24. 24 with allure.step("请求接口:%s,请求地址:%s,请求方法:%s,请求头:%s,请求Cookies:%s" % (

  25. 25 get_name, get_url, get_method, get_headers, get_cookies)):

  26. 26 allure.attach("接口用例描述:", "{0}".format(get_case_name))

  27. 27 allure.attach("接口用例请求参数:", "{0}".format(get_case_params))

  28. 28 logger.info(

  29. 29 '请求接口名:%r,请求地址:%r,请求方法:%r,请求头:%r,请求Cookies:%r' % (get_name, get_url, get_method, get_headers, get_cookies))

  30. 30 logger.info('请求接口名:%r,请求接口用例名:%r,接口用例请求参数:%r' % (get_name, get_case_name, get_case_params))

  31. 31 try:

  32. 32 response_data = baseRequest.run_main(get_method, get_url, get_case_params, get_headers)

  33. 33 except Exception as e:

  34. 34 logger.exception('用例请求返回失败,{}'.format(e))

  35. 35 logger.info('请求接口名:%r,请求接口用例名:%r,返回参数:%r' % (get_name, get_case_name, response_data.json()))

  36. 36 return response_data

1.4、Excel数据处理

1.4.1、Excel测试用例

在这里插入图片描述

测试用例中维护在Excel文件中,类中定义如何获取Excel中的相关数据(如获取某个单元格的内容,获取单元格的行数,以及将数据写入Excel中等操作)。

handle_exceldata.py部分源码

 
  1. class OperationExcel:

  2. 2 def __init__(self, file_name=None, sheet_id=None):

  3. 3 if file_name:

  4. 4 self.file_name = file_name

  5. 5 self.sheet_id = sheet_id

  6. 6 else:

  7. 7 self.file_name = ''

  8. 8 self.sheet_id = 0

  9. 9 self.data = self.get_data()

  10. 10

  11. 11 # 获取sheets的内容

  12. 12 def get_data(self):

  13. 13 data = xlrd.open_workbook(self.file_name)

  14. 14 tables = data.sheets()[self.sheet_id]

  15. 15 return tables

  16. 16

  17. 17 # 获取单元格的行数

  18. 18 def get_lines(self):

  19. 19 tables = self.data

  20. 20 return tables.nrows

  21. 21

  22. 22 # 获取某一个单元格的内容

  23. 23 def get_cell_value(self, row, col):

  24. 24 return self.data.cell_value(row, col)

1.5、Json数据处理

1.5.1、Json测试用例

 
  1. {

  2. 2 "config":{

  3. 3 "name":"post接口名",

  4. 4 "url":"/langdetect",

  5. 5 "method":"POST",

  6. 6 "headers":{

  7. 7 "Content-Type":"application/json"

  8. 8 },

  9. 9 "cookies":{

  10. 10

  11. 11 }

  12. 12 },

  13. 13 "testcase":[

  14. 14 {

  15. 15 "name":"测试用例1",

  16. 16 "params":{

  17. 17 "query":"测试"

  18. 18 },

  19. 19 "validate":[

  20. 20 {

  21. 21 "check":"status_code",

  22. 22 "comparator":"eq",

  23. 23 "expect":"200"

  24. 24 }

  25. 25 ]

  26. 26 },

  27. 27 {

  28. 28 "name":"测试用例2",

  29. 29 "params":{

  30. 30 "query":"python"

  31. 31 },

  32. 32 "validate":[

  33. 33 {

  34. 34 "check":"msg",

  35. 35 "comparator":"eq",

  36. 36 "expect":"success"

  37. 37 }

  38. 38 ]

  39. 39 }

  40. 40 ]

  41. 41 }

1.5.2、Json用例处理

获取Json文件中里具体字段的值。

handle.json.py部分源码

 
  1. 1 class HandleJson:

  2. 2 # 读取json文件

  3. 3 def load_json(self, file_name):

  4. 4 if file_name == None:

  5. 5 file_path = ""

  6. 6 else:

  7. 7 file_path = file_name

  8. 8 try:

  9. 9 with open(file_path, encoding='UTF-8') as f:

  10. 10 data = json.load(f)

  11. 11 return data

  12. 12 except Exception:

  13. 13 print("未找到json文件")

  14. 14 return {}

  15. 15

  16. 16 # 读取json文件里具体的字段值

  17. 17 def getJson_value(self, key, file_name):

  18. 18 if file_name == None:

  19. 19 return ""

  20. 20 jsonData = self.load_json(file_name)

  21. 21 if key == None:

  22. 22 getJsonValue = ""

  23. 23 else:

  24. 24 getJsonValue = jsonData.get(key)

  25. 25 return getJsonValue

2、基类封装

2.1、请求基类封装

接口支持Get、Post请求,调用requests请求来实现接口的调用与返回。接口参数包括,接口地址、接口请求参数、cookie参数、header参数。

 
  1. 1 class BaseRequest:

  2. 2

  3. 3 def send_get(self, url, data, header=None, cookie=None):

  4. 4 """

  5. 5 Requests发送Get请求

  6. 6 :param url:请求地址

  7. 7 :param data:Get请求参数

  8. 8 :param cookie:cookie参数

  9. 9 :param header:header参数

  10. 10 """

  11. 11 response = requests.get(url=url, params=data, cookies=cookie, headers=header)

  12. 12 return response

  13. 13

  14. 14 def send_post(self, url, data, header=None, cookie=None):

  15. 15 """

  16. 16 Requests发送Post请求

  17. 17 :param url:请求地址

  18. 18 :param data:Post请求参数

  19. 19 :param data:Post请求参数

  20. 20 :param cookie:cookie参数

  21. 21 :param header:header参数

  22. 22 """

  23. 23 response = requests.post(url=url, json=data, cookies=cookie, headers=header)

  24. 24 return response

  25. 25

  26. 26 # 主函数调用

  27. 27

  28. 28 def run_main(self, method, url, data, header, cookie=None):

  29. 29 try:

  30. 30 result = ''

  31. 31 if method.upper() == 'GET':

  32. 32 result = self.send_get(url, data, header, cookie)

  33. 33 elif method.upper() == 'POST':

  34. 34 result = self.send_post(url, data, header, cookie)

  35. 35 return result

  36. 36 except Exception as e:

  37. 37 logger.exception('请求主函数调用失败:{}'.format(e))

3、接口测试用例编写
3.1、接口测试用例

引用Pytest来进行接口的单元测试,通过JSON中多个测试用例来做为参数化数据驱动。结合Allure制定相应接口的测试报告。在接口返回断言之前,我们先进行该接口的契约测试,

我们采用的是Pactverity的全量契约校验测试。当契约测试通过时,我们再进行返回参数的相关校验测试。

test_getRequestJson.py部分源码
 

 
  1. @allure.feature('测试GET请求模块')

  2. 2 class TestRequestOne():

  3. 3 @allure.title('测试标题')

  4. 4 @allure.testcase('测试地址:https://www.imooc.com')

  5. 5 @pytest.mark.parametrize('case_data', testCaseData['testcase'])

  6. 6 def test_requestOne(self, case_data):

  7. 7 try:

  8. 8 api_response = apiRequest.api_request(baseurl, testCaseData, case_data)

  9. 9 api_response_data = api_response.json()

  10. 10 # pactverity——全量契约校验

  11. 11 config_contract_format = Like({

  12. 12 "msg": "成功",

  13. 13 "result": 0,

  14. 14 "data": EachLike({

  15. 15 "word": Like("testng")

  16. 16 })

  17. 17 })

  18. 18 mPactVerify = PactVerify(config_contract_format)

  19. 19 try:

  20. 20 mPactVerify.verify(api_response_data)

  21. 21 logger.info(

  22. 22 'verify_result:{},verify_info:{}'.format(mPactVerify.verify_result, mPactVerify.verify_info))

  23. 23 assert mPactVerify.verify_result == True

  24. 24 except Exception:

  25. 25 err_msg = '契约校验错误'

  26. 26 logger.exception('测试用例契约校验失败,verify_result:{},verify_info:{}'.format(mPactVerify.verify_result,

  27. 27 mPactVerify.verify_info))

  28. 28 try:

  29. 29 for case_validate in case_data['validate']:

  30. 30 logger.info('断言期望相关参数:check:{},comparator:{},expect:{}'.format(case_validate['check'],

  31. 31 case_validate['comparator'],

  32. 32 case_validate['expect']))

  33. 33 comparatorsTest.comparators_Assert(api_response, case_validate['check'],

  34. 34 case_validate['comparator'], case_validate['expect'])

  35. 35 logger.info('测试用例断言成功')

  36. 36 except Exception as e:

  37. 37 logger.exception('测试用例断言失败')

  38. 38 except Exception as e:

  39. 39 logger.exception('测试用例请求失败,原因:{}'.format(e))

3.2、主运行

运用Pytest和Allure的特性,命令行运行测试用例文件夹,并生成对应的allure测试报告。

 
  1. if __name__ == "__main__":

  2. 2 pytest.main(['-s', '-v', 'test_case/testRequest/', '-q', '--alluredir', 'reports'])

4、Allure2测试报告
当我们运行主函数时,并生成对应的测试用例报告时,我们可以看到在该文件夹中会生成对应的json文件的测试报告。将json文件的测试报告转换成html形式的。命令如下

reports是json格式测试报告存放的目录位置,allure_reports是html测试报告文件生成的目录位置。allure命令如下。

1 allure generate reports -o allure_result/

项目根目录下的allure_reports文件,存放的是allure生成的测试报告。可看出文件下有一个HTML文件,可通过Python的编辑器Pycharm来打开该HTML文件(测试报告),

或可通过allure命令来打开该HTML,展示HTML测试报告。如下所示。

测试报告文件,HTML测试报告如下。

在这里插入图片描述

allure命令打开HTML测试报告。命令如下所示。

1 allure open allure_result/

如下图所示。

在这里插入图片描述

打开生成的HTML测试报告如下图所示。

在这里插入图片描述

5、Jenkins集成
Allure+Jenkins的分享,我之前在Pytest+Allure+Jenkins的博客中已经分享过了。这块可以出门左转看看。前期的准备就不在这里重复说明了。我们就直接来上手创建Item进行相关配置。

General中GitHub项目地址的配置,将自己项目的Git复制至项目URL处。如下图所示。

在这里插入图片描述
源码管理设置。勾选Git,填写相应的项目Git地址,Git项目权限所有者,以及对应的拉取代码的分支。如下图所示。

在这里插入图片描述

配置构建命令。选择“执行windows批处理命令”,用python运行主函数运行脚本,命令如下图所示。

在这里插入图片描述

当我们在Jenkins里面成功安装Allure插件后,直接可以在构建后操作中配置Allure的相关配置。在Pytest+Allure+Jenkins中已经说明过的。

Results应与项目运行时设置的Allure生成的Json格式报告的路径一致,Report path为Allure html报告结果生成文件存放的路径。

在这里插入图片描述

排除万难之后,我们就可以用Jenkins来运行项目了。如下图所示。

在这里插入图片描述

测试报告详情页,如下图所示。 

在这里插入图片描述

六、后期优化

1、接口测试用例之间的数据依赖

2、测试报告邮件的发送

七、感想

该框架是在涉及python的知识点比较多,将接口测试与契约测试结合起来。该框架是在工作之余学习多篇文章,实战上手逐步入门开始的,适合新手入门接口自动化实战练习,仅供参考学习。框架中有不少可优化点与不足点,希望大家多多提建议或想法。

 感谢每一个认真阅读我文章的人!!!

作为一位过来人也是希望大家少走一些弯路,如果你不想再体验一次学习时找不到资料,没人解答问题,坚持几天便放弃的感受的话,在这里我给大家分享一些自动化测试的学习资源,希望能给你前进的路上带来帮助。

软件测试面试文档

我们学习必然是为了找到高薪的工作,下面这些面试题是来自阿里、腾讯、字节等一线互联网大厂最新的面试资料,并且有字节大佬给出了权威的解答,刷完这一套面试资料相信大家都能找到满意的工作。

 

          视频文档获取方式:
这份文档和视频资料,对于想从事【软件测试】的朋友来说应该是最全面最完整的备战仓库,这个仓库也陪伴我走过了最艰难的路程,希望也能帮助到你!以上均可以分享,点下方小卡片即可自行领取。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/2239107.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

Docker:镜像构建 DockerFile

Docker:镜像构建 DockerFile 镜像构建docker build DockerfileFROMCOPYENVWORKDIRADDRUNCMDENTRYPOINTUSERARGVOLUME 镜像构建 在Docker官方提供的镜像中,大部分都是基础镜像,他们只提供某个简单的功能,如果想要一个功能更加丰富…

《JavaEE进阶》----20.<基于Spring图书管理系统①(登录+添加图书)>

PS:关于接口定义 接口定义,通常由服务器提供方来定义。 1.路径:自己定义 2.参数:根据需求考虑,我们这个接口功能完成需要哪些信息。 3.返回结果:考虑我们能为对方提供什么。站在对方角度考虑。 我们使用到的…

【JavaEE】文件io

目录 文件类型 File概述 属性 构造方法 常用方法 Reader Writer InputStream OutputStream 字节流转字符流 通过Scanner读取InputStream 通过PrintWriter转换outputstream 示例 文件类型 从编程的角度看,文件类型主要就是两大类 文本(文…

D3入门:概念、主要特点、基本功能、常见应用场景

D3.js(Data-Driven Documents)是一个JavaScript库,用于基于数据操作文档。它利用了HTML、SVG和CSS等Web标准技术,使得开发者可以创建丰富的交互式图表和数据可视化。D3.js的强大之处在于其灵活的数据绑定机制和对DOM元素的高效操作…

go函数传值是值传递?还是引用传递?slice案例加图解

先说下结论 Go语言中所有的传参都是值传递(传值),都是一个副本,一个拷贝。 值语义类型:参数传递的时候,就是值拷贝,这样就在函数中就无法修改原内容数据。 基本类型:byte、int、bool…

tensorflow案例5--基于改进VGG16模型的马铃薯识别,准确率提升0.6%,计算量降低78.07%

🍨 本文为🔗365天深度学习训练营 中的学习记录博客🍖 原作者:K同学啊 前言 本次采用VGG16模型进行预测,准确率达到了98.875,但是修改VGG16网络结构, 准确率达到了0.9969,并且计算量…

攻防世界38-FlatScience-CTFWeb

攻防世界38-FlatScience-Web 点开这个here看到一堆pdf,感觉没用&#xff0c;扫描一下 试试弱口令先 源码里有&#xff1a; 好吧0.0 试试存不存在sql注入 根本没回显&#xff0c;转战login.php先 输入1’,发现sql注入 看到提示 访问后得源码 <?php ob_start(); ?>…

数据分析-44-时间序列预测之深度学习方法TCN

文章目录 1 TCN简介1.1 网络示意图1.2 TCN优点2 模拟应用2.1 模拟数据2.2 预处理创建滞后特征2.3 划分训练集和测试集2.4 创建TCN模型2.5 模型训练2.6 模型预测3 自定义my_TCN模型3.1 my_TCN()函数3.2 训练模型3.3 模型预测3.4 改进4 参考附录1 TCN简介 时间卷积网络(TCN)是…

C++【STL容器系列(二)】vector的模拟实现

文章目录 1. vector的结构2. vector的默认成员函数2.1构造函数2.1.1 默认构造2.1.2 迭代器构造2.1.3 用n个val初始化构造 2.2 拷贝构造2.3 析构函数2.4 operator 3. vector iterator函数3.1 begin 和 cbegin函数3.2 end() 和 cend()函数 4. vector的小函数4.1 size函数4.2 capa…

【linux】网络基础 ---- 应用层

1. 再谈 "协议" 协议是一种 "约定"&#xff0c;在读写数据时, 都是按 "字符串" 的方式来发送接收的. 但是这里我们会遇到一些问题&#xff1a; 如何确保从网上读取的数据是否是完整的&#xff0c;区分缓冲区中的由不同客户端发来的数据 2. 网…

C语言PythonBash:空白(空格、水平制表符、换行符)与转义字符

C语言 空白 C语言中的空白&#xff08;空格、水平制表符、换行符&#xff09;被用于分隔Token&#xff0c;因此Token间可以有任意多个空白。 // 例1 printf("Hello, World!"); 例1中存在5个Token&#xff0c;分别是&#xff1a; printf("Hello, World! \n&qu…

Linux基础(十四)——BASH

BASH 1.BASH定义2.shell的种类3.bash的功能3.1 命令记录功能3.2 命令补全功能3.3 命令别名设置3.4 工作控制、 前景背景控制3.5 程序化脚本&#xff1a; &#xff08; shell scripts&#xff09;3.6 万用字符 4.bash的内置命令5.shell的变量功能5.1 变量的取用5.2 新建变量5.3 …

【重学 MySQL】八十二、深入探索 CASE 语句的应用

【重学 MySQL】八十二、深入探索 CASE 语句的应用 CASE语句的两种形式CASE语句的应用场景数据分类动态排序条件计算在 SELECT 子句中使用在 WHERE子句中使用在 ORDER BY 子句中使用 注意事项 在MySQL中&#xff0c;CASE 语句提供了一种强大的方式来实现条件分支逻辑&#xff0c…

由播客转向个人定制的音频频道(1)平台搭建

项目的背景 最近开始听喜马拉雅播客的内容&#xff0c;但是发现许多不方便的地方。 休息的时候收听喜马拉雅&#xff0c;但是还需要不断地选择喜马拉雅的内容&#xff0c;比较麻烦&#xff0c;而且黑灯操作反而伤眼睛。 喜马拉雅为代表的播客平台都是VOD 形式的&#xff0…

7+纯生信,单细胞识别细胞marker+100种机器学习组合建模,机器学习组合建模取代单独lasso回归势在必行!

影响因子&#xff1a;7.3 研究概述&#xff1a; 皮肤黑色素瘤&#xff08;SKCM&#xff09;是所有皮肤恶性肿瘤中最具侵袭性的类型。本研究从GEO数据库下载单细胞RNA测序&#xff08;scRNA-seq&#xff09;数据集&#xff0c;根据原始研究中定义的细胞标记重新注释各种免疫细胞…

uniapp解析蓝牙设备响应数据bug

本文章为了解决《uniapp 与蓝牙设备收发指令详细步骤(完整项目版)》中第十步的Array 解析成 number函数bug 1、原代码说明 function array16_to_number(arrayValue) {const newArray arrayValue.filter(item > String(item) ! 00 || String(item) ! 0)const _number16 ne…

【递归回溯与搜索算法篇】算法的镜花水月:在无尽的自我倒影中,递归步步生花

文章目录 递归回溯搜索专题&#xff08;一&#xff09;&#xff1a;递归前言第一章&#xff1a;递归基础及应用1.1 汉诺塔问题&#xff08;easy&#xff09;解法&#xff08;递归&#xff09;C 代码实现时间复杂度和空间复杂度易错点提示 1.2 合并两个有序链表&#xff08;easy…

大数据开发面试宝典

312个问题&#xff0c;问题涵盖广、从自我介绍到大厂实战、19大主题&#xff0c;一网打尽、真正提高面试成功率 一、Linux 1. 说⼀下linux的常⽤命令&#xff1f; 说一些高级命令即可 systemctl 设置系统参数 如&#xff1a;systemctl stop firewalld关闭防火墙 tail / hea…

链表归并与并集相关算法题|两递增归并为递减到原位|b表归并到a表|两递减归并到新链表(C)

两递增归并为递减到原位 假设有两个按元素递增次序排列的线性表&#xff0c;均以单链表形式存储。将这两个单链表归并为一个按元素递减次序排列的单链表&#xff0c;并要求利用原来两个单链表的节点存放归并后的单链表 算法思想 因为两链表已按元素值递增次序排列&#xff0…

【RabbitMQ】06-消费者的可靠性

1. 消费者确认机制 没有ack&#xff0c;mq就会一直保留消息。 spring:rabbitmq:listener:simple:acknowledge-mode: auto # 自动ack2. 失败重试机制 当消费者出现异常后&#xff0c;消息会不断requeue&#xff08;重入队&#xff09;到队列&#xff0c;再重新发送给消费者。…