• 一文总结软件测试工程师面试前必背的面试题(持续更新中)


    一 软件测试基础理论题

    • 常见的测试方法有哪些?
    1 从是否关心内部结构来看分为:白盒,黑盒,灰盒
        黑盒测试不考虑程序内部结构和逻辑结构,主要是用来测试系统的功能是否满足需求规格说明书。一般会有一个输入值,一个输入值,和期望值做比较。
        白盒测试主要应用在单元测试阶段,主要是对代码级的测试,针对程序内部逻辑结构,测试手段有:语句覆盖、判定覆盖、条件覆盖、路径覆盖、条件组合覆盖
        灰盒是一种综合测试法,它将黑盒与白盒结合在一起,是基于程序运行时的外部表现又结合内部逻辑结构来设计用例,执行程序并采集路径执行信息和外部用户接口结果的测试技术。
    2 从是否执行代码来看分为:静态测试和动态测试
       静态测试:指不运行被测程序本身,仅通过分析或检查源程序的语法、结构、过程、接口等来检查程序的正确性。
       动态测试:是指通过运行被测程序,检查运行结果与预期结果的差异,并分析运行效率、正确性和健壮性等性能指标。
    3 从开发过程级别来看分为:单元测试,集成测试,系统测试,验收测试。
       单元测试的粒度最小,一般由开发小组采用白盒方式来测试,主要测试单元是否符合“设计”。
       集成测试界于单元测试和系统测试之间,起到“桥梁作用”,一般由开发小组采用白盒加黑盒的方式来测试,既验证“设计”,又验证“需求”。
       系统测试的粒度最大,一般由独立测试小组采用黑盒方式来测试,主要测试系统是否符合“需求规格说明书”。系统测试中具体的类型类型有:功能测试,性能测试,接口测试,安全性测试,兼容性测试等
       验收测试与系统测试相似,主要区别是测试人员不同,验收测试由用户执行。
    View Code
    •  测试用例设计方法(可能会结合具体的题让你用方法设计测试用例)有哪些?
    等价类划分,边界值分析,判定表,正交实验法,错误推测,因果图,场景法等
    常见的设计测试用例题:给你一部电梯怎么设计测试用例,针对一支笔设计测试用例,对手机上的计算器设计测试用例,给你一个纸杯怎么怎么设计测试用例,针对美团支付尽可能多的设计测试用例
    View Code
    •  说一说web测试和app测试有哪些异同点?
    相同:
    web测试和app测试从流程上来说,没有区别。都需要经历测试计划方案,用例设计,测试执行,缺陷管理,测试报告等相关活动。从技术上来说,web测试和app测试其测试类型也基本相似,都需要进行功能测试、性能测试、安全性测试、GUI测试等测试类型。
    不同:
    他们的主要区别在于具体测试的细节和方法有区别,比如:性能测试,在web测试只需要测试响应时间这个要素,在app测试中还需要考虑流量测试和耗电量测试。
    兼容性测试:在WEB端是兼容浏览器,在App端兼容的是手机设备。而且相对应的兼容性测试工具也不相同,web因为是测试兼容浏览器,所以需要使用不同的浏览器进行兼容性测试(常见的是兼容IE,chrome,firefox,360,Edge,Safari,搜狗)如果是手机端,那么就需要兼容不同品牌,不同分辨率,不同android版本甚至不同操作系统的兼容。(常见的兼容方式是兼容市场占用率前N位的手机即可),有时候也可以使用到兼容性测试工具,但WEB兼容性工具多用IETester等工具,而app兼容性测试会使用Testin这样的商业工具也可以做测试。
    安装测试:web测试基本上没有客户端层面的安装测试,但是app测试是存在客户端层面的安装测试,那么就具备相关的测试点。
    还有,app测试基于手机设备,还有一些手机设备的专项测试。如交叉事件测试,操作类型测试,网络测试(弱网测试,网络切换)
    交叉事件测试:就是在操作某个软件的时候,来电话、来短信,电量不足提示等外部事件。
    操作类型测试:如横屏测试,手势测试
    网络测试:包含弱网和网络切换测试。需要测试弱网所造成的用户体验,重点要考虑回退和刷新是否会造成二次提交。弱网络的模拟,据说可以用360wifi实现设置。
    从系统架构的层面,web测试只要更新了服务器端,客户端就会同步会更新。而且客户端是可以保证每一个用户的客户端完全一致的。但是APP端是不能够保证完全一致的,除非用户更新客户端。如果是app下修改了服务器端,意味着客户端用户所使用的核心版本都需要进行回归测试一遍。
    还有升级测试:升级测试的提醒机制,升级取消是否会影响原有功能的使用,升级后用户数据是否被清除了。
    View Code
    •  接口怎么测试?
    接口测试点:
    1 业务功能是否实现,包括正常、异常场景是否实现。
       正常包括单个参数,组合参数,必填参数,非必填参数都在接口文档范围内输入
       异常场景包括少传,多传,不传接口文档里规定的参数,重复提交、并发提交、多机环境、大数据量测试
    2 检查接口返回的数据是否与预期结果一致。
        如新增成功时业务code是否返回00,新增用户已存在时code是否返回02,传参类型错误时code是否返回03,与接口文档对比
        响应body:是否与文档里给的结果和字段一致
        响应数据:是否与数据库数据匹配
    3 检查接口的容错性,假如传递参数值为空,长度不一致,错误数据,不同数据类型等时是否可以处理。
    4 接口参数的边界值。例如,传递的参数足够大,足够小或为负数时,接口是否可以正常处理。
    5 接口的性能,http请求接口大多与后端执行的SQL语句性能、算法等比较相关。
    6 接口的安全性,外部调用的接口尤为重要。   
       1 敏感信息是否加密
       2 必要参数是否后端也进行验证(绕过前端很容易,需要后端同样进行控制)
       3 接口是否防恶意请求(SQL注入)
    7 接口的兼容性,比如接口进行了调整,但是前端没有进行变更,这时候需要验证新的接口是否满足旧的调用方式
    View Code
    •  什么是C/S和B/S架构?分别说一说?
    C/S架构软件:
    是Client/Server的简称,指客户/服务器模式
    这种模式只要客户机上安装一个浏览器,如Internet Explorer,服务器安装Oracle、MYSQL等数据库。浏览器通过Web Server 同数据库进行数据交互。
    
    B/S型模式:
    是Browser/Server的简称,指浏览器/服务器模式。
    它是软件系统体系结构,通过它可以充分利用两端硬件环境的优势,将任务合理分配到Client端和Server端来实现,降低了系统的通讯开销。目前大多数应用软件系统都是Client/Server形式的两层结构。
    View Code

     二 数据库题

    •  简述内连接和外连接的区别?

                           

    外连接分为左外连(left join)和右外连(right join)
    左连接:取左表的全部,右表按条件符合的显示,不符合的则显示null
    右连接:取右表的全部,左表按条件符合的显示,不符合的则显示null
    SELECT *FROM t_reserve a LEFT JOIN t_advisor b ON a.advisor_id=b.id;
    SELECT *FROM t_reserve a RIGHT JOIN t_advisor b ON a.advisor_id=b.id;
    
    内连接关键字为inner join,返回两张表都满足条件的部分
    View Code
    • 多表查询/分组查询题
    现有三张表,分别为:
    学生表(学生id,姓名,性别,分数) )student(s_id, name, sex, score)
    班级表(班级id,班级名称) class(c_id, c_name)
    学生班级表(班级id,学生id) student_class(s_id,c_id)
    
    1.查询一班得分在80分以上或者等于60,61,62的学生。
    SELECT
        s.s_id,
        s. NAME,
        s.score,
        sc.c_id,
        c.c_name
    FROM
        student s
    LEFT JOIN student_class sc ON s.s_id = sc.s_id
    LEFT JOIN class c ON sc.c_id = c.c_id
    WHERE
        (
            s.score > 80
            OR s.score IN (60, 61, 62)
        )
    AND c.c_name = '一班';
    
    2.査询所有班级的名称,和所有班中女生人数和女生的平均分。
    SELECT
        sc.s_id,
        c.c_name,
        COUNT(s.sex),
        AVG(s.score)
    FROM
        student_class sc
    LEFT JOIN class c ON sc.c_id = c.c_id
    LEFT JOIN student s ON sc.s_id = s.s_id
    WHERE
        s.sex = ''
    GROUP BY
        c.c_name
    ORDER BY
        c.c_id ASC;
    View Code
    • 什么是数据库事务?

    数据库事务( transaction)是访问并可能操作各种数据项的一个数据库操作序列,这些操作要么全部执行,要么全部不执行,是一个不可分割的工作单位。事务由事务开始与事务结束之间执行的全部数据库操作组成。
    View Code

     三 网络协议篇

    •  get和post的区别?
    get和post是http协议最常用的两种请求方式:
    
    1.get请求是从服务器获取资源,post请求是向服务器提交数据
    2.get请求参数放在url里,通过?拼接;post请求参数放在body里,通过表单提交
                   ①url很容易被截获,所以get比post更不安全
                   ②因为get放在url里,url存在长度限制一般限制最长256个字符,而post放在body则不存在长度限制
    3.get请求通过url可以放在浏览器中,所以可以被缓存和收藏为书签,并且能在浏览器历史中记录下来; 而post则不行
    4.get方法发送同一个请求无论执行多少次效果都相同,不会对服务器端数据产生不良影响,所以get请求是幂等的,post请求是非幂等的
    View Code
    • 在浏览器中输入一个url后发生了什么?
    1 在浏览器中输入一个url地址
    2 浏览器通过DNS域名解析器找到域名对应的ip和端口
    3 确认ip和端口后,向该ip对应的服务器的端口发送TCP请求(三次握手),建立连接
    4 浏览器给web服务器发送一个http请求
    5 服务器处理请求
    6 服务器发送回一个HTML响应
    7 关闭TCP连接(四次挥手)
    8 浏览器开始显示HTML
    9 浏览器发送获取嵌入在HTML中的对象
    10 构建渲染树
    11 浏览器布局渲染
    View Code
    •  http和https有什么区别?
    HTTP协议是超文本传输协议,被用于在Web浏览器和网站服务器之间传递信息。HTTP协议以明文方式发送内容,不提供任何方式的数据加密,如果攻击者截取了Web浏览器和网站服务器之间的传输报文,就可以直接读懂其中的信息,因此HTTP协议不适合传输一些敏感信息,比如信用卡号、密码等。
    为了解决HTTP协议的这一缺陷,需要使用另一种协议:安全套接字层超文本传输协议HTTPS。为了数据传输的安全,HTTPS在HTTP的基础上加入了SSL协议,SSL依靠证书来验证服务器的身份,并为浏览器和服务器之间的通信加密。
        HTTPS和HTTP的区别主要为以下四点:
        1.https协议需要到ca申请证书,一般免费证书很少,需要交费。
        2.http是超文本传输协议,信息是明文传输,https 则是具有安全性的ssl加密传输协议。
        3.http和https使用的是完全不同的连接方式,用的端口也不一样,前者默认是80,后者默认是443。
        4.http的连接很简单,是无状态的;HTTPS协议是由SSL+HTTP协议构建的可进行加密传输、身份认证的网络,比http协议安全。
    
    思考:什么是http的无状态?
    无状态是指协议对于事务处理没有记忆能力,服务器不知道客户端是什么状态。即我们给服务器发送HTTP请求之后,服务器根据请求,会给我们发送数据过来,但是,发送完,不会记录任何信息。所以随着人们需求的增加,客户端使用cookie,服务端使用session来记录连接的状态
    View Code
    • 说一说对TCP协议的三次握手和四次挥手 的理解?

     

    (注:seq代表序号,ack代表确认号)
    
    第一次握手:当客户端需要去建立连接时,客户端就会发送SYN包(seq=x)到服务器,然后客户端进入SYN_SEND的状态,代表已经发SYN包过去,并且在等待服务器确认。此时ACK=0,SYN=1.,这时候由于才第一次握手,所以没有ACK标志
    第二次握手:服务器收到SYN包,就会进行确认,由上面的标志位介绍我们可以知道SYN是表示同步序号,这时候会使得确认号=序号+1,即ack就会等于x+1,然后服务器也会像客户端发送一个SYN包(seq=y),这时候也就是服务器会发送SYN+ACK包,来表示服务器确认到了客户端的一次握手并且二次握手建立,此时服务器进入SYN_RECV状态。此时SYN=1,ACK=1,这时候由于是第二次握手,所以就会有一个服务器给客户端的确认标志。
    第三次握手:客户端收到服务器的SYN+ACK包,然后就会像服务器发送确认包ACK(ack=k+1)和SYN(seq=x+1),等到这个包发送完毕之后客户端和服务器就会进入ESTABLISHED状态,完成三次握手,而后就可以在服务端和客户端之间传输数据。此时SYN标志位已经不需要,因为当我们发送ACK标志位的时候代表三次握手成功,已经建立完连接了,接下来可以传送数据过去了。
    既然都有SYN包那为什么还要ACK来确认呢?SYN是同步序号,当 SYN=1 而ACK=0 时,表明这是一个连接请求报文。对方若同意建立连接,则应在响应报文中使 SYN=1 和 ACK=1。因此SYN置1就表示这是一个连接请求或连接接受报文。而ACK状态是用来确认是否同意连接。也就是传了 SYN,证明发送方到接收方的通道没有问题,但是接收方到发送方的通道还需要 ACK 信号来进行验证。
    
    当TCP三次握手完之后,就代表连接已经建立完成
    View Code

    当在传送完数据之后,客户端会和服务端之间有四次握手
    
    第一次握手:客户端发送一个FIN和序号过去(seq=u),用来表示客户端和服务端之间有关闭的请求,同时关闭客户端到服务端的数据传送,客户端就进入FIN_WAIT_1的状态。
    第二次握手:服务端收到FIN=1的标志位时,就会发送一个ACK标志位代表确认,然后确认序号就变成了收到的序号加1,即ack=u+1(FIN和SYN在这点上相同,但是作用不一样)这时候服务端进入CLOSE_WAIT状态,这是一个半关闭状态。只能服务端给客户端发送数据而客户端不能给服务端发送数据。
    第三次握手:这次握手还是由服务端发起,这是服务端在传完最后的数据(没有就不传)就会发送一个FIN=1和ACK=1,且序号seq会改变(没有传数据则不变),而ack不变。这时候服务端就会进入LAST_ACK状态,表示最后确认一次。
    第四次握手:客户端在接收到FIN之后,就会进入TIME_WAIT状态,接着就发送一个ACK和seq=u+1,ack=w+1给服务端,这时候服务端就会进入CLOSED状态。而客户端进入TIME_WAIT状态的时候必须要等待2MSL的时间才会关闭
    View Code
    •  http常见的状态码分别代表什么?
    1xx:信息提示
    2xx:成功
        200:成功。请求的所有数据都在响应体中
    3xx:重定向
        301:(Moved Permanently)当客户端触发的动作引起了资源URI的变化时发送此响应代码。另外,当客户端向一个资源的旧URI发送请求时,也发送此响应代码。
    4xx:客户端错误
        400:(Bad Request)客户端方面的问题。实体主题中的文档(若存在的话)是一个错误消息。希望客户端能够理解此错误消息,并改正问题。
        401:(Unauthorized未授权)需要输入用户名和密码
        404:(Not Found未找到)服务器无法找到所请求URL对应的资源
    5xx:服务器错误
        502:(Bad Gateway)指错误网关,无效网关;在互联网中表示一种网络错误
    View Code
    •  说一说对正向代理和反向代理的理解?

     

    如图所示,正向代理,"它代理的是客户端",是一个位于客户端和原始服务器(Origin Server)之间的服务器,为了从原始服务器取得内容,客户端向代理发送一个请求并指定目标(原始服务器)。
    然后代理向原始服务器转交请求并将获得的内容返回给客户端。客户端必须要进行一些特别的设置才能使用正向代理。
    正向代理的用途:
    
    访问原来无法访问的资源,如 Google。
    可以做缓存,加速访问资源。
    对客户端访问授权,上网进行认证。
    代理可以记录用户访问记录(上网行为管理),对外隐藏用户信息。
    View Code

    通过上述的图解大家就可以看清楚了,多个客户端给服务器发送的请求,Nginx 服务器接收到之后,按照一定的规则分发给了后端的业务处理服务器进行处理了。
    此时请求的来源也就是客户端是明确的,但是请求具体由哪台服务器处理的并不明确了,Nginx 扮演的就是一个反向代理角色。
    客户端是无感知代理的存在的,反向代理对外都是透明的,访问者并不知道自己访问的是一个代理。因为客户端不需要任何配置就可以访问。
    反向代理,"它代理的是服务端",主要用于服务器集群分布式部署的情况下,反向代理隐藏了服务器的信息。
    反向代理的作用:
    
    保证内网的安全,通常将反向代理作为公网访问地址,Web 服务器是内网。
    负载均衡,通过反向代理服务器来优化网站的负载。
    View Code

    四 linux相关

    •  Linux怎么查看日志?
    linux查看日志文件内容命令tail、cat、tac、head、echo
    
    tail -f test.log
    实时查看日志,你会看到屏幕不断有内容被打印出来. 这时候中断第一个进程Ctrl+C,
    
    
    linux 如何显示一个文件的某几行(中间几行)
    
    从第3000行开始,显示1000行。即显示3000~3999行
    cat filename | tail -n +3000 | head -n 1000
    
    显示1000行到3000行
    cat filename| head -n 3000 | tail -n +1000
    
    *注意两种方法的顺序
    分解:
    tail -n 1000:显示最后1000行
    tail -n +1000:从1000行开始显示,显示1000行以后的
    head -n 1000:显示前面1000行
    
    
    用sed命令
    sed -n '5,10p' filename 这样你就可以只查看文件的第5行到第10行。
    
    例:cat mylog.log | tail -n 1000 #输出mylog.log 文件最后一千行
    
    
    tac (反向列示)
    tac 是将 cat 反写过来,所以他的功能就跟 cat 相反, cat 是由第一行到最后一行连续显示在萤幕上,
    而 tac 则是由最后一行到第一行反向在萤幕上显示出来!
    
    
    
    在Linux中echo命令用来在标准输出上显示一段字符,比如:
    echo "the echo command test!"
    
    这个就会输出“the echo command test!”这一行文字!
    View Code
    •  linu常用命令又哪些?
    pwd 显示当前路径
    
    cd 切换目录
    cd ../ 切换到上级目录
    cd /   切换到根目录
    
    mkdir 创建目录
    
    rmdir -rf 删除目录
    
    ls 查看目录或文件信息
    ll 列出目录或文件的详细信息。比如权限/修改时间等
    
    vi 文本编辑器
    键入i 进入编辑状态
    退出编辑按ESC键
    不保存退出: :q!
    保存退出:   :wq
    输入/,进入搜索
    输入:set nu,显示每一行的行数
    按键盘G,可以直接定位到最末尾
    
    cp 复制
    cp a.txt b.txt将a文件复制,且另命名为b文件
    
    mv移动
    mv a.txt ../    将a文件移动到上级目录(将一个文件移动到另一个目录没有重命名)
    mv a.txt  ../b.txt   将a文件移动到上一级并改名为b文件(将一个文件移动到另一个目录并重命名)
    
    find查找文件
    find  . -name *.log    在当前目录查找以.log结尾的文件
    find  / -name  log   在根目录查找log命名的目录
    
    grep过滤
    grep band file  在file文件中找寻band字符串
    
    cat显示文本文件内容
    cat a.txt
    
    head查看前几行
    head -n 5 a.txt 查看a文件中的前5行内容
    
    tail从指定点开始将我呢见写到标准输出
    tail -n 5  文件名  查看后几行
    tail -f error.log  不断刷新,看到最新内容
    
    ps查看进程
    ps -ef 显示所有运行的进程
    
    netstat查看网络状况
    netstat -apn 查看所有端口
    
    rz上传
    sz下载
    
    .tar (注:tar是打包,不是压缩!)
    解包:tar xvf FileName.tar
    打包:tar cvf FileName.tar DirName
    
    .zip
    解压:unzip FileName.zip
    压缩:zip FileName.zip DirName
    
    关闭防火墙
    开启:service iptables start
    关闭:service iptables stop
    View Code
    •  Linux如何查看ip?
    环境centos7
    1 打开终端
    2 在终端里输入命令ifconfig -a
    3 如何找不到这个命令可以试试ip addr
    View Code

    五 编程题(python)

    •  说说list ,tuple,dict之间的区别?
    1 list,dict是可变类型;tuple是不可变类型
    2 list用{}来申明,tuple用()来申明,dict用key,value键值对来表示,且key必须是不可变类型
    3 list和tuple是有序的,可以用下标来访问,dict只能用key来访问
    View Code
    • 迭代器和生成器有什么区别?
    迭代器:
    迭代是Python最强大的功能之一,是访问集合元素的一种方式。
    迭代器是一个可以记住遍历的位置的对象。
    迭代器对象从集合的第一个元素开始访问,直到所有的元素被访问完结束。迭代器只能往前不会后退。
    迭代器有两个基本的方法:iter() 和 next()
    创建一个迭代器:
    把一个类作为一个迭代器使用需要在类中实现两个方法 __iter__() 与 __next__() 。
    如果你已经了解的面向对象编程,就知道类都有一个构造函数,Python 的构造函数为 __init__(), 它会在对象初始化的时候执行。
    __iter__() 方法返回一个特殊的迭代器对象, 这个迭代器对象实现了 __next__() 方法并通过 StopIteration 异常标识迭代的完成。
    __next__() 方法(Python 2 里是 next())会返回下一个迭代器对象。
    
    生成器:
    在 Python 中,使用了 yield 的函数被称为生成器(generator)。
    跟普通函数不同的是,生成器是一个返回迭代器的函数,只能用于迭代操作,更简单点理解生成器就是一个迭代器。
    在调用生成器运行的过程中,每次遇到 yield 时函数会暂停并保存当前所有的运行信息,返回 yield 的值, 并在下一次执行 next() 方法时从当前位置继续运行。
    调用一个生成器函数,返回的是一个迭代器对象。
    View Code
    • =和==和is有什么不同?
    =:是赋值
    ==:是判断是否相等,比较的是对象的值,返回True或False
    is:比较的是对象的内存地址,即is比较的是两个对象的id值是否相同。is 运算符比 == 效率高,在变量和None进行比较时,应该使用 is
    View Code
    • 什么是装饰器,手写一个装饰器
    #装饰器的本质是两层函数,两层函数的本质是闭包,闭包的本质是函数对象加函数部分所需要使用的一个外部变量
    import time
    
    def timer(func):
        def func1():
            time1 = time.time()
            func()
            time2 =time.time()
            print("时间差:%s" %(time2-time1))
        return func1
    
    
    @timer
    def a():
        i = 1
        while i<=1000000:
            i+=1
    
    a()
    View Code
    •  简述一下三种方法的区别?
    1 实例方法,参数要有self,必须通过实例化的对象去调用。
    2 类方法,要加上@classmethod来声明,参数至少有一个,一般定义为cls,使用类变量,不能使用实例变量。通过类名或者实例对象调用。
    3 静态方法,要加上@staticmethod来声明,可以没有参数,使用类变量,不能使用实例变量。通过类名或者实例对象调用。
    View Code
    • 说一说类的三大特性
    封装:根据职责将属性和方法封装到一个抽象的类中。
    继承:实现代码的重用,不需要重复编写代码。子类拥有父类所有的属性和方法。也可以重新定义父类方法。
    多态:不同的对象调用相同的代码,产生不同的效果,提高代码的灵活性。
    View Code
    •  深浅拷贝的区别? 
    浅拷贝copy.copy(),数据半共享(只是拷贝原来变量中的不可变数据类型,可变数据类型只是引用)
    >>> import copy
    >>>
    >>> a=[1,2,3,'x',['y','z']]
    >>> c=copy.copy(a)
    >>> a.append(4)
    >>> a[4].append(100)
    >>> print(a)
    [1, 2, 3, 'x', ['y', 'z', 100], 4]
    >>> print(c)
    [1, 2, 3, 'x', ['y', 'z', 100]]
    
    深拷贝copy.deepcopy(),数据完全不共享(复制其数据完完全全放独立的一个内存,形成一个新的对象,虽然与之前的值和内容一模一样,但是它们完完全全的两个对象,互不影响)
    >>> import copy
    >>>
    >>> a=[1,2,3,'x',['y','z']]
    >>> c=copy.deepcopy(a)
    >>> a.append(4)
    >>> a[4].append(100)
    >>> print(a)
    [1, 2, 3, 'x', ['y', 'z', 100], 4]
    >>> print(c)
    [1, 2, 3, 'x', ['y', 'z']]
    View Code
    •  写一个冒泡排序
    #冒泡的核心是两两比较,大的放最后
    for i in range(len(a)):
        for j in range(len(a)-1-i):   #里层循环每次循环剔除一个元素,即-i
            if a[j]>a[j+1]:
                a[j],a[j+1] = a[j+1],a[j]  #如果前一个元素大于后一个元素则交换两个元素
            #print("****",a)
    
    
    print(a)
    View Code
    • 写一个快排
    '''
    快排的核心思想如下:
    对于列表,选取一个轴值(一般选取第一个元素或者最后一个元素),把列表中小于该轴值的排在左边,大于该轴值的排在右边,这样,轴值在列表中的位置就确定了。
    由此衍生出了轴值的左子列表,以及右子列表,递归的对于左子列表以及右子列表使用上述的排序算法,直到子列表中只有一个元素。
    '''
    a=[5,4,3,2,1,7]
    
    def quick_sort(arr):
        if len(arr)<=1:
            return arr
    
        piovt = arr[0]
        left = [] #小于pivot的元素,放到这里
        right = [] #大于pivot的元素,放到这里
        for i in arr[1:]:
            if piovt>i:
                left.append(i)
            elif piovt<i:
                right.append(i)
        return quick_sort(left)+[piovt]+quick_sort(right)
    
    print(quick_sort(a))
    View Code
    •  二分法查找
    '''
    二分法查找:
    前提:必须是一个已经排好序的列表
    核心:不断的除以2
    a=[1,2,3,4,6,7,17,34]
    key =3
    min=0
    max=len(a)-1
    center=(min+max)/2
    每次找中间,用key跟中间元素比较,
    如果比中间元素大,那么更新min的值
    如果比中间元素小,那么更新max的值
    如果等于中间元素,则找到了
    '''
    
    def brainy_search(arr,key):
    
        min = 0
        max = len(arr)-1
        if key in arr:
            while True:
                center = int((min+max)/2)
                if key > arr[center]:
                    min = center +1
                elif key < arr[center]:
                    max = center -1
                elif key == arr[center]:
                    print("%s在列表中的位置是:%s" %(key,center))
                    return key
        else:
            print("%s不在列表中" %key)
    
    a=[1,2,3,4,6,7,17,34]
    print(brainy_search(a,2))
    View Code
    •  python有重载和重写吗?怎么实现的?
    重写是指子类重写父类的成员方法。子类可以改变父类方法所实现的功能, 但子类中重写的方法必须与父类中对应的方法具有相同的方法名。也就是说 要实现重写,就必须存在继承。
    示例:
    class Person():
        def print_info(self):
            print("*************")
    
    
    class ChinesePerson(Person):
        def print_info(self):  #子类重写父类的print_info方法
            print("________")
    
    p= ChinesePerson() #子类实例
    p.print_info()  #子类调用重写方法
    p1=Person()  #父类实例
    p1.print_info()  #父类调用重写方法
    
    
    重载方法的名称是相同的,但在方法的声明中一定要有彼此不相同的成
    份,以使编译器能够区分这些方法。重载的方法必须遵循下列原则:
    ➢方法的参数必须不同,包括参数的类型或个数,以此区分不同方法
    体;
    ➢方法的返回类型、修饰符可以相同,也可以不同。
    示例:
    def a(x):
        return x
     
    def a(x,y):
        return x+y
     
    print(a(1,2))
    print(a(1))
    运行结果:
    3
    Traceback (most recent call last):
      File "0609.py", line 8, in <module>
        print(a(1))
    TypeError: a() missing 1 required positional argument: 'y'
    
    
    总结:
    重写:把父类的方法覆盖掉,使用子类的同名方法。
    重载:多个方法名一样,但是他们的参数类型,还有参数个数不一样(java)。
    python不支持重载,因为python可以传可变参数,也没有参数类型的定义。
    View Code
    • 什么是单例,单例有什么用,业务场景是什么?
    #单例模式(Singleton Pattern)是一种常用的软件设计模式,单例的本质是一个类最多生成一个实例
    
    比如,某个服务器程序的配置信息存放在一个文件中,客户端通过一个 AppConfig 的类来读取配置文件的信息。
    如果在程序运行期间,有很多地方都需要使用配置文件的内容,也就是说,很多地方都需要创建 AppConfig 对象的实例,这就导致系统中存在多个 AppConfig 的实例对象,而这样会严重浪费内存资源,尤其是在配置文件内容很多的情况下。
    事实上,类似 AppConfig 这样的类,我们希望在程序运行期间只存在一个实例对象。所以单例设计模式一般用于有减少重复创建实例需求的场景
    
    在 Python 中,我们可以用多种方法来实现单例模式:
    
    1:使用模块使用
    2:使用 new
    3:使用装饰器(decorator)
    4:使用元类(metaclass)
    
    
    使用__new__示例:
    1 真正生成实例的方法
    2 在这个方法里,要判断是否存在_instance的类变量,如果已经存在了,直接返回
    
    class Singleton(object):
        def __new__(cls, *args, **kw):
            if not hasattr(cls, '_instance'):
                print(cls)
                #orig = super(Singleton, cls)
                cls._instance = object.__new__(cls, *args, **kw)
            return cls._instance
     
    s1=Singleton()#第一次生成实例,走if语句成立,调用__new__生成一个实例,后返回
    s2=Singleton()#第二次生成实例,if语句不成立不会再走下面的的语句,直接返回cls._instance(第一次生成的实例),以此来实现单例
    print(s1==s2)
    print(id(s1))
    print(id(s2))
    
    运行结果:
    <class '__main__.Singleton'>
    True
    1526180159560
    1526180159560
    View Code
    •  你熟悉哪些设计模式?

     六 自动化篇

    七 性能篇

    八 工具篇

  • 相关阅读:
    vue系列教程:插值
    docker load 镜像时出现:open /var/lib/docker/tmp/docker-import-500852078/repositories: no such file or dir
    Day 18: 记filebeat内存泄漏问题分析及调优
    Filebeat 启动关闭流程
    docker加速
    Docker镜像保存save、加载load(外网转移至内网)
    filebeat.yml(中文配置详解)
    kafka介绍
    基于统一开发平台的微服务架构转型升级之路 | 某国有大型银行案例
    转 -Filebeat + Redis 管理 LOG日志实践
  • 原文地址:https://www.cnblogs.com/wenm1128/p/12109862.html
Copyright © 2020-2023  润新知