快速掌握python面试基础,让你面试回答有思路

面试知识点整理

python基础知识

简述变量名的规范

1.变量由字母、数字、下划线任意组成
2.不能以数字开头
3.不能使用python关键字
4.变量要具有可描述性
5.变量不能使用中文
6.驼峰命名和下划线

python编程语言PEP8规范

分号:不要在行尾加分号, 也不要用分号将两条命令放在同一行。

行长度:1.每行不超过80个字符(长的导入模块语句和注释里的URL除外)

​ 2.不要使用反斜杠连接行。Python会将圆括号, 中括号和花括号中的行隐式的连接起来

括号:宁缺毋滥的使用括号,除非是用于实现行连接, 否则不要在返回语句或条件语句中使用括号. 不过在元组两边使用括号是可以的.

缩进:用4个空格来缩进代码,不要用tab, 也不要tab和空格混用.

空格:1.顶级定义之间空2行, 方法定义之间空1行,顶级定义之间空两行, 比如函数或者类定义. 方法定义, 类定义与第一个方法之间, 都应该空一行. 函数或方法中, 某些地方要是你觉得合适, 就空一行.

​ 2.不要在逗号, 分号, 冒号前面加空格, 但应该在它们后面加(除了在行尾).

​ 3.参数列表, 索引或切片的左括号前不应加空格.

​ 4.不要用空格来垂直对齐多行间的标记, 因为这会成为维护的负担(适用于:, #, =等):

注释:总体原则,错误的注释不如没有注释。所以当一段代码发生变化时,第一件事就是要修改注释!

1.文档字符串:
Python有一种独一无二的的注释方式: 使用文档字符串。文档字符串是包, 模块, 类或函数里的第一个语句. 这些字符串可以通过对象的doc成员被自动提取, 并且被pydoc所用。
对文档字符串的惯例是使用三重双引号”“”。

2.函数和方法:
每节应该以一个标题行开始. 标题行以冒号结尾. 除标题行外, 节的其他内容应被缩进2个空格.
列出每个参数的名字, 并在名字后使用一个冒号和一个空格,
分隔对该参数的描述.如果描述太长超过了单行80字符,使用2或者4个空格的悬挂缩进(与文件其他部分保持一致). 描述应该包括所需的类型和含义.
如果一个函数接受foo(可变长度参数列表)或者**bar (任意关键字参数), 应该详细列出foo和**bar.

3.类:
类应该在其定义下有一个用于描述该类的文档字符串. 如果你的类有公共属性(Attributes), 那么文档中应该有一个属性(Attributes)段. 并且应该遵守和函数参数相同的格式.

4.块注释和行注释:
最需要写注释的是代码中那些技巧性的部分. 如果你在下次 代码审查 的时候必须解释一下, 那么你应该现在就给它写注释. 对于复杂的操作,
应该在其操作开始前写上若干行注释. 对于不是一目了然的代码, 应在其行尾添加注释.为了提高可读性, 注释应该至少离开代码2个空格.

类:如果一个类不继承自其它类, 就显式的从object继承. 嵌套类也一样.

语句:通常每个语句应该独占一行

import:不要在一句import中引用多个库

书写python2与python3的三个不同

python2:代码混乱、ASCII交互:raw_input

python3:代码简明、UTF-8交互:input

pass的作用

空语句do nothing

保证格式完整

保证予以完整

is和==的区别

is判断内存地址是否相等

==判断数值是否相等

python垃圾回收机制

1.引用计数

2.标记清除

3.隔代回收

深拷贝和浅拷贝的区别

深拷贝是将对象本身复制个另一个对象。这意味着如果对象的副本进行更改时不会影响原对象

浅拷贝是将一对对象拷贝,二级对象对象引用复制给另一个对象。这意味着如果对象副本进行更改时会影响原对象

import copy

a = [1,2,3]

b = copy.copy(a)

c = copy.deepcopy(a)

*args和kwargs的区别

将list,元组参数传递给函数,用*args

不知道会传入多少参数,用kwargs

个人理解即需要传入未定义的键值对时用kwargs

字节与位的关系

1字节 = 8 位

数字,字符串,列表,元祖,字典对应的布尔值的False分别是什么

数字:0

字符串:空字符串

列表:空列表

元组:空元组

字典:空字典

os和sys模块的作用

os模块负责程序与操作系统的交互,提供了访问操作系统底层的接口

sys模块负责程序与python解释器的交互,提供一系列函数和变量,用于操控python的运行时环境

面向对象的理解

万物皆对象

优点:解决了程序的可扩展性。易维护,易复用

缺点:可控性差

面向对象三大特征

1.封装

隐藏对象的属性和实现细节,提高复用性,安全性

2.继承

提高代码复用性;继承是多态的前提

3.多态

父类或接口定义的应用变量可以指向子类或具体实现类的实例对象。提高程序的扩展性

五大基本原则

1.单一职责原则

类的功能要单一

2.开放封闭原则

一个模块扩展是开放的,修改是封闭的。

3.里氏替换原则

子类可以替换父类出现在父类能够出现的任何位置

4.依赖倒置原则

高层次的模块不应该依赖于低层次的模块。

5.接口分离原则

采用多个于特定客户类有关的接口优于采用一个接口

继承的优点

1.在继承中基类的构造方法(init())不会被自动调用,它需要在派生类的构造中亲自调用

2.在调用基类的方法时,需要加上基类的类名前缀,需要带上self参数变量。区别于类中调用普通函数时并不需要带上self参数

3.python总是首先查找对应类型中的方法即先查找所在类中的方法,找不到再从基类中查找

面向对象中super的作用

1.super在面向对象继承类中代指父类,书写方法super(类名,self).属性或者方法

2.super方法可以增加类之间调用的灵活性,当父类名发生变化时不必修改

3.super方法在类的多继承时可以简化代码,避免代码冗杂

4.super机制保证父类仅被执行一次。

面向对象中的特殊方法

1.__init__(self)

构造方法。创建对象时被访问

2.__call__(self,*args)

对象后面+()直接调用call方法

3.__str__(self方法)

str方法中含有什么就return什么,print

4.__dic__

获取对象中封装的所有字段

python基础语法

进制间转换

十进制 int(v,进制)

二进制 bin(v)

八进制 oct(v)

十六进制 hex(v)

num = 12

num_bin = bin(num)
num_tem1 = int(num_bin,2)
num_oct = oct(num)
num_tem2 = int(num_oct,8)
num_hex = hex(num)
num_tem3 = int(num_hex,16)

字符串常用方法

str = " hellO wOrld "
str2 = "w456w 123w"
str3 = "w456w"

print("首字母大写:{0} 方法:{1}".format(str.capitalize(),'capitalize()'))
print("字符串全部大写:{0} 方法:{1}".format(str.upper(),'upper()'))
print("字符串全部小写:{0} 方法:{1}".format(str.lower(),'lower()'))
print("去除字符串左右空格、tab、换行符:{0} 方法:{1}".format(str.strip(),'strip()'))
print("去除字符串左空格、tab、换行符:{0} 方法:{1}".format(str.lstrip(),'lstrip()'))
print("去除字符串右空格、tab、换行符:{0} 方法:{1}".format(str.rstrip(),'rstrip()'))
print("字符串替换:{0} 方法:{1}".format(str.replace('hello','hi'),'replace(old,new)'))
print("检测{0}和{1}是否开头相同:{2} 方法:{3}".format(str2,str3,str2.startswith(str3),'startwith()'))
print("检测{0}和{1}是否结尾相同:{2} 方法:{3}".format(str2,str3,str2.endswith(str3),'endwith()'))
print("将字符串大小写翻转:原({0}) 翻转({1}) 方法:{2}".format(str,str.swapcase(),'swapcase()'))
print("将字符串每个由非字母开头隔开的单词首字母大写:原({0})转换后({1}) 方法:{2}".format(str,str.title(),'title()'))
print("检测字符全部是数字:字符串({0})结果({1}) 方法:{2}".format(str3,str3.isdigit(),'isdigit()'))
print("检测字符全部是字母:字符串({0})结果({1}) 方法:{2}".format(str3,str3.isalpha(),'isalpha()'))
print("检测字符是字母数字组成:字符串({0})结果({1}) 方法:{2}".format(str3,str3.isalnum(),'isalnum()'))
print("计算字符中某字符个数:字符串({0})个数:{1} 方法:{2}".format(str3,str3.count('w'),'count()'))

列表常用方法

list = ['xiaoming','xiaohong','xiaozhang']
list2 = ['huahua']

#列表添加
list.append('xiaohua')#向列表结尾插入元素
list.insert(2,'xiaolin')#向列表指定索引出插入元素
list.extend(list2)#扩展列表

#列表删除
list.remove('xiaoming')#删除列表指定元素,只删除靠前的
list.pop(2)#删除指定索引元素,默认最后一个元素
del list2#删除列表对象

#列表反转
list.reverse()

#列表排序
list.sort()

#检测元素所在索引
list.index('xiaoming')

写代码,有如下列表,利用切片实现每一个功能

li = [1,3,2,‘a’,4,‘b’,5,‘c’]

1.通过对li列表的切片形成新的列表l3,l3 = [1,2,4,5]
li = [1,3,2,"a",4,"b",5,"c"]
l3 = li[::2]
print(l3)
2.通过对li列表的切片形成新的列表l4,l4 = [3,‘a’,‘b’]
li = [1,3,2,"a",4,"b",5,"c"]
l3 = li[1:6:2]
print(l3)
3.通过对li列表的切片形成新的列表l5,l5 = [‘c’]
li = [1,3,2,"a",4,"b",5,"c"]
l3 = li[-1:]
print(l3)
4.通过对li列表的切片形成新的列表l6,l6 = [‘b’,‘a’,3]
li = [1,3,2,"a",4,"b",5,"c"]
l3 = li[5:0:-2]
print(l3)

li = [1,3,2,"a",4,"b",5,"c"]
l3 = reversed(li[1:6:2])
print(list(l3)

实现“1,2,3” 变成[1,2,3]

import pandas as pd
str = "1,2,3"

#方式一
strList = str.split(',')
series = pd.Series(strList)
series = series.map(lambda x:int(x))
print(list(series))

# 方式二
strList = str.split(',')
i = 0
while i < len(strList):
   strList[i] = int(strList[i])
   i+=1
print(strList)

如何使用python删除一个文件

import os
os.remove(r'path')

异常处理以及抛出异常

try:
	#主体函数
except Exception as e:
	print(e)
	
raise TypeError(‘异常’)

编写一个函数将IP地址转换成一个整数

如 10.3.9.12 转换规则为:
10 00001010
3 00000011
9 00001001
12 00001100
再将以上二进制拼接起来计算十进制结果:00001010 00000011 00001001 00001100 = ?

def test(str):
   """
   
   :param str: 
   :return: 
   """
   strlist = str.split('.')
   reslist = []
   i = 0
   while i < len(strlist):
       strlist[i] = bin(int(strlist[i]))
       i+=1

   for i in strlist:
       reslist.append(i.replace('0b',(10-len(i))*'0'))

   return int(''.join(reslist),2)


str = "10.3.9.125"
print(test(str))

一行代码实现99乘法表

[print('{0}*{1}={2}'.format(j,k,j*k)) for j in range(1,10) for k in range(1,10) if j <= k ]

django知识点

CSRF攻击与防止流程

攻击:

1.用户C浏览并登录信任的站点A

2.A验证通过,在用户C处产生A的cookie

3.用户在没有登出站点A的情况下访问攻击站点B

4.站点B向用户C发送请求,要求访问站点A

5.用户C携带步骤2中的cookie对站点A进行访问

防止:

1.在客户端向后端请求页面数据的时候,后端会往相应中的cookie中设置csrf_token的值

2.在FORM表单中添加一个隐藏的字段,值是csrf_token

3.在用户点击提交的时候,会带上这两个值向后台发起请求

4.在后端接收到请求后,会从cookie中却出csrf_token并和表单数据中的隐藏csrf_token进行对比

5.相同则正常的请求,反之则不执行请求

seesion和cookie的区别

1.cookie信息保存在浏览器,session数据是放在服务器

2.cookie不安全,易进行cookie欺骗

3.session会在一定时间内存放在服务器上,当访问过多时,会占用服务器性能。

4.单个cookie保存的数据不能超过4K,一个站点最多存放20个cookie

一次完整的http请求过程

1.域名解析,找到ip

2.浏览器与网站建立tcp连接

3.网站发起默认的get请求

4.页面返回或返回其他

django对http请求的处理流程

1.在接受一个http请求之前的准备:

​ 1).启动一个支持WSGI网关协议的服务器监听端口等待外界的Http请求。

​ 2).服务器更具WSGI协议制定相应的Handler来处理Http请求,并初始化该Handler

​ 3).此时服务器已处于监听状态,可以接受外界的http请求

2.当一个http请求到达服务器的时候

​ 1).服务器根据WSGI协议从http请求中提取出必要的参数组成一个字典并传入Handler中进行处理

​ 2).在Handler中对已经符合WSGI协议规定的http请求进行分析。

3.返回一个可以被浏览器解析的符合http协议的httpresponse

算法与数据结构

代码实现stack

class Stack(object):
    def __init__(self):
        self.stack = []

    def push(self,value):
        self.stack.append(value)
    
    def pop(self):
        self.stack.pop()
     
    def isEmpty(self):
        return bool(self.stack)
        
    def getNewNum(self):
        return self.stack[-1]  

交换排序

冒泡排序

def bulle_sort(L):
   """
   冒泡排序
   :param L:
   :return:
   """
   for i in range(len(L)):
       for j in range(len(L)-i-1):
           if L[j] > L[j+1]:
               tem = L[j+1]
               L[j+1] = L[j]
               L[j] = tem
   return L

快速排序

def quick_sort(L,start,end):
    """
    快速排序
    :param L:
    :param start:
    :param end:
    :return:
    """
    if start < end:
        i, j, pivot = start, end,L[start]
        while i<j:
            while (i < j) and (L[j] >= pivot):
                j = j-1
            if (i < j):
                L[i] = L[j]
                i += 1
            while (i < j) and (L[i] < pivot):
                i += 1
            if (i < j):
                L[j] = L[i]
                j = j-1

        L[i] = pivot
        quick_sort(L,start,i-1)
        quick_sort(L,i+1,end)

    return L

插入排序

直接插入排序

def insert_sort(L):
   """
   直接插入排序
   :param L:
   :return:
   """

   for i in range(1,len(L)):
       for j in range(i-1,-1,-1):
           if L[j] > L[j+1]:
               tem = L[j+1]
               L[j+1] = L[j]
               L[j] = tem
   return L

希尔排序

def insert_shell(L):
   """
   希尔排序
   :param L:
   :return:
   """
   gap = int(len(L)/2)
   while gap >= 1:
       for i in range(gap,len(L)):
           for j in range(i-gap,-1,-gap):
               if L[j] > L[j+gap]:
                   tem = L[j+gap]
                   L[j+gap] = L[j]
                   L[j] = tem
       gap = int(gap/2)

   return L

选择排序

简单选择排序

def select_sort(L):
    """
    简单选择排序法
    :param L:
    :return:
    """
    for x in range(0,len(L)):
        minimum = L[x]

        for i in range(x+1,len(L)):
            if L[i] < minimum:
                tem = L[i]
                L[i] = minimum
                minimum = tem

        L[x] = minimum

    return L

堆排序

def LEFT(i):
    """
    获取左叶子节点
    :param i:
    :return:
    """
    return 2*i + 1

def RIGHT(i):
    """
    获取右叶子节点
    :param i:
    :return:
    """
    return 2*i + 2

def adjust_max_heap(L,length,i):
    """
    调整大顶堆
    :param L:
    :param length:
    :param i:
    :return:
    """
    largest = i
    while 1:
        left, right = LEFT(i),RIGHT(i)
        if (left < length) and (L[left] > L[i]):
            largest = left
        else:
            largest = i

        if (right < length) and (L[right] > L[largest]):
            largest = right

        if (largest != i):
            temp = L[i]
            L[i] = L[largest]
            L[largest] = temp
            i = largest
            continue
        else:
            break

def build_max_heap(L):
    """
    建立大顶堆
    :param L: 
    :return: 
    """
    length = len(L)
    for x in range((int)((length-1)/2),-1,-1):
        adjust_max_heap(L,length,x)

def heap_sort(L):
    """
    堆排序
    :param L: 
    :return: 
    """
    build_max_heap(L)
    i = len(L)

    while i > 0:
        temp = L[i-1]
        L[i-1] = L[0]
        L[0] = temp

        i -= 1
        adjust_max_heap(L,i,0)

    return L

归并排序

基数排序

爬虫

简述一下爬虫程序的执行过程

1.获取想要的页面

2.根据规则进行解析

3.解析数据入库

爬虫在想数据库存数据开始和结束都会发送一条消息,是scrapy哪个模块实现的

Item PIpeline scrapy的信号处理

爬去下来的数据如何去重,说下具体的算法依据

1.通过MD5生成电子指纹来判断页面是否改变

2.nutch去重。nutch中的digest是对采集数据的每一个网页内容的32位哈希值,如果两个网页内容完全一样,他们的digest值肯定会一样。

线程的同步和异步

线程同步:多线程同时访问同一资源,等待资源访问结束,浪费时间,效率低

线程异步:在访问资源时在空闲等待时间访问其他资源,实现多线程机制

网络的同步与异步

同步:提交请求—>等待服务器处理—>处理完毕返回 期间服务器不能进行其他操作

异步:请求通过事件触发—>服务器处理—>处理完毕

计算机网络

http和https的理解与差别

1.https协议需要到ca申请证书,需缴费
2.http是超文本传输协议,信息是明文传输,https是具有安全性的ssl加密传输协议
3.http端口80,https端口443

tcp和udp的差别

1.tcp是面向连接的(确认有创建三方交握,连接已创建才传输)

2.tcp是有序数据传输

3.tcp是重发丢失的数据包

4.tcp是舍弃重复的数据包

5.tcp是无差错的数据传输

6.tcp有阻塞/流量控住

7.udp通信模型中,不需要先建立相关链接,只需发送数据即可

你可能感兴趣的:(python,爬虫,算法,面试,python,http)