一、算法相关:
(1)熟悉常见的排序算法:冒泡排序、插入排序、选择排序 、快排
二、计算机网络相关
(1)http协议:
http(超文本传输协议)是一个在器客户端和服务器端之间基于请求与响应模式的、无状态的、应用层的协议,常基于TCP的连接方式。
无状态的含义:无状态协议对于事务处理没有记忆能力。无状态协议解决办法: 通过Cookie 或者通过Session会话保存
常见的状态码的含义:
请求报文结构:
***请求报文的格式***
请求方法(POST/GET) URL 协议版本/r/n
Header1 vaule /r/n
Head1 vaule /r/n
回复报文结构:
(2)http1.0与http1.1以及http2.0的区别
- 在http1.0中,当建立连接后,客户端发送一个请求,服务器端返回一个信息后就关闭连接,当浏览器下次请求的时候又要建立连接,
- 在http1.1中,默认使用长连接,通过这种连接,浏览器可以建立一个连接之后,发送请求并得到返回信息,然后继续发送请求再次等到返回信息,也就是说客户端可以连续发送多个请求,而不用等待每一个响应的到来。长连接有一个保持时间
- HTTP2.0使用了多路复用的技术,做到同一个连接并发处理多个请求,而且并发请求的数量比HTTP1.1大了好几个数量级。
(3)http和https的区别
http是超文本传输协议,信息是明文传输,https则是具有安全性的SSL加密传输协议,
http的默认端口是80,https的默认端口是443,
http的连接是简单的,无状态,https是有SSL+HTTP协议构建的可进行加密传输、身份认证的网络协议,比http协议安全
(4)get和post的区别
(5)cookie机制和session机制的区别
Cookie是服务器在本地机器上存储的小段文本并随每一个请求发送至同一服务器。Cookies保存在客户端,主要内容包括:名字,值,过期时间,路径等等。
Session是在服务器端保存用户数据。服务器从请求中提取出Session ID,并和保存的所有Session
ID进行对比,找到这个用户的信息。
***cookies和session的区别***
cookies数据保存在客户端,session数据保存在服务器端;
cookies可以减轻服务器压力,但是不安全,容易进行cookies欺骗;
session较安全,但占用服务器资源
(6)输入一个URL,接下来会发生什么
查询DNS,获取域名对应的IP->得到目标IP以及端口号后,调用socket,请求一个TCP流套接字,客户端向服务端发送HTTP请求报文(三次握手)->服务端通过五层,解析请求报文,发送http响应报文->关闭连接(四次挥手)->客户端解析响应报文,并在浏览器显示
(7)tcp udp协议的区别,各自使用场景
a. tcp面向连接,udp是无连接的
b. tcp提供可靠的服务,udp尽最大努力交付
c. tcp是面向字节流的,tcp是把数据看成一连串的无结构的字节流,udp是面向报文的。Udp没有拥塞控制,适用于实时应用
d. 每条tcp连接只支持一对一,udp支持一对一,一对多,多对一,多对多
e. tcp首部开销20字节,udp只有8个字节
f. tcp建立起的是全双工的可靠信道,udp是不可靠的
(8)tcp的连接建立以及拆除过程
***三次握手:***
(1)在建立通道时,客户端会向服务端发送一个SYN同步信号,即请求报文
(2)服务端收到请求信号以后,会向客户端发送一个SYN信号和ACK信号,告诉客户端请求和你连接,并告诉客户端我已经收到你的请求
(3)当服务端的SYN信号和ACK信号杯客户端收到以后,此时通道建立
***四次挥手:***
a. 客户端A发送一个FIN包,用来关闭客户A到服务器B的数据传送
b. 服务器B收到这个FIN,它发回一个ACK,确认序号为收到的序号加1,和SYN一样,一个FIN将占用一个序号
c. 服务器B决定关闭与客户端A的连接,发送一个FIN给客户端A
d. 客户端A发回ACK报文确认,并将确认号设置为收到序号加1
为甚么要三次握手,两次握手可以吗?
两次握手可以,但是会造成极大的资源浪费!
因为客户端发送请求后进入等待状态,有时候由于网络阻塞的原因,服务端会收到两次请求,而客户端只有一次请求。极端情况下,客户端只有一次请求,而服务端收到N次响应
为什么要四次挥手?
因为客户端和服务端断开连接以后,由于连接内存在数据传输,为了保证双方合约的完整执行,必须分四次断开
(9)tcp保证可靠的四项措施
a. 确认和重传机制:建立连接时三次握手同步双方的序列号确认号、窗口大小等信息,传输过程中,如果检验失败、丢包、延时则重传
b. 数据排序
c. 流量控制:维持一个滑动窗口来确保不会发生发送太快来不及接收的问题
d. 拥塞控制:慢启动,拥塞避免,快速重传,快速恢复
(10)DNS如何解析出IP地址
a. 浏览器先检查自身缓存有没有解析过这个域名对应的ip,如果有解析结束
b. 浏览器检查系统缓存中有没有对应的解析的结果,hosts文件,如果有解析结束
c. 请求本地域名服务器(LDNS)来解析这个域名,如果命中,则解析结束
d. 请求根域名服务器(Root server),根域名服务器返回给LDNS一个所查询域的name server的地址,这个name server就是网站注册的域名服务器
e. name server 根据ip域名映射表找到目标ip,返回给LDNS
f. LDNS缓存这个域名对应的ip
g. LDNS将解析的结果返回给用户,用户缓存到本地的缓存中,解析结束
(11)TCP/IP四层网络架构
数据链路层:负责建立和管理节点间的链路,通过各种控制协议,将有差错的物理信道编程无差错的,能可靠传输数据帧的数据链路
网络层:通过路由选择算法,为报文或分组通过通信子网选择最适当的路径
传输层:向用户提供可靠的端到端的差错和流量控制,保证报文的正确传输
应用层:直接向用户提供服务
三、python语言
(1)python的垃圾回收机制
> python采用的是引用计数机制为主,标记-清除和分代收集两种机制为辅的策略。
(2)__new__和__init__的区别
__
new__是用来创造一个类的实例的(constructor),而__init__是用来初始化一个实例的(initializer)。__new__所接收的第一个参数是cls,而__init__所接收的第一个参数是self。__new__函数首先被调用,构造了一个newStyleClass的实例,接着__init__函数在__new__函数返回一个实例的时候被调用,并且这个实例作为self参数被传入了__init__函数。
(3)python的多线程
多线程类似于同时执行多个不同程序,多线程运行有如下优点: 使用线程可以把占据长时间的程序中的任务放到后台去处理。
用户界面可以更加吸引人,这样比如用户点击了一个按钮去触发某些事件的处理,可以弹出一个进度条来显示处理的进度 程序的运行速度可能加快
在一些等待的任务实现上如用户输入、文件读写和网络收发数据等,线程就比较有用了。在这种情况下我们可以释放一些珍贵的资源如内存占用等等。
Python中使用线程有两种方式:函数或者用类来包装线程对象。
函数式:调用thread模块中的start_new_thread()函数来产生新线程。语法如下:
thread.start_new_thraed(function, args(, kwargs))
function----线程函数
args---传递给线程函数的参数
kwargs----可选参数
(4)python连接数据库的方式
首先我们需要安装mysql的库
pip install pyMySQL
安装完毕以后我们需要:
安装完毕后,数据库连接的具体步骤如下
(1)引入 API 模块。
(2)获取与数据库的连接。
(3)执行SQL语句和存储过程。
(4)关闭数据库连接。
(5)python的装饰器,(本文部分转载菜鸟教程,主要觉得附上代码可以理解的更懂,勿喷!)
python装饰器可以让其他函数在不需要做任何代码变动的前提下增加额外功能,装饰器的返回值也是一个函数对象。它经常用于有切面需求的场景,比如:插入日志、性能测试、事务处理、缓存、权限校验等场景
我们可以从以下四个方面来理解装饰器:
(1)一切皆对象
def hi(name="yasoob"):
return "hi " + name
print(hi())
# output: 'hi yasoob'
# 我们甚至可以将一个函数赋值给一个变量,比如
greet = hi
# 我们这里没有在使用小括号,因为我们并不是在调用hi函数
# 而是在将它放在greet变量里头。我们尝试运行下这个
print(greet())
# output: 'hi yasoob'
# 如果我们删掉旧的hi函数,看看会发生什么!
del hi
print(hi())
#outputs: NameError
print(greet())
#outputs: 'hi yasoob'
(2)在函数中定义函数
def hi(name="yasoob"):
print("now you are inside the hi() function")
def greet():
return "now you are in the greet() function"
def welcome():
return "now you are in the welcome() function"
print(greet())
print(welcome())
print("now you are back in the hi() function")
hi()
#output:now you are inside the hi() function
# now you are in the greet() function
# now you are in the welcome() function
# now you are back in the hi() function
greet()
#outputs: NameError: name 'greet' is not defined
(3)从函数中返回函数
def hi(name="yasoob"):
def greet():
return "now you are in the greet() function"
def welcome():
return "now you are in the welcome() function"
if name == "yasoob":
return greet
else:
return welcome
a = hi()
print(a)
#outputs: <function greet at 0x7f2143c01500>
#上面清晰地展示了`a`现在指向到hi()函数中的greet()函数
#现在试试这个
print(a())
#outputs: now you are in the greet() function
(4)将函数作为参数传给另一个函数
def hi():
return "hi yasoob!"
def doSomethingBeforeHi(func):
print("I am doing some boring work before executing hi()")
print(func())
doSomethingBeforeHi(hi)
#outputs:I am doing some boring work before executing hi()
#outputs:hi yasoob!
(6)python GIL
(7)python深拷贝、浅拷贝、
首先深拷贝和浅拷贝都是对象的拷贝,都会生成一个看起来相同的对象,他们***
本质的区别是拷贝出来的对象的地址是否和原对象一样,也就是地址的复制还是值的复制的区别。*
**
浅拷贝时,拷贝出来的新对象的地址和原对象是不一样的,但是新对象里面的可变元素(如列表)的地址和原对象里的可变元素的地址是相同的
深拷贝是,拷贝出来的新对象的地址和原对象是不一样的,而且深拷贝和浅拷贝最根本的区别就在去深拷贝同时改变了对象里面可变元素的地址。
(8)is和==的区别
is比较的是两个对象的地址值,也就是说两个对象是否为同一个实例对象;而==比较的是对象的值是否相等,其调用了对象的__eq__()方法。
(9)有一个单向链表,链表中有可能出现环,如何判断链表是否有环?
方法一:
首先从头结点开始遍历,每遍历一个新的节点,就从头遍历之前遍历过得节点,如果新节点和之前的节点相同,则链表有环。
方法二:
首先创建一个空集合,每遍历一个节点,就把节点存放在集合中,并与集合中的节点进行对比,如果相同则链表有环
方法三:
创建两个指针p1和p2,可以让p1向前移动一个节点,p2移动两个节点,此时判断p1节点是否和p2节点相同,如果相同,则有环!如果不是,继续移动。
四、操作系统
(1)进程和线程的区别
1.引入线程的系统当中,线程作为调度和分配的基本单位,进程是资源拥有的基本单位 2.并发性 进程间可以并发,同一进程的多个线程间可以并发,提高了进程的并发度 3.拥有资源,线程不拥有自己的资源,但可以访问其隶属进程的资源 4.系统开销:线程切换仅需保存少量寄存器内容,不涉及存储器管理方面的操作,因此代价小于进程切换代价
(2)内存分配的几种方式
静态存储区:从全局存储区域分配:这时内存在程序编译阶段就已经分配好,该内存在程序运行的整个周期都有效,如:全局变量、static静态变量。
栈:栈(stack):存放程序临时创建的局部变量,不包括static声明的变量,static意味着在数据段中存放。除此之外,当函数被调用时,其参数也会被压到栈中,并在调用结束后,函数的返回值也会被放到栈中。栈由编译器自动释放。其操作方式类似于数据结构中的栈。栈内存分配运算内置于处理器的指令集中,一般使用寄存器来存取,效率很高,但是分配的内存容量有限。
堆:堆(heap):用于存放进程运行中被动态分配的内存段,大小不固定。当进程调用malloc或者new等函数时,新分配的内存就被动态添加到堆上(堆被扩张),当使用free或者delete等函数释放内存时,被释放的内存从堆中被删除。需要注意的是,它与数据结构中的堆是两回事,它的分配方式类似于链表。
(3)线程间的同步机制
1.互斥锁 ,类似于整型信号量,S=1,容易引起死锁 2.条件变量 进入临界区后,若所需资源正处于忙碌状态,则等待,并开锁
(4)进程间的通信方式
1.共享存储器系统,进程间共享某些存储区和数据结构 2.消息传递系统 以格式化的消息为单位进行传递 3.管道通信,管道是进程间的一个共享文件
(5)死锁产生的条件
互斥条件 请求和保持条件 不剥夺条件 环路等待条件
(6)进程间的同步机制
a.信号量机制:1.整型信号量 S表示资源数目 2.记录型信号量 S>0表示可用资源数目,S<0表示被阻塞的进程的数目 3.AND型信号量 同时获取多个资源,一次性全部分配,只要一个不满足,就不分配 4.信号量集 AND型信号量的扩充,同种资源可能一次需要多个
b.管程:代表共享资源的数据结构,以及由对该共享数据结构实施操作的一组过程所组成的资源管理程序,共同构成的一个操作系统的资源管理模块
(7)进程的几种状态:就绪态 阻塞态 执行态
四、linux相关
(1)查找某个进程的ID,进程的端口号
- 先根据进程名查看进程id
ps -ef | grep 进程名
2.通过进程id查看占用的端口
netstat -nap | grep 进程id
3.通过端口号查看占用的进程id
netstat -nap | grep 端口号
(2)查看log的命令
tail -f xx.out(动态显示log日志)
tail -100 xx.out(显示前100行日志信息)
五、数据库
(1)SQL中drop/truncate/delete的区别
a. delete是dml, 执行delete时每次从表中删除一行,删除操作会被记录在redo和undo表中以便进行回滚,需要手动commit才能生效,可通过rollback撤销操作
b. truncate是DDL,会隐式提交,不能通过rollback回滚,不会触发触发器,会删除表中所有记录
c. drop使DDL,会隐式提交,不能回滚,不会触发触发器,他会删除表结构以及所有数据,并将占用的空间全部释放
(2)当进行大量查询时,查询方式的优化:建立索引
(3)数据库事务的几个特性
a. 原子性:事务的原子性指的是bai,事务中包含的程序作为数据库的逻辑工作单位,它所做的对数据修改操作要么全部执行,要么完全不执行。这种特性称为原子性。
b. 一致性:事务的一致性指的是在一个事务执行之前和执行之后数据库都必须处于一致性状态。例如,当数据库处于一致性状态S1时,对数据库执行一个事务,在事务执行期间假定数据库的状态是不一致的,当事务执行结束时,数据库处在一致性状态S2。
c. 分离性:分离性指并发的事务是相互隔离的。即一个事务内部的操作及正在操作的数据必须封锁起来,不被其它企图进行修改的事务看到。
d. 持久性:持久性意味着当系统或介质发生故障时,确保已提交事务的更新不能丢失。
(4)索引数据结构
a. hash结构
b. 二叉搜索树
c. 红黑树
d. B树
e. B+树
六、测试相关
(1)设计测试用例的方法
a. 黑盒测试:等价类划分、边界值分析法、正交实验法、状态转移法、流程分析法、输入域测试法、输出域测试法、判定表分析法、因果图分析法、错误猜测法、异常分析法
b. 白盒测试: 静态测试,动态测试
(2)测试的相关流程
需求测试->概要设计测试->详细设计测试->单元测试->集成测试->系统测试->验收测试
(3)软件质量的六个特征
a. 功能特征:满足明确或者隐含的需求的那些功能
b. 可靠特征:在规定的一段时间和条件下,软件能够维持其性能水平的能力
c. 易用特征:使用软件所需要的努力
d. 效率特征:软件的性能水平与所使用的资源量的关系
e. 可维护特征:进行制定的修改所需的努力
f. 可移植特征:不同的设备,不同的操作系统
(4) 如何测试 微信朋友圈,微信发红包,测试电梯,如何测试一支笔