面试题

1.有没有学过其他语言,和其他语言的区别?

a. 先说python的特点,语言简洁,开发效率高,类库齐全(数据分析,机器学习)
b. JavaScript/python/在学GO lang (自学)

问题: GO和python的区别
问题: 为什么要学习GO?

2.python2与python3的区别?

  • 默认编码方式不一样,python2中ASCII码,3中是utf-8,程序员不用担心乱码问题了。

  • True和False的改变,从全局变量,可以随意赋值,变为固定对象,不能重新赋值,True和false也成为关键字

  • nonlocal关键字,python2中想要在嵌套函数中声明一个变量为非局部变量是不可能的,python3中可以。

  • 输入输出语法不同

    # py2
    	print "Hello world"
    	raw_input("Hello world")
    # py3
    	print("Hello world")
    	input("Hello world")
    
  • 数据类型不同,python2中的Unicode对应python3中的str,python2中的str对应python3中的bytes

    py2       unicode        str 
    py3        str           bytes
    
  • python2中 int类型超过长度会自动转化成long,python3中只有int

  • xrange与range的区别

    # py2
    	range: 在内部会立即把所有的值都会创建
    	xrange: 在内部不会立即创建的所有的值,只有在循环时,边循环边创建
    # py3
    	range:在内部不会立即创建的所有的值,只有在循环时,边循环边创建
    
  • 模块与包

    # py2
    	文件中必须有__init__.py
    # py3
    	文件中不需要,但是建议写
    
  • 字典

    # py2:
        keys: 列表	
        values: 列表
        items: 列表
    # py3
    	keys: 迭代器,可以循环但不可以索引	
        values: 迭代器,可以循环但不可以索引
        items: 迭代器,可以循环但不可以索引
    
  • 内置函数map/filter

    py2:返回列表
    py3:返回迭代器,可以循环但不可以索引
    
  • 类中的新式类与经典类:python3中默认都会继承object,所以没有经典类只有新式类

3.运算符

v = 1 and 8 or 9 and 0 or True
# 8

知识点:
    and,如果第一个转换成布尔值为True,则输出第二值,反之则输出第一个值
	or ,如果第一个值转换成布尔值为True,则输出第一个值,反之则输出第二个值
	not,如果not x 转换成布尔值为True,则输出False,反之则输出True
	优先级: not,and ,or

4.pass 的作用

1.空的语句,占位符,不表示任何意义
# 在软件设计阶段时候用来TODO,提醒实现相应的实现(留着以后用)
def log(*args):
	pass # please implement this
2.保证格式的完整性

5.*args和**kwargs

# 1.args和kwargs 名字就是一个变量,是开发人员的约定俗称的定义

# 2.*args 和 **kwargs 允许函数接收不定数量的参数
    *args可以接受一个或者多个非关键字参数,args一个元组的形式返回
    **kwargs 可以接受一个多个关键字参数,对传参的位置没有要求,kwargs以一个字典的形式返回
    
# 3. *
1)聚合:函数接收实参时,按顺序分配给函数形参,如果遇到带*的形参,那么就把未分配出去的实参以元组的形式打包,分配给那个带*的形参
2)打散: 把聚合的实参(元组或者列表)拆分成单个的,依次赋值给函数的形参

# 4.**
1)聚合: **kwargs 是把多个关键字参数聚合成字典
2)打散: **kwargs是把字典的键值拆成单个的,依次赋值给函数的形参。

6.列举数据类型常用的方法

  • int

  • bool

  • str

    upper()  大写
    split()  分割
    isdecimal   字符串只由十进制数组成
    strip()  取空格
    replace  替换
    join()   拼接
    len
    count
    
  • list

    append()   追加元素
    insert     添加元素
    pop()      删除元素,默认删除最后一个,有返回值
    remove()   删除元素
    extend     扩展
    sort       反转
    reserve    排序
    
  • tuple

  • dict

    keys    获取键
    values   获取字典的值
    items    获取字典的键值对
    get      根据键获取值,有返回值,存在即返回值,不存在返回None
    pop      根据键删除值,有返回值,
    
  • set

    add   添加元素
    
    

7.集合求交并差

交集: v1 & v2
并集:	v1 | v2
差集:
     v1中存在,v2中不存在: v1 - v2
     v2中存在,v1中不存在: v2 - v1
    

8.如下两个类型的区别

((1),(2),(3))  元组
(1,2,3)     元组

9.大文件操作

f = open(...)
for line in f:
	pass

10.常用的内置函数

len,range,help,数据类型转换,进制转换

11.高级的内置函数

map/reduce/filter/zip
a. 函数的作用
b. 写实列

12以下函数有什么坑

def func(a,b=[]):
	pass

13.什么是闭包?

什么是闭包?
# 1.在闭包只能存在在嵌套函数
# 2.内层函数对外层函数非全局变量的引用,
# 闭包的作用
	# 保证数据的安全
内置函数调用外部函数存储的数据
def func():
	v = 123
	def inner():
		print(v)
	return inner
data = func()
data()

14.装饰器& 带参数的装饰器

# 装饰器
def warpper(func):
    def inner(*args,**kwargs):
        # 函数执行之前做的操作
        ret = func(*args,**kwargs)
        # 函数执行之后做的操作
        return ret
    return inner

@warpper
def index():
    print(123)
index()

# 带参数的装饰器
def xx(a):
    def warpper(func):
        def inner(*args,**kwargs):
            ret = func(*args,**kwargs)
            return ret
        return inner
    return warpper

@xx(a)
def inder():
	print(123)
index()

# 装饰器相关的知识点
装饰器的一个定义:
	在不改变原被装饰的函数的源代码以及调用方式下,为其添加额外的功能。
装饰器的开放封闭原则:
    开放:对扩展,新添功能是开放的
    封闭:对函数的修改是封闭
装饰器的应用场景:
    1.用户的登录注册

15.列表生成式

v = [lambda :x+10 for x in range(10)]
result = v[3]()
print(result)
# 19

16.什么是迭代器

从前到后逐一迭代取值,只能向前无法倒退,可以使用内部的__next__ 方法取值
v1 = iter([1,2,3,4,5,6])
v1.__next__()
v1.__next__()
v1.__next__()
next(v1)

17.什么是生成器?

不在内存中一次性创建太多数据,而是生成器让他在使用的过程中逐步创建,一个函数如果内部还有yield放入关键字,则此函数就是生成器函数

# 生成器函数
def func():
    yield 1
    yield 2
    
# 生成器
v1 = func()

18.函数的参数传递的是值,还是引用?

引用
def func(arg):
	pass
a = [11,22,33]  # 引用计数器 1
func(a) 	    # 引用计数器 2

# [11,22,33]   在内存中的引用计数器再次变成1 

19.找文件夹下的所有的文件

# os.walk

#  利用递归查询
import os
def show_file(path):
    name_file = os.listdir(path)    # 列出指定目录下的所有文件和子目录以列表的形式的展示
    for name is name_file:
        abs_path = os.path.join(path,name)  # 路径的拼接
        if os.path.isfile(os_path)  # 判断是否是一个文件
        	print(abs_path)
        elif os.path.isdir(os_path)  # 判断是否是一个存在的目录
        	show_file(abs_path)
show_path(r"D:22python")  



20.re模块中的match和search 的区别

match: 从头开始
search :遍历整个字符串
    

21.什么是贪婪匹配?

在正则匹配中,贪婪匹配指的是尽量多的去匹配,通过在正则最后加?来控制.

22.给你一段HTML,请找到某个标签

<a href="x" >

23.如何获取用户传入的参数

sys.argv

24.@staticmethod和@classmethod的区别

从传参和执行角度
从它们的使用上来看,
@staticmethod不需要表示自身对象的self和自身类的cls参数,就跟使用函数一样。
@classmethod也不需要self参数,但第一个参数需要是表示自身类的cls参数。
如果在@staticmethod中要调用到这个类的一些属性方法,只能直接类名.属性名或类名.方法名。

而@classmethod因为持有cls参数,可以来调用类的属性,类的方法,实例化对象等,避免硬编码。

25.类变量

class Base:
	x = 1
class Foo(Base):
	pass
class Bar(Base):
	pass



26.super的作用

根据类的继承关系(mro)向上继续找
class Base(object):
	def func(self):
		print('base.func')
		super().func()
class Bar(object):
	def func(self):
		print('bar.func')
class Foo(Base,Bar):
	pass
obj = Foo()
obj.func()

27.魔法方法(双下划线方法)

 
__new__
a. 该方法的返回值是什么?
  	未初始化的一个对象(一个内部没有数据的对象)
    class Foo:
      def __init__(self,name):
        self.name = name
      def __new__(self,cls):
		# 创建一个空的Foo类的对象
return object.__new__(cls) obj = Foo('')

b. 单例模式(加锁)
import time
import threading

class Singleton(object):
	instance = None # 静态字段、类变量 
    lock = threading.RLock()
	
    def __init__(self,name):
		"""初始化对象""" 
    	self.name = name
	
    def __new__(cls, *args, **kwargs): 
        """创建对象"""
        if cls.instance:
            return cls.instance
        with cls.lock:
            if not cls.instance:
                # time.sleep(0.2)
                cls.instance = object.__new__(cls)
            return cls.instance


28.什么是元类

python中的类都是由type创建

class Foo(object):
	pass
等价于
Foo = type('Foo',(object,),{})
通过metaclass可以指定类由谁来创建
class Foo(object,metaclass=XXX):
	pass

29.c/s和b/s架构

#  CS    Client与Server ,中文意思:客户端与服务器端架构,这种架构也是从用户层面(也可以是物理层面)来划分的。
优点:
1.由于客户端实现与服务器的直接相连,没有中间环节,因此响应速度快
2.操作界面漂亮,形式多样,可以充分满足客户自身的个性化要求
3.CS结构的管理信息系统具有较强的事务处理能力,能实现复杂的业务与流程
缺点:
1.需要专门的客户端安装程序,分布功能弱,针对点多面广且不具备网络条件的用户群体,不能实现快速部署安装和配置
2.兼容性差,对于不同的工具,具有较大的局限性.若采用不同工具,需要重新改写程序
3.开发成本高,需要具有一定专业水准的技术人员才能完成

#  BS    Browser与Server,中文意思:浏览器端与服务器端架构,这种架构是从用户层面来划分的。
缺点:
1.具有分布性特点,可以随时随地进行查询,浏览等业务处理
2.业务扩展简单方便,通过增加网页即可增加服务器功能
3.维护简单方便,只需要改变网页,即可实现所有用户的同步更新
4.开发简单,共享性强
缺点:
1.个性性特点明显降低,无法实现具有个性化的功能要求.
2.操作是以鼠标为最基本的操作方式,无法满足快速操作的要求
3.页面动态刷新,响应速度明显降低.
4.无法实现分页显示,给数据访问造成较大的压力
5.功能弱化,难以实现传统模式下的特殊功能要求

30简述TCP三次握手和四次挥手

  • 三次握手

    1.客户端向服务端发送syn请求
    2.服务端向客户端回复ack,并发送syn请求
    3.客户端接收请求之后在回复ack表示建立连接
    
    
  • 四次挥手

    1.客户端向服务端发送fin请求
    2.服务端回复ack确认
    3.服务端向客户端发送fin请求
    4.客户端回复ack确认
    
    

    1571402375054

# TCP三次握手
在TCP/IP协议中,TCP协议提供可靠的连接服务,采用三次握手建立一个连接。
第1次握手:建立连接时,客户端A发送 一个TCP的SYN(同步序列编号(Synchronize Sequence Numbers)包(标志位置 SYN=j),并进入SYN_SEND状态,等待服务器B确认。
第2次握手:服务器B收到SYN包,必须确认客户A的SYN(ACK=j+1),同时自己也发送一个SYN包(SYN=k),即SYN+ACK,此时服务器B进入SYN_RECV状态。
第3次握手:客户端A收到服务器B的SYN+ACK包,向服务器B发送确认包ACK(ACK=k+1),此包发送完毕,客户端A和服务器B进入ESTABLISHED状态,完成三次握手。
完成三次握手,客户端与服务器开始传送数据。

# TCP四次挥手
TCP的连接的拆除需要发送四个包,因此称为四次挥手(four-way handshake)。客户端或服务器均可主动发起挥手动作,在socket编程中,任何一方执行close()操作即可产生挥手操作。    

	由于TCP连接是全双工(又称为双向同时通信,即通信的双方可以同时发送和接收信息的信息交互方式。)的,因此每个方向都必须单独进行关闭。这个原则是当一方完成它的数据发送任务后就能发送一个FIN来终止这个方向的链接。收到一个FIN只意味着这方向上没有数据流动,一个TCP连接在收到一个FIN后仍能发送数据。首先进行关闭的一方将执行主动关闭,而另一方执行被动关闭。 
(1)客户端A发送一个FIN,用来关闭客户端A到服务器B的数据传送
(2)服务器B收到这个FIN,它发回一个ACK,确认收到的序号加1,和SYN一样,一个FIN将占用一个序号。
(3)服务器B关闭与客户端A的连接,发送一个FIN给客户端A。
(4)客户端A发回ACK报文确认,并将确认序号设置为收到序号加1

为什么建立连接协议是三次握手,而关闭连接却是四次挥手呢?   
	这是因为服务端的LISTEN状态下的SOCKET当收到SYN报文的连接请求后,它可以把ACK和SYN(ACK起应答作用,而SYN起同步作用)放在一个报文里来发送。但关闭连接时,当收到对方的FIN报文通知时,它仅仅表示对方没有数据发送给你了;但未必你所有的数据都全部发送给对方了,所以你可能未必会马上会关闭SOCKET,也即你可能还需要发送一些数据给对方之后,再发送FIN报文给对方来表示你同意现在可以关闭连接了,所以它这里的ACK报文和FIN报文多数情况下都是分开发送的。    
    
    报文:是网络中交换与传输的数据单元,即站点一次性要发送的数据块。包含了将要发送的完整的数据信息,其长短很不一致,长度不限且可变

31.OSI 7层模型

# OSI7层模型
OSI是一个开放性的通信系统互联参考模型,它是一个定义的非常好的协议规范。互联网的本质就是一系列的网络协议,这个协议就视为OSI协议。人们按照功能不同,分工不同分为了七层。
会话层
表示层
应用层      http/https/ftp协议
传输层      tcp/udp协议,端口    四层交换机,四层路由器
网络层      IP地址,             设备:三层路由器,三层交换器(带路由功能的交换机)
数据链路层   Mac与ARP协议 ,     设备:二层交换机,网卡
物理层                          设备:双绞线,电缆,光缆等

# OSI五层模型
应用层
传输层
    tcp协议:可靠,效率低,面向连接,全双工通信
        三次握手
        四次挥手
    udp协议:效率高,无连接,不可靠
    物理设备;四层交换机,四层路由器
网络层
	ip协议(ip4,ip6)
    物理设备:路由器,三层交换机
数据链路层
	arp协议:地址解析协议,通过ip找到mac地址
    物理设备:交换机,网卡,单播,广播,组播
物理层

32.TCP和UDP的区别

TCP:面向连接的可靠的流式传输 适合传输比较大的文件,对稳定性要求比较高的
UDP:无连接的 快速 但不可靠 适合传输对效率要求比较高的短消息

可靠地原因:TCP的可靠保证,是它的三次握手双向机制,这一机制保证校验了数据,保证了他的可靠性。
UDP就没有了,udp信息发出后,不验证是否到达对方,所以不可靠。

33什么是粘包

由于两端通信时,会经过计算机的缓存区,并且传输数据时流式无边界,导致例如:A和B通信,A发送了两个数据包,B在接受时无法区分包,可能会获取错误.
为了解决显示错误问题,我们通过struct模块自定义数据内容格式: 头信息|数据

34.socket 代码

客户端和服务端并发一条消息,关闭
# server端(服务端)
import socket
sk = socket.socket()
sk.bind(("127.0.0.1",8000))     # 把地址绑定到套接字上
sk.listen()					  # 监听链接
conn,addr = sk.accept()         # 接收客服端链接
ret = conn.recv(1024)		   # 接收客服端信息
print(ret)                      # 打印客服端信息
conn.send(b"hello work")        # 向客户端发送信息
conn.close()                   # 关闭客户端套接字
sk.close()                     # 关闭服务端套接字

# client端(客服端)
import socket 
sk = socket.socket()              # 创建客户套接字
sk.connect(("127.0.0.1",8000))    # 尝试连接服务器
sk.send(b"hello")                 # 向服务端发送消息
ret = sk.recv(1024)               # 对话
print(ret)
sk.close()                        # 关闭客户套接字

35.断电续传的实现思路


36.进程,线程,协程的区别

# 进程:数据隔离,数据不安全,操作系统级别的,是计算机中最小的资源分配单位,开销非常大,能够利用多核

# 线程:数据共享,数据不安全,操作系统级别的,是计算机能够被CPU调度的最小单位,开销小,不能利用多核,一个和文件操作相关的io操作只有操作系统能够感知到

# 协程:数据共享,数据安全,用户级别的,开销更小,不能利用多核,协程的所有切换都是基于用户的,只有在用户能够够感知到的io才会用到协程模块做切换来规避
    
一个进程总可以有个线程,线程中有多个协程,他们都可以帮助我们完成并发操作,特殊协程只有遇到IO切换才有意义,否则效率反倒会降低

37.GIL锁

GIL; 全局解释器锁
保证一个进程中同一时刻只有一个进程可以被CPU调度

计算密集型用多进程,IO密集型用多线程

可以在一定程度上保证数据的安全
	-list/dict在调用内部方法时,线程是安全
    v =[]
    v.append(100)
    其他操作,如果想要让进程安全,需要自动通过Lock或RLock来实现

补充:在其他编程语言中没有GIL锁,这是cpython特有

38 IO 多路复用


39.数据库引擎

myisam: 不支持事务,只支持表锁,速度快且支持全文索引
innodb:支持事务,支持表锁和行锁;

40.事务的特性

原子性,一致性,隔离性,持久性

41.上课讲的SQL语句看一遍

42.inner join 和 left join的区别


43char 和 varchar 的区别

char :定长
varchar :变长

44.varchar(50),代表什么意思?

50 代表最多支持50个字符

45.笛卡尔积

select * from A,B

46.联合索引如何命中索引


47.mysqldump 导入导出

#mysqldump -h localhost -uroot -p123456 -d database > dump.sql
create table User(.....)
#mysqldump -h localhost -uroot -p123456 database > dump.sql

48.数据库优化方案

数据库读写分离
缓存(Redis,memcached)
分库分表
使用索引&命中索引
设计表结构时,把定长的放前面,变长放后面
有些数据放在内存,不要做连表查询

49.创建索引就应该命中索引,哪些情况下无法命中

。。。。

50.慢日志

执行比较慢或未命中索引的所有SQL

51.SQL注入

select count(1) from user where name = "%s" and pwd = "%s"
select count(1) from user where name = "alex" and pwd = "123"
select count(1) from user where name = "alex" or 1==1 -- " and pwd = "123"

# 如何防止SQL注入:
- pymysql
cursor.execute("select count(1) from user where name = "%s" and pwd = "%s"",['alex','123'])
- ORM

52.redis五大数据类型

str、list、hash、set、sorted set

53.redis 和 memcached的区别

数据类型:redis有5种,memcached有一种数据类型

持久化:redis支持持久化、memcached不支持。

高可用:redis支持、memcached不支持。

分布式集群:redis支持cluster、memcached不支持

54.redis的AOF和RDB有什么区别?

AOF:基于日志做的持久化,保证数据的完整性。即:记录所有执行的命令,恢复时将所有命令执行一遍。

RBD:基于快照做的持久化,速度快。即:定期对reids中的数据进行备份。

55.redis过期策略

redis 内存数据集大小上升到一定大小的时候,就会施行数据淘汰策略。reids提供6中数据淘汰策略:

voltile-lru::从已设置过期时间的数据集(server.db[i].expires)中挑选最近最少使用的数据淘汰。

volatile-ttl:从已设置过期时间的数据集(server.db[i].expires)中挑选将要过期的数据淘汰。

 volatile-random:从已设置过期时间的数据集(server.db[i].expires)中任意选择数据淘汰。

allkeys-lru:从数据集(server.db[i].dict)中挑选最近最少使用的数据淘汰。

allkeys-random:从数据集(server.db[i].dict)中任意选择数据淘汰。

no-enviction(驱逐):禁止驱逐数据

56.写出常用的bootstrap的样式(很少)

container、table、row、form-control、md-col-6

57.什么是响应式布局?

​ 根据用户设备不同,显示不同效果,内部使用了@media属性实现。

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta http-equiv="x-ua-compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1">
    <title>Title</title>
    <style>
        .pg-header{
            height: 45px;
            background-color: red;
        }
        @media (min- 800px) {
            .pg-header{
                background-color: green;
        }
        }
    </style>
</head>
<body>
    <div class="pg-header"></div>
</body>
</html>

58.发送ajax请求

$.ajax({
    url:'...',
    type:"GET",
    data: {},
    dataType:"JSON",
    success:funtion(arg){
    }
})

60.“同源策略”、“跨域”、jsonp、cors?

浏览器具有“同源策略”,即:浏览器只能向当前所在的域发送Ajax,如果向其他域发送请求,浏览器就会报错。

跨域会报错,因为浏览器具有浏览器具有同源策略。但是,同源策略不对script标签中的src属性限制。

如何才能跳过浏览器的同源策略,让我们向别的域可以发送ajax请求并获取结果?
cors一个解决跨域的方案(设置响应头)。主流

jsonp一个解决跨域的方案,是一种巧妙的机制,可以绕过浏览器的同源策略,实现跨域(动态创建script标签)

注意:jsonp只能发送get请求  

扩展:域名、端口、二级域名不同都会引发跨域。

61.谈谈你对前端框架的了解。

vue.js
react.js
angular.js

62.简述你对HTTP协议的理解。

超文本传输协议。
关于连接:http协议规定一次请求一次相应之后断开连接,在此体现了它的无状态,无连接的特点。
关于格式:发送请求时数据是由请求头+请求体组成,头和体之间有两个
分割,请求头之间由一个
分割(请求首行特殊)。响应时也是由响应头和响应体组成。
例如:在浏览器上输入 http:www.baidu.com/edu/api/

sk.send('GET /edu/api/ http1.1
host:www.baidu.com
useragent:....

')
sk.send('POST /edu/api/ http1.1
host:www.baidu.com
useragent:....

user=123&pwd=456')

相关问题:
1.常见的请求头都有哪些?
    user-agent,用的什么浏览器
    host,访问的主机名
    accept,告诉服务端我能接收什么格式的数据
    content-type, 告诉服务器我给你发送的数据是什么格式
    referer(防盗链)

2.常见请求方式
    GET,form表单时用于获取数据,restful api中用于获取数据。
    POST,form表单时一般用户添加和修改,restful api规范中用于添加。
    PUT,restful api规范中用于修改
    PATCH,restful api规范中用于局部修改。
    DELETE,restful api规范中用于删除
    OPTIONS,在解决跨域问题时,遇到复杂请求会先发送一个options请求做预检。

3.常见的状态码
    200,成功
    301,永久重定向
    302,临时重定向
    403,禁止访问
    404,找不到页面
    500,服务器错误

63.简述你对HTTPS协议的理解?


64.django和flask的区别

django 是一个大而全的框架,在他的内部集成了很多方便功能,例如:	ORM,Form,ModelForm,ModelFormSet,中间件,incluion_tag,缓存信号,多数据连接以及读写分离
    
flask 是一个轻量级的框架,可扩展性强,有很多第三方组件可以应用.

之间还有一个最本质的区别,对于请求的处理django是基于传递实现的,flask是基于上下文管理实现.两者是两种不同的实现方式
    

65.flask框架了解


66.django的请求生命周期


67.django中间价作用以及应用场景

可以django中所有的请求处理之前和处理之后进行功能的扩展
应用场景
1.自定义权限组件中使用它做权限控制
2.django内置实现的csrf认证
3.django内置实现的session的功能
4.用户认证
5.用户访问频率限制(对已登录的用户)
6.黑名单和白名单


68.django中路由设置name的作用

基于名字反向生成URL

69.django中FBV和CBV有什么区别

FBV 就是试图中写函数处理业务逻辑
CBV 就是在试图中写类来处理业务逻辑
原文地址:https://www.cnblogs.com/he-qing-qing/p/13688051.html