自主研发接口测试框架

news2024/11/15 21:31:56

测试任务:将以前完成的所有的脚本统一改写为unitest框架方式

1、需求原型

1.1 框架目录结构

V1.0:一般的设计思路分为配置层、脚本层、数据层、结果层,如下图所示

V 2.0:加入驱动层testdriver

1.2 框架各层需要完成的工作

1、配置层:config

设计配置文件.csv:由配置文件来控制此次测试执行,以及需要调用哪些测试脚本。

2、脚本层:script

ind_interface:存放独立接口测试脚本、一个类中有一个测试方法、完成一个接口的测试。

mul_interface:存放接口联调测试脚本、一个类中有多个测试方法、完成接口联调的测试。

注意:脚本文件的名称有一定的规范性。

3、测试数据文件层:testdatafile

ind_interface:存放独立接口测试脚本对应的测试数据文件

mul_interface:存放接口联调测试脚本对应的测试数据文件

注意:数据文件的命名 ind_、 mul_

4、测试报告文件层:testresultfile

fram_result:测试框架报告

ind_interface:存放独立接口测试报告文档

mul_interface:存放联调接口测试报告文档

注意:报告文件命名 fram_  、ind_rep_  、mul_rep_

5、框架驱动层

存放测试框架的驱动程序

1.3  框架的测试执行过程

1、由框架驱动层中的框架驱动程序运行。

2、依据配置层相关的设置是否执行及执行顺序,调用对应脚本层的程序,进行执行。

3、相关的脚本运行时,如果需要测试数据,则在数据层进行文件的读取。

4、测试脚本执行结束后,会写明相关的测试报告文件,并存入测试报告层。

1.4 最终目标

2、测试框架前期准备

1、依据框架需求搭建框架项目及模块

2、接口测试数据文件向框架转移

3、框架脚本的研发

3.1 重构测试脚本

更新用户信息接口测试,在框架对应的分层下创建新的python文件,注意符合命名规范,test_updateuser

3.1.1  更新用户信息接口V1.0

V1.0版本
    S1:导入unittest
    S2:定义一个类,继承unittest
    S3:传入固定的接口测试数据(一组)
    S4:assert进行判断

# 对更新用户信息的脚本进行测试,使用unittest框架技术,V1.0版本,传入一组固定的测试数据,进行接口测试
# 接口说明:
# 接口访问地址:   http://localhost:8080/jwshoplogin/user/update_information.do
# 接口传入参数:1、email: 2、phone:3、answer: 4、question:
# 接口预期返回结果:
# 1、email已存在, 请更换email再尝试更新 2、更新个人信息成功  3、更新个人信息失败"
#*****************************************************************************
# 脚本实现:
# 导入相关类库
import unittest
import requests

# 定义测试类,继承unittest框架
class test_updateuser(unittest.TestCase):
    # 通过setup方法实现登录接口的调用
    def setUp(self):
        url="http://localhost:8080/jwshoplogin/user/login.do"
        userinfo={"username":"程勇4",
                  "password":"123456"}

        response=requests.post(url,data=userinfo)

        self.sessionID=dict(response.cookies)['JSESSIONID']
        print(self.sessionID)

    # V1.0版本,传入一组固定的测试数据,进行接口测试
    def test_case1(self):
        # 传入指定的接口测试数据
        url="http://localhost:8080/jwshoplogin/user/update_information.do"
        userinfo={"email":"1234561@qq.com",
                  "phone":"13311095555",
                  "question": "苹果",
                  "answer":"最喜欢的水果"
        }
        session={"JSESSIONID":self.sessionID}
        # 进行接口调用
        response=requests.post(url,data=userinfo,cookies=session).text
        print(response)
        self.assertIn("更新个人信息成功",response)

    def tearDown(self):
        pass

if __name__ == '__main__':
    unittest.main()

3.1.2  更新用户信息接口V2.0

S1:是否需要测试数据文件
    对测试数据文件进行设计
        测试用例的设计
    更新接口测试分析
        正常
            只更新一个数据
                1、只更新email
                    email不冲突
                2、只更新phone
                3、只更新answer
                4、只更新问题question
            更新更多数据
                更新2组数据
                    更新email和phone
                        email不冲突
                    更新question和answer
                    更新...
                更新3组数据
                    更新email和phone和question
            更新全部数据
                1、email
                    email不冲突
                2、phone
                3、answer
                4、question
        异常
            1、未登录更新
            2、邮箱冲突
            3、电话的长度不正确
            4、问题为空
            5、答案为空
S2:把数据文件中的内容传入脚本

# V2.0 通过csv文件进行更新测试数据的读取

# 接口说明:
# 接口访问地址:   http://localhost:8080/jwshoplogin/user/update_information.do
# 接口传入参数:1、email: 2、phone:3、answer: 4、question:
# 接口预期返回结果:
# 1、email已存在, 请更换email再尝试更新 2、更新个人信息成功  3、更新个人信息失败"
#*****************************************************************************
# 脚本实现:
# 导入相关类库
import os
import unittest
import requests
import csv

# 定义测试类,继承unittest框架
class test_updateuser_V2(unittest.TestCase):
    # 通过setup方法实现登录接口的调用
    def setUp(self):
        # # 从csv测试数据文件中读取url和登录测试数据
        path=os.getcwd()
        print(path)
        # p1=os.path.abspath(os.path.dirname(path)+os.path.sep+".")
        # print(p1)
        p2 = os.path.abspath(os.path.dirname(path) + os.path.sep + "..")
        self.fpath=p2+"\\testdatafile\\ind_interface\\test_updateuser_V21.csv"
        # print(fpath)
        userinfo={}
        file1=open(self.fpath,'r')
        table=csv.reader(file1)
        for row in table:
            print(row[0])
            url=row[0]
            userinfo[row[3]]=row[4]
            userinfo[row[5]]=row[6]
            print(userinfo)
            break  # 读完一行就退出
        response=requests.post(url,data=userinfo)
        self.sessionID=dict(response.cookies)['JSESSIONID']
        print(self.sessionID)

    # V2.0版本,读取指定的测试数据文件中对应的内容,进行接口测试
    def test_case1(self):
        # 打开对应的文件
        file1=open(self.fpath,'r')
        # 如何从指定行开始读取
        table=csv.reader(file1)
        userinfo={}
        num=0
        for row in table:
            num=num+1
            if num>1:
                url=row[0]
                expresult=row[2]
                j=int(row[1])
                for i in range(3,j*2+3,2):
                    userinfo[row[i]]=row[i+1]
                print(userinfo)
                session={"JSESSIONID":self.sessionID}
                print(session)
                response=requests.post(url,data=userinfo,cookies=session).text
                print(response)
                userinfo={}
                self.assertIn("更新个人信息成功",response)


if __name__ == '__main__':
    unittest.main()

工作小结:需要注意的事项
    1、文件位置的读取
        import os
        获取当前路径
            path=os.getcwd()
        获取上一级路径
            p1=os.path.abspath(os.path.dirname(path)+os.path.sep+".")
        获取前两级路径
            p2 = os.path.abspath(os.path.dirname(path) + os.path.sep + "..")
    2、测试数据文件的设计
        可以把固定的内容放在前面的列中
        把不定项的参数可以放在后面的列中
        通过手工加入参数个数。方便进行循环读取
        不要用拖拽的方式拷贝数据,防止数据出错
        先设计正确的数据,保证脚本调试通过
        再设计错误的数据
            也可以考虑放在不同的文件
    3、从指定的某一行开始读取内容
        num=0
        for row in table:
        追加
            num=num+1
        例如:我们想从第四行读起
            if num>4
            从指定的行开始进行读取

3.1.3  更新用户信息接口V3.0

生成HTML格式的测试报告

步骤
    1、下载HTML格式的测试报告
        步骤
            1、下载HTMLTestRunner.py
                http://tungwaiyip.info/software/HTMLTestRunner.html
            2、拷贝到项目文件夹下
            3、导入HTMLReport包
                from HTMLTestRunner import HTMLTestRunner
            4、生成测试报告的脚本
                脚本
                    做好测试执行前的准备工作
                        指定要执行的测试用例
                    S1:以wb(二进制写文件)模式打开测试报告文件
                    S2:使用HTMLTestRunner方法创建HTML文件
                    S3:执行测试
                    S4:关闭文件
    工作小结
        在main()函数中来生成html的测试报告
            1、获取测试报告文件应放置的路径
            2、给定具体的测试报告文件名
            3、以wb的方式打开文件
            4、设置测试套,并添加要 测试的方法
            5、生成HTML报告
                runner=HTMLTestRunner(stream=file,title="标题",description="描述")
            6、调用runner对象执行测试套
                runner.run(suite)
            7、关闭测试报告文件

# v3.0  创建HTML格式的测试报告文件

# 接口说明:
# 接口访问地址:   http://localhost:8080/jwshoplogin/user/update_information.do
# 接口传入参数:1、email: 2、phone:3、answer: 4、question:
# 接口预期返回结果:
# 1、email已存在, 请更换email再尝试更新 2、更新个人信息成功  3、更新个人信息失败"
#*****************************************************************************
# 脚本实现:
# 导入相关类库
import os
import unittest
import requests
import csv
from HTMLTestRunner import HTMLTestRunner

# 定义测试类,继承unittest框架
class test_updateuser_V3(unittest.TestCase):
    # 通过setup方法实现登录接口的调用
    def setUp(self):
        # # 从csv测试数据文件中读取url和登录测试数据
        path=os.getcwd()
        # print(path)
        # p1=os.path.abspath(os.path.dirname(path)+os.path.sep+".")
        # print(p1)
        p2 = os.path.abspath(os.path.dirname(path) + os.path.sep + "..")
        print(p2)
        self.fpath=p2+"\\testdatafile\\ind_interface\\test_updateuser_V21.csv"
        # print(fpath)
        userinfo={}
        file1=open(self.fpath,'r')
        table=csv.reader(file1)
        for row in table:
            print(row[0])
            url=row[0]
            userinfo[row[3]]=row[4]
            userinfo[row[5]]=row[6]
            print(userinfo)
            break
        response=requests.post(url,data=userinfo)
        self.sessionID=dict(response.cookies)['JSESSIONID']
        print(self.sessionID)


    def test_case1(self):
        # 打开对应的文件
        file1=open(self.fpath,'r')
        # 如何从指定行开始读取
        table=csv.reader(file1)
        userinfo={}
        num=0
        for row in table:
            num=num+1
            if num>1:
                url=row[0]
                expresult=row[2]
                j=int(row[1])
                for i in range(3,j*2+3,2):
                    userinfo[row[i]]=row[i+1]
                print(userinfo)
                session={"JSESSIONID":self.sessionID}
                print(session)
                response=requests.post(url,data=userinfo,cookies=session).text
                print(response)
                userinfo={}
                self.assertIn("更新个人信息成功",response)


if __name__ == '__main__':
    # unittest.main()
    # 定义测试报告文件
    path=os.getcwd()
    p2 = os.path.abspath(os.path.dirname(path) + os.path.sep + "..")
    filename=p2+"\\testresultfile\\ind_interface\\test_updatauser_report.html"

    # 加载测试套
    suite=unittest.TestSuite()
    suite.addTest(test_updateuser_V3("test_case1"))
    # 以wb的方式打开文件
    file=open(filename,"wb")

    # 调用HTML测试报告的报告生成测试报告
    runner=HTMLTestRunner(stream=file,title="更新用户接口测试",description="接口测试报告")
    print("测试报告")
    runner.run(suite)
    file.close()

3.1.4 遇到问题分析

更新用户的接口,需要先进行登录
   1、测试场景1:未登录,进行更新
        提示:用户未登录
   2、 测试场景2:先登录,再进行更新
        需要解决的问题
            解决方案
                方案1
                    在当前的测试类中,追加一个setup方法
                        登录的测试脚本写入setup中
                        用的比较多
                方案2:
                    在当前的测试类中,追加一个新的测试方法
                        test_case1
                            完成登录的调用
                        把原来的更新测试方法改为test_case2
                方案3:
                    在当前的测试类及测试方法中
                        前面追加一段代码
                            完成登录的调用
                方案4:
                    另外创建一个脚本文件,来实现登录,通过测试框架进行接口测试联调
    3、遇到的问题
        即使已经发送了登录请求,在调用更新接口时提示"用户未登录"
    问题分析
        sessionID
            服务器端发送给客户端一个随机的认证号码
        方法1:
            使用postman工具
                先登录
                再修改个人信息是否可行
        方法2:
            通过工具获取JESSIONID
            再把相关的JESSION传入代码中
            问题:
                1、JessionID有时间限制
                2、如果关闭tomcat服务重新启动,session自动失效了
                3、用工具过去的session ID和登录脚本没有任何关系
        方法3
            在用户登录之后获取到对应的JESSIONID
                dict(response.cookie)["JSESSIONID"]
            把这个JESSIONID当成传输参数传递给更新脚本
                self.sessionID
            要解决的问题
                如何在登录后获取对应的JESSIONID

4、设计及实现框架驱动程序

4.1 框架驱动程序V1.0

在配置文件中写入一个测试文件进行执行


    S1:设计一个配置文件
        脚本名称
        脚本所在路径
    S2:读取配置文件的内容
    S3:找到对应的脚本文件进行调用
    工作小结
        工作思路
            由简到繁
                选择一种框架调用模式
                    defaultloader方式
                        unittest.defaultTestLoader.discover(路径,pattern=脚本名称)
                先用常量值进行脚本的调试
                在把常量值改为变量值
                    逐个替换
                    不要全部替换
                再把变量改为从文件读取
            发现问题,添加print语句进行分析
                问题:路径不一致
                    级别关系发生了变化
                        print(path)
                调整脚本中对应的路径级别

# 测试框架驱动程序V1.0版本
# 只是从配置文件中读取一个脚本文件进行调用
import csv
import unittest
if __name__ == '__main__':
    # 指定对应的脚本路径,从csv文件中读取相关路径和文件名
    file=open("D:\python\interfacefram\config\config1.csv","r")
    table=csv.reader(file)
    num=0
    for row in table:
        if num>0:
            testdir=row[0]
            fname=row[1]
            print(testdir,fname)
        num=num+1
    discover=unittest.defaultTestLoader.discover(testdir,pattern=fname)
    # # 定义一个运行对象
    runner=unittest.TextTestRunner()
    runner.run(discover)

4.2 框架驱动程序V2.0

在配置文件中写入两个测试文件进行执行

S1:修改配置文件

S2:进行脚本的修改

# 测试框架驱动程序V2.0版本
# 只是从配置文件中读取两个脚本文件进行调用
import csv
import unittest
if __name__ == '__main__':
    # 指定对应的脚本路径,从csv文件中读取相关路径和文件名
    file=open("D:\python\interfacefram\config\config2.csv","r")
    table=csv.reader(file)
    num=0
    for row in table:
        if num>0:
            testdir=row[0]
            fname=row[1]
            print(testdir,fname)
            discover = unittest.defaultTestLoader.discover(testdir, pattern=fname)
            # # 定义一个运行对象
            runner = unittest.TextTestRunner()
            runner.run(discover)
        num=num+1

4.3 框架驱动程序V3.0

在配置文件中针对不同的运行状态进行文件的执行
    S1:升级改造配置文件
        加入一状态列
            状态表示
                0/1不运行/运行
                RUN/NORUN
                No/Yes
    S2:脚本的调整
        加入条件判断

# v3.0  创建HTML格式的测试报告文件

# 接口说明:
# 接口访问地址:   http://localhost:8080/jwshoplogin/user/update_information.do
# 接口传入参数:1、email: 2、phone:3、answer: 4、question:
# 接口预期返回结果:
# 1、email已存在, 请更换email再尝试更新 2、更新个人信息成功  3、更新个人信息失败"
#*****************************************************************************
# 脚本实现:
# 导入相关类库
import os
import unittest
import requests
import csv
from HTMLTestRunner import HTMLTestRunner

# 定义测试类,继承unittest框架
class test_updateuser_V3(unittest.TestCase):
    # 通过setup方法实现登录接口的调用
    def setUp(self):
        # # 从csv测试数据文件中读取url和登录测试数据
        path=os.getcwd()
        # print(path)
        # p1=os.path.abspath(os.path.dirname(path)+os.path.sep+".")
        # print(p1)
        p2 = os.path.abspath(os.path.dirname(path) + os.path.sep + "..")
        print(p2)
        self.fpath=p2+"\\testdatafile\\ind_interface\\test_updateuser_V21.csv"
        # print(fpath)
        userinfo={}
        file1=open(self.fpath,'r')
        table=csv.reader(file1)
        for row in table:
            print(row[0])
            url=row[0]
            userinfo[row[3]]=row[4]
            userinfo[row[5]]=row[6]
            print(userinfo)
            break
        response=requests.post(url,data=userinfo)
        self.sessionID=dict(response.cookies)['JSESSIONID']
        print(self.sessionID)


    def test_case1(self):
        # 打开对应的文件
        file1=open(self.fpath,'r')
        # 如何从指定行开始读取
        table=csv.reader(file1)
        userinfo={}
        num=0
        for row in table:
            num=num+1
            if num>1:
                url=row[0]
                expresult=row[2]
                j=int(row[1])
                for i in range(3,j*2+3,2):
                    userinfo[row[i]]=row[i+1]
                print(userinfo)
                session={"JSESSIONID":self.sessionID}
                print(session)
                response=requests.post(url,data=userinfo,cookies=session).text
                print(response)
                userinfo={}
                self.assertIn("更新个人信息成功",response)


if __name__ == '__main__':
    # unittest.main()
    # 定义测试报告文件
    path=os.getcwd()
    p2 = os.path.abspath(os.path.dirname(path) + os.path.sep + "..")
    filename=p2+"\\testresultfile\\ind_interface\\test_updatauser_report.html"

    # 加载测试套
    suite=unittest.TestSuite()
    suite.addTest(test_updateuser_V3("test_case1"))
    # 以wb的方式打开文件
    file=open(filename,"wb")

    # 调用HTML测试报告的报告生成测试报告
    runner=HTMLTestRunner(stream=file,title="更新用户接口测试",description="接口测试报告")
    print("测试报告")
    runner.run(suite)
    file.close()

4.4 框架驱动程序V4.0

按照测试人员指定的顺序来执行相应的测试文件
    S1:升级改造配置文件
        加入执行顺序
    S2:修改脚本

# v4.0  执行任意指定路径下的任意相关命名的python测试脚本
# 脚本实现:
import unittest
import requests

if __name__ == '__main__':

    #**********************************************
    #以文件的方式来进行框架的执行
    #声明文件所在路径
    testdir='./'
    discover=unittest.defaultTestLoader.discover(testdir,pattern='test_updateser_v1.py')
    #声明测试运行对象
    runner=unittest.TextTestRunner()
    runner.run(discover)

4.5 按照测试顺序和是否运行来确定要执行哪些测试V5.0

其实框架难的地方也就是在驱动的处理这。

按照测试顺序和是否运行来确定要执行哪些测试
    复杂程序的编写思路
        分解任务,逐个击破
        逐步合并,分段调试
        脚本设计思路
            突破点
                python提供的数据字典的排序
                    脚本名
                    脚本路径
                    执行顺序
                    是相关的一组数据,不是无关的
                    import operator
                    sorted(数据字典,key=operator.itemgetter(下标或标签))


            试验1
                给定一些字典的具体数据
                    dic={"testA":3,"testC":1,"testB:4,"testD:2}
                    dicn=sorted(dic.items(),key=operator.itemgetter(1))
                    print(dicn)
                    for fn in dicn:
                    print(fn[0])
                排序算法是否可行
            试验2
                把csv配置文件的一行内容导入到字典中
                代码部分实现
                        file=open("D:\python\interfacefram\config\config4.csv","r")
                        table=csv.reader(file)
                        dic={}
                        listd=[]
                        line=0
                        for row in table:
                        if line>0:
                            跳过第一行
                        #把文件中读取的数据放入字典
                            dic={}
                                每读一行,字典清空一次
                            dic[row[1]]=row[0]
                            dic["num"]=int(row[3])
                                文件执行顺序
                            print("dicn",dicn)
            试验3
                把csv配置文件的多行内容导入到字典列表中
                    listd=[]
                    line=line+1
                    if dic!={}:
                         listd.append(dic)
                    dicn=sorted(listd,key=operator.itemgetter("num"))


            试验4
                检验读取顺序是否正确,能否正确执行
                    for i in range(0,line-1):
                    n=0
                    for content in dicn[i].items():
                        if n==0:
                            fname=content[0]
                            fdir=content[1]
                            print("fname",fname,"fdir",fdir)
                            # 调用脚本程序进行执行
                            discover = unittest.defaultTestLoader.discover(fdir, pattern=fname)
                            # # 定义一个运行对象
                            runner = unittest.TextTestRunner()
                            runner.run(discover)
                        n=n+1
            试验5
                加入对状态的判断
                    解决问题1
                        把状态内容也要追加到字典列表中
                            dic["state"]=row[2]
                    解决问题2
                        在确定执行前,把状态要取出来
                        从字典列表中取出
                    代码
                        if n==2:
                            state=content[1]
                            # print("state",state)
                            if state=="Yes":
                                # 调用脚本程序进行执行
                                 print("最终运行的程序",fname)
                                discover = unittest.defaultTestLoader.discover(fdir, pattern=fname)
                                 # # 定义一个运行对象
                                 runner = unittest.TextTestRunner()
                                runner.run(discover)
                列表字典
                    [{"testa":"d:\\sdfs","num":3,"state":"Yes"},{"testa":"d:\\sdfs","num":1,"state":"Yes"},{"testa":"d:\\sdfs","num":2,"state":"Yes"}]

# V5.0版本  把所有配置文件中的内容全部进行读取

#***********************************V5.0驱动脚本程序*******************************************************
import unittest
import csv
import operator
if __name__ == '__main__':
    # 打开对应的配置文件进行读取
    # 以只读方式打卡
    file=open("D:\python\interfacefram\config\config4.csv","r")
    table=csv.reader(file)
    dic={}
    listd=[]
    # line=len(open("D:\python\interfacefram\config\config4.csv").readlines())
    line=0
    print(line)
    for row in table:
        print(row[0])
        if line>0:
        # 把文件中读取的数据放入字典
            dic={}
            dic[row[1]]=row[0]
            dic["num"]=int(row[3])
        #把脚本运行状态加入字典数据
            dic["state"]=row[2]
            print("dic",dic)
        line=line+1
        if dic!={}:
            listd.append(dic)
    # print(listd)
    print("n行数=",line)
    dicn=sorted(listd,key=operator.itemgetter("num"))
    print("dicn",dicn)

    for i in range(0,line-1):
        n=0
        for content in dicn[i].items():
            if n==0:
                print("content",content)
                fname=content[0]
                fdir=content[1]
                print("fname",fname,"fdir",fdir)
            if n==2:
                print("content2", content)
                state=content[1]
                # print("state",state)
                if state=="Yes":
                    # 调用脚本程序进行执行
                    print("最终运行的程序",fname)
                    discover = unittest.defaultTestLoader.discover(fdir, pattern=fname)
                    # # 定义一个运行对象
                    runner = unittest.TextTestRunner()
                    runner.run(discover)
            n=n+1

5、接口测试的总结

5.1 自主框架总体框图设计

5.2 接口测试的得与失

1、从独立接口测试脚本->接口联调测试脚本->接口测试框架都是独立研发的,不仅该项目可以用,也可以移植复用到其他项目中。

2、测试框架的技术不仅可以用于接口测试,其他以python+unittest+自动化测试的项目都可以继续沿用,具有较强的通用性。

3、一定程度上降低了由于界面或需求不断变更而造成的测试脚本修改或返工。

4、接口测试开展的有些晚,建议今后的接口测试最好安排在接口代码完成后就可以开始。

5、接口测试的相关设计文档还不是很完备,建议进行完善,避免测试的误解和返工。

6、接口测试的联调设计需要产品和开发的配合,确保设计的联调流程和实际应用相一致。

5.3 接口测试工作流程总结

S1:解读接口设计,形成接口测试文档。

S2:使用postman工具快速学习接口并进行首轮接口冒烟测试。

S3:独立接口测试脚本的设计及研发。

S4:接口联调脚本的设计及研发。

S5:测试框架的设计及研发。

S6:接口测试工作的改进及优化

愿每个测试都能成为测试开发,提高职业技能,成为前1%的存在,为社会创造更大的价值,为公司节约更多的成本,为自己和家庭谋求更高的收入,所有人不受职业年龄限制,越老越吃香,直至财富自由;愿测试技术越来越进步,软件质量进一步得到提高,效率提高。愿祖国更加美好,人民更加幸福。多喜乐,常安宁。

​​​​​​​拨云见日终有时,学无止境勤可达。

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

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

相关文章

【CT】LeetCode手撕—70. 爬楼梯

目录 题目1- 思路2- 实现⭐70. 爬楼梯——题解思路 3- ACM实现 题目 原题连接&#xff1a;70. 爬楼梯 1- 思路 思路 爬楼梯 ——> 动规五部曲 2- 实现 ⭐70. 爬楼梯——题解思路 class Solution {public int climbStairs(int n) {if(n<1){return 1;}// 1. 定义 dp 数…

html5——CSS基础选择器

目录 标签选择器 类选择器 id选择器 三种选择器优先级 标签指定式选择器 包含选择器 群组选择器 通配符选择器 Emmet语法&#xff08;扩展补充&#xff09; 标签选择器 HTML标签作为标签选择器的名称&#xff1a; <h1>…<h6>、<p>、<img/> 语…

数据平滑处理(部分)

一、 移动平均&#xff08;Moving Average&#xff09; 是一种最简单的数据平滑方法&#xff0c;用于平滑时间序列数据。它通过计算一定窗口内数据点的平均值来减少噪音&#xff0c;同时保留数据的趋势。移动平均包括简单移动平均&#xff08;SMA&#xff09;或指数加权移动平均…

初始网络知识

前言&#x1f440;~ 上一章我们介绍了使用java代码操作文件&#xff0c;今天我们来聊聊网络的一些基础知识点&#xff0c;以便后续更深入的了解网络 网络 局域网&#xff08;LAN&#xff09; 广域网&#xff08;WAN&#xff09; 路由器 交换机 网络通信基础 IP地址 端…

可观察性优势:掌握当代编程技术

反馈循环是我们开发人员工作的关键。它们为我们提供信息&#xff0c;并让我们从用户过去和现在的行为中学习。这意味着我们可以根据过去的反应进行主动开发。 TestComplete 是一款自动化UI测试工具&#xff0c;这款工具目前在全球范围内被广泛应用于进行桌面、移动和Web应用的…

“闭门造车”之多模态思路浅谈:自回归学习与生成

©PaperWeekly 原创 作者 | 苏剑林 单位 | 科学空间 研究方向 | NLP、神经网络 这篇文章我们继续来闭门造车&#xff0c;分享一下笔者最近对多模态学习的一些新理解。 在前文《“闭门造车”之多模态思路浅谈&#xff1a;无损》中&#xff0c;我们强调了无损输入对于理想的…

压缩文件的解析方式

我们常用的压缩文件有两种&#xff1a;后缀为.zip或者.rar&#xff0c;接下来将介绍解析两种压缩文件的代码。需要用到三个jar包&#xff1a;commons-io-2.16.1.jar、junrar-7.5.5.jar、slf4j-api-2.0.13.jar&#xff0c;可以在官网下载&#xff0c;也可以发私信。 这段代码是一…

2.GAP:通用访问协议

GAP的简单理解 GAP这个名字&#xff0c;直接翻译过来不好理解。 简单点可以理解为&#xff1a; 这是蓝牙设备在互联之前&#xff0c;过程中&#xff0c;第一个用于交流的协议。在代码上&#xff0c;会给这个协议实现&#xff0c;连接参数的设置&#xff0c;连接事件的实现&am…

【算法】二叉树-迭代法实现前后中序遍历

递归的实现就是:每一次递归调用都会把函数的局部变量&#xff0c;参数值和返回地址等压入调用栈中&#xff0c;然后递归返回的时候&#xff0c;从栈顶弹出上一次递归的各项参数&#xff0c;这就是递归为什么可以返回上一层位置的原因 可以用栈实现二叉树的前中后序遍历 1. 前序…

【数学趣】拉窗帘模型之求面积引发的6个解法

抖音上推了一个趣题 题 求橙色部分的面积 蓝色部分是2个正方形。大的正方形边长为6。&#xff08;小的正方形一半被一个黄色三角形遮住了一半&#xff09; 答案 18 解法1&#xff1a;拉窗帘 先写一个代号&#xff0c;方便证明&#xff0c;H G 代表正方形。&#xff08;G…

AV1 编码标准中帧内预测技术详细说明

AV1 编码标准帧内预测 AV1&#xff08;AOMedia Video 1&#xff09;是一种开源的视频编码格式&#xff0c;旨在提供比现有标准更高的压缩效率和更好的视频质量。在帧内预测方面&#xff0c;AV1相较于其前身VP9和其他编解码标准&#xff0c;如H.264/AVC和H.265/HEVC&#xff0c;…

暑假第一次作业

第一步&#xff1a;给R1,R2,R3,R4配IP [R1-GigabitEthernet0/0/0]ip address 192.168.1.1 24 [R1-Serial4/0/0]ip address 15.0.0.1 24 [R2-GigabitEthernet0/0/0]ip address 192.168.2.1 24 [R2-Serial4/0/0]ip address 25.0.0.1 24 [R3-GigabitEthernet0/0/0]ip address 192.…

【Mutilism用74ls192和与非门设计3进制24进制加法计数器2荔枝】2022-5-10

缘由【数电 数字逻辑】如何用74ls192和与非门设计任意进制加法计数器&#xff1f;-嵌入式-CSDN问答

Qt学生管理系统(付源码)

Qt学生管理系统 一、前言1.1 项目介绍1.2 项目目标 2、需求说明2.1 功能性说明2.2 非功能性说明 三、UX设计3.1 登录界面3.2 学生数据展示3.3 信息插入和更新 三、架构说明3.1 客户端结构如下3.2 数据流程图3.2.1 数据管理3.2.2 管理员登录 四、 设计说明3.1 数据库设计3.2 结构…

基于Python+Flask+MySQL的新冠疫情可视化系统

基于PythonFlaskMySQL的新冠疫情可视化系统 FlaskMySQL 基于PythonFlaskMySQL的新冠疫情可视化系统 项目主要依赖前端&#xff1a;layui&#xff0c;Echart&#xff0c;后端主要是Flask&#xff0c;系统的主要支持登录注册&#xff0c;Ecahrt构建可视化图&#xff0c;可更换主…

Qt 统计图编程

学习目标&#xff1a;Qt 折线图&#xff0c;柱形图和扇形统计图编程 学习基础 Qt QChart 曲线图表操作-CSDN博客 学习内容 Qt中绘制三种常见的图表非常方便, 主要步骤如下: 1. 折线图: - 使用QLineSeries定义折线数据,添加多个坐标点 - 使用QValueAxis创建X轴和Y轴 - 将…

数据结构——查找算法

文章目录 1. 查找算法 2. 顺序查找 2. 二分查找 1. 查找算法 查找算法是用于在数据集中定位特定元素的位置的算法。查找是计算机科学中一项基本操作&#xff0c;几乎在所有应用程序中都需要使用。例如&#xff0c;数据库查询、信息检索、字典查找等都涉及到查找操作。查找算…

【Mutilism数字电路实现32进制5线32译码器】2022-5-7

缘由3-8译码器到74HC138-编程语言-CSDN问答 2片16004非门2个组成8进制和4进制实现。 按138逻辑表把E3也接入置零&#xff0c;同时把E1也接入反向使得切换时138保持高电平输出&#xff0c;就看不到转换时第一个出现短暂低电平&#xff0c;是最完美的解决方案&#xff0c;二级反向…

分布式I/O从站的认知

为什么需要分布式I/O从站&#xff1f; 当PLC与控制机构距离过远时&#xff0c;远距离会带来信号干扰&#xff0c;分布式I/O从站只需要一个网络线缆连接。 ET200分布式I/O从站家族 体积紧凑、功能强大。 ET200SP ET200M ET200S ET200iSP ET200 AL ET200pro ET200 eco PN 通讯协议…

yarn底层原理详解:(第33天)

系列文章目录 一、yarn总体架构 二、yarn核心组件及功能 三、yarn资源分配与调度 四、yarn提交和执行流程 五、yarn调度算法 六、yarn安全性与容错性 文章目录 系列文章目录前言一、总体架构二、核心组件及功能1. ResourceManager&#xff08;RM&#xff09;2. NodeManager&am…