一 软件测试基础理论题

  • 常见的测试方法有哪些?
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
  •  你熟悉哪些设计模式?

 

 

 

 

 六 自动化篇

 

 

七 性能篇

 

 

八 工具篇

 

posted on 2020-01-20 11:38  腿短毛不多  阅读(742)  评论(0编辑  收藏  举报