315道题——基础(1~80)

第一部分 Python基础篇

1. 为什么学习Python?

2. 通过什么途径学习的Python?

3. Python和Java、 PHP、 C、 C#、 C++等其他语言的对比?

4. 简述解释型和编译型编程语言?

5. Python解释器种类以及特点?

6. 位和字节的关系?

7. b、 B、 KB、 MB、 GB 的关系?

8. 请至少列举5个 PEP8 规范(越多越好)。

9. 通过代码实现如下转换:

bin()    0b 二进制
oct()    0o 八进制
hex()   0x 十六进制
二进制转换成十进制: v = “0b1111011”      // 1*2**6+1*2**5+1*2**4...+0*2**2..+2**0 = 64+32+16+8+0+2+1=123
十进制转换成二进制: v = 18       
八进制转换成十进制: v = “011”
十进制转换成八进制: v = 30
十六进制转换成十进制: v = “0x12”  
十进制转换成十六进制: v = 87

10. 请编写一个函数实现将IP地址转换成一个整数。

如 10.3.9.12 转换规则为: 

10 00001010
3 00000011
9 00001001
12 00001100


再将以上二进制拼接起来计算十进制结果: 00001010 00000011 00001001 00001100 = ?

11. python递归的最大层数?

默认的递归最大限度 998

修改最大限度:

  import sys

  sys.setrecursionlimit(num)

12. 求结果:

v1 = 1 or 3     # 1
v2 = 1 and 3    # 3
v3 = 0 and 2 and 1  # 0
v4 = 0 and 2 or 1  # 1  优先级:not > and > or
v5 = 0 and 2 or 1 or 4  # 1
v6 = 0 or False and 1  # False

# print(x or y), 如果 x 为真,则值为x,否则为y
# print(x and y), 如果 x 为真,则值为y,否则为x

也可以理解成:  

  如果是or 前面如果是真的,就不继续往后运算了

  如果是and,前面如果是假的,也不用继续往后运算了

13. ascii、 unicode、 utf-8、 gbk 区别?

  ASCII:是美国最初的编码,只包含了英文字母、数字和特殊字符

  Unicode: ASCII 是1个字节,8位,256种不同组合,不能满足非英语国家的需要,为了解决全球化的文字问题,产生了Unicode码

  utf-8: utf-8是Unicode的升级版,Unicode用4个字节表示一个汉字,而utf-8只用3个字节表示一个汉字

  gbk: gbk是中国为自己编写的,2个字节表示一个汉字,只能在国内使用

 

14. 字节码和机器码的区别?

  字节码: 编译后的二进制文件,比机器码更抽象,需要虚拟机

  比如:字节码在运行时通过JVM(JAVA虚拟机)做一次转换生成机器指令,因此能够更好的跨平台运行。

  机器码: 机器码是电脑CPU直接读取运行的机器指令,运行速度最快,但是非常晦涩难懂,也比较难编写


15. 三元运算规则以及应用场景?

  c = a if a>b else b

  场景:

16. 列举 Python2和Python3的区别?

汉字 的识别     
    python2  默认ASCII码  --------------- 得加 #-*- encoding:utf-8 -*-
    python 3 是utf-8  

raw_input()          
input()              

print'' 
print('')

range  和  xrange   
python 3 中没有xrange

python 3   有nonlocal 关键字  局部命名空间 变量值 的修改
python 2   没有nonlocal  

小数:
python 2  中向下取整    小数是float类型    
python3中没有float类型 

17. 用一行代码实现数值交换: 


  a = 1


  b = 2

  # a, b, = b, a

18. Python3和Python2中 int 和 long的区别?

int范围之内: 内存中只创建一个值,多个变量指向同一个地址

int范围之外: 自动把数据类型转换成long类型

32位系统 int的范围为 -2**31 到 2**31-1 ???????????????????????????

64位系统 int的范围为 -2**63 到 2**63-1

#int 类型 在python中 -5 到 257 如果有变量的值相同,在这个范围内,不会创建多个值出来,只会创建一个值出来

#python中long没有范围,long的范围大小只根据你的内存大小来决定

19. xrange和range的区别?

  都是生成生成器

20. 文件操作时: xreadlines和readlines的区别?

readlines() 读取文件所有内容,按行为单位放到一个列表中,返回list类型。

xreadlines() 返回一个生成器,来循环操作文件的每一行。循环使用时和readlines基本一样

21. 列举布尔值为False的常见值?

  None, ' ' , 0, [], {}, () 

22. 字符串、列表、元组、字典每个常用的5个方法?

split   replace    trip    lower   join('abc'): 用字符串分割abc

append    insert     index [0]    [:]

元组: .index()    .count()

dic['k'] = v dic.setdefault('k', ‘v’) :存在不修改 dic.get dic.pop dic.clear .items() .values()

23. lambda表达式格式以及应用场景?

foo = lambda x: x+1

场景:

24. pass的作用?

空语句: do nothing

占位: 思路没想好

25. *arg和**kwarg作用

接收多余的位置参数和关键字参数

不知道要传多少个参数

26. is和==的区别

==: 值相等

is: 内存地址相同

27 简述Python的深浅拷贝以及应用场景?

浅拷贝: 指向内存地址

不可哈希=: 浅拷贝

不可哈希嵌套: 外层深拷贝, 内层浅拷贝

深拷贝: 开辟新的内存地址

场景: stark组件,需要修改request.GET里面的值,因为其他地方可能还用到,所以深拷贝一份(_mutable = True才能修改)

28. Python垃圾回收机制?

定义一个变量,当这个变量以后不再被引用,这个变量就要回收掉,解释器开了线程帮程序员干了这活(其他语言需要程序员自己回收),把程序员解放出来了.

这个需要GIL锁,垃圾回收线程工作的时候,其他所有线程都要停止(防止要回收的变量恰好又被重新赋值,给回收错了)

29. Python的可变类型和不可变类型?

可哈希: string, tuple, 数字

不可哈希:list sets dict

30. 求结果:

v = dict.fromkeys(['k1','k2'],[])
v[‘k1’].append(666)
print(v)    #  {"k1":[666], "k2":[666]}
v[‘k1’] = 777
print(v)     # {"k1":777, "k2":[666]}

31. 求结果:

def num():
    return [lambda x: i * x for i in range(4)]  # [3x, 3x, 3x, 3x]

print([m(2) for m in num()])
# [6, 6, 6, 6]

32. 列举常见的内置函数?

    isinstance()
    divmod  求商
    max
    min
    reverse
    abs
    map
    zip

33. filter、 map、 reduce的作用?

filter()函数不改变可迭代对象原来的元素,只是元素个数<=原数量
   filter(func,iter)
            def func(n):
                if n > 3:
                    return True
            t = filter(func,[1,2,3,4,5])
            print(type(t))           #<class 'filter'>
            print(list(t))           #[4,5]

map(func ,iter1,iter2)          根据提供的函数对指定序列做映射
    新内容个数 = 原内容个数
    map() 和 filter() 区别:map不改变元素个数     可迭代对象的 元素 可能发生变化
    
    def f(x):
        return x**2
    ret = map(f,[1,2,3,4,5,6,7,8])      map(函数,可迭代obj)          
    print(list(ret))                               返回:迭代器 
    #[1, 4, 9, 16, 25, 36, 49, 64]

reduce:
    reduce把一个函数作用在一个序列[x1, x2, x3, ...]上,这个函数必须接收两个参数,reduce把结果继续和序列的下一个元素做累积计算,其效果就是reduce(f, [x1, x2, x3, x4]) = f(f(f(x1, x2), x3), x4)
    需要引入: from functools import reduce

34. 一行代码实现9*9乘法表

print('\n'.join([' '.join(["%s*%s=%-2s" % (x,y,x*y) for x in range(1, y+1)]) for y in range(1, 10)]))
# 大列表套小列表,小列表里面是每一行

35. 如何安装第三方模块?以及用过哪些第三方模块?

pip安装

源码安装: 下载包,解压, ./configure    make     make install
re    pymysql     beautifulsoup4    lxml    djangorestframework    wtforms    SQLAlchemy     flask-session    flask-script

36. 至少列举8个常用模块都有那些?

 

37. re的match和search区别?

re.search()    # 只找第一个
re.match()    # 从头开始匹配,找不到返回None
.group()取值,  # None.group()会报错

39. 什么是正则的贪婪匹配?

尽量多的去匹配

    import re
    s = 'xyabc'
    ret1 = re.findall('a.*', s)    # ['abc']贪婪
    ret2 = re.findall('a.*?', s)    # ['a'] 非贪婪
    print(ret1, ret2)

39. 求结果:

a. [ i % 2 for i in range(10) ]     # [0, 1, 0, 1, 0, 1, 0, 1, 0, 1]
b. ( i % 2 for i in range(10) )     # 生成器  for循环取值  结果和上面的一样

40 求结果:

a. 1 or 2       # 1
b. 1 and 2      # 2
c. 1 < (2==2)   # False
d. 1 < 2 == 2   # True

41. def func(a,b=[]) 这种写法有什么坑?

参数为不可哈希类型,类似b=[]放到外面

42. 如何实现 “1,2,3” 变成 [‘1’,’2’,’3’] ?

'1,2,3'.split(',')

43. 如何实现[‘1’,’2’,’3’]变成[1,2,3] ?

list(map(lambda x:int(x), li))

44. 比较: a = [1,2,3] 和 b = [(1),(2),(3) ] 以及 b = [(1,),(2,),(3,) ] 的区别?

a: 一个列表, 三个int元素

b: 一个列表, 三个int元素

c: 一个列表, 三个tuple元素

45. 如何用一行代码生成[1,4,9,16,25,36,49,64,81,100] ?

[i**2 for i in range(1,11)]

46. 一行代码实现删除列表中重复的值 ?

[i for i in set(li)]

47. 如何在函数中设置一个全局变量 ?

globals
n = 1

def foo():
    global n
    return n+1

48. logging模块的作用?以及应用场景?

记录日志

场景: 数据库写入,记录日志, 

49. 请用代码简单实现stack 。

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

    def push(self, data):
        self._item.append(data)  # 压栈

    def pop(self):
        try:
            self._item.pop()  # 出栈
        except IndexError:
            return '空栈'

    def is_empty(self):
        return self._item == []

    def peek(self):  # 查看栈顶元素
        return self._item[-1]

    def size(self):
        return len(self._item)


if __name__ == '__main__':
    stack = Stack()
    print(stack.pop())

50. 常用字符串格式化哪几种?

json:
dumps 转换成str      str = json.dumps(dic)
dump 写入文件        json.dump(dic,f)
loads 倒回来            dic = json.loads(str)
load 从文件倒回来     dic = json.load(f)

pickle: 所有类型可以 python独有
类似json的四个方法

shelve:打开一个文件 然后把文件句柄当做一个字典去操作
f = shelve.open('file', flag='r') # r:只读
f['k1'] = ‘v1’

51. 简述 生成器、迭代器、可迭代对象 以及应用场景?

可迭代协议:含有__iter__方法
迭代器协议:含有__iter__方法 且 __next__方法

可迭代对象: 含有__iter__方法              可迭代对象.__iter__        就变成 迭代器
    range()
迭代器: 含有__iter__方法和__next__方法         迭代器.__next__    调用迭代器
    内置迭代器:enumerate()
生成器: 函数含有yield  
    redis的 scan_iter,   

52. 用Python实现一个二分查找的函数。

li = list(range(10))

def foo(li, arg):                   # 时间复杂度: O(logn)
    low = 0
    high = len(li) - 1          # high/low是索引(下标)
    while low <= high:
        mid = (high + low) // 2
        if arg < li[mid]:
            high = mid - 1
        elif arg > li[mid]:
            low = mid + 1
        else:
            return mid
    return None

print(foo(li, 3))
# 3

53. 谈谈你对闭包的理解?

闭包= 函数+引用环境
def func(arg):
    def inner():
        return arg + 1
    return inner

func(1)
func(2)
# 两次传不同的参数,得到2个不同的内部函数(这就是:函数+引用环境)

54. os和sys模块的作用?

os: 可以使用操作系统函数的方法

sys: 可以访问 由解释器使用或维护的变量 和 与解释器进行交互的函数。

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

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

os.remove(‘path/filename’) #删除文件
os.rename(oldname, newname)  #重命名文件
os.mkdir/makedirs('dirname') #创建目录/多层目录
os.rmdir/removedirs('dirname')  #删除目录/多层目录
os.getcwd()  #取得当前工作目录
os.path.join(path1[,path2[,...]]) #将分离的各部分组合成一个路径名
os.path.split('path')  #返回( dirname(), basename())元组
os.path.exists() # 是否存在

sys.path  #返回模块的搜索路径,初始化时使用PYTHONPATH环境变量的值
sys.platform  #返回操作系统平台名称
sys.stdout  #标准输出
sys.stdin  #标准输入
sys.stderr  #错误输出

55. 如何生成一个随机数?

import random
ret = random.randint(1,1000)
print(ret)
# randrange 可以设置步长
# random.random()   0-1之间的随机小数

56. 如何使用python删除一个文件?

os.remove('path/filename')

57. 谈谈你对面向对象的理解?

 

58. Python面向对象中的继承有什么特点?

python继承一个特点就是支持多继承

继承关系: 经典类(深度优先) 新式类(广度优先)

python2:

  新式类: class A(object): pass

  经典类: class A: pass

python3:

  都是新式类:

59. 面向对象深度优先和广度优先是什么?

新式类,经典类, 区分这两个类就是看是否继承Object类

新式类: 广度优先

经典类: 深度优先

60 面向对象中super的作用?

执行super的时候, 会在实例对象的MRO列表上搜搜cls的下一个类

分两步:

  找到inst的MRO列表

  找到当前cls的索引,索引+1, 返回cls下一个类

61. 是否使用过functools中的函数?其作用是什么?

from functools import wraps  # 装饰器修复器,(报错什么的,被装饰函数的__dict__, __doc__属性时装饰器的)
from functools import reduce   #传进去的函数必须2个参数,求和再和后面的累积计算
from functools import partial   # 偏函数  把部分参数锁定固定的值

def add(a, b):
    return a + b

add3 = partial(add, 3)            # 为函数自动传参
add5 = partial(add, 5)

print(add3(10))  # 13
print(add5(10))  # 15

62 列举面向对象中带双下划线的特殊方法,如: __new__、 __init__

1. 调用对象的一个不存在的属性时会触发__getattr__方法 
2. 删除对象的一个属性的时候会触发__delattr__方法 
3. 设置对象(增加/修改)属性会触发__setattr__方法

__call__
__mro__
__name__
__dict__        # {属性名: 属性值}
__doc__
__str__         # 显示对象信息, 面向用户
__repr__        # 显示对象信息,输出字符串 '1'  面向开发人员
__dir__
__setitem__     # 采取字典格式的操作,才会触发
__getitem__     
__delitem__

63. 如何判断是函数还是方法?

类外面: ---- 函数

类里面:

  取决调用者

    类.func(xx) ---- 函数

    对象.func() ----方法

from types import MethodType, FunctionType


class A:

    def func(self):
        return 123


print(isinstance(A.func, MethodType))       # False
print(isinstance(A.func, FunctionType))     # True          类调用,是函数

a = A()

print(isinstance(a.func, MethodType))       # True          对象调用, 是方法
print(isinstance(a.func, FunctionType))     # False

64 静态方法和类方法区别?

类方法: @classmethod

  调用:不需要实例化 直接用类名调用就好

  定义:不用接受self参数,默认传cls,cls就代表当前方法所在的类

  什么时候用类方法?

    需要使用静态变量 且 不需要和对象相关的任何操作的时候

静态方法: @staticmethod

  调用: 类名.func(), 不需要self和cls参数, 和普通的函数没啥区别

  什么时候用静态方法?

    既不需要操作静态变量,也不需要使用对象相关的操作,就用静态方法

65. 列举面向对象中的特殊成员以及应用场景

__repr__ __str__

66. 1、 2、 3、 4、 5 能组成多少个互不相同且无重复的三位数

 

67. 什么是反射?以及应用场景?

什么是反射:

  反射的概念是由Smith在1982年首次提出的,主要是指程序可以访问、检测和修改它本身状态或行为的一种能力(自省)。

python面向对象中的反射:

  通过字符串的形式操作对象相关的属性。python中的一切事物都是对象(都可以使用反射)


四个可以实现自省的函数:

下列方法适用于类和对象(一切皆对象,类本身也是一个对象)

hasattr(obj,属性) #检测对象是否拥有这个属性
getattr(obj,属性) #查看对象 的属性
setattr(obj,属性,值) # 添加/修改 属性
delattr(obj,属性) # 删除属性

场景:

scoped_session dispatch

68. metaclass作用?以及应用场景?

 

69. 用尽量多的方法实现单例模式。

方式一: 模块 单例模式: 天生单例
方式二: __new__ 单例模式:

class Singleton(object):
    a = 1
    _flag = None            # 创建一个_flag标识,初始值None
    
    def __new__(cls, *args, **kw):          # cls: MyClass  指向实例化的类
        print("cls.a-->>", cls.a)                   # 2   证明cls接收的参数是 MyClass类
        print("cls._flag-->>", cls._flag)
        if not cls._flag:           # 第一次进来, _flag==None, if条件成立,创建一个对象,赋值给_flag, 从这以后_flag!=None
            cls._flag = super(Singleton, cls).__new__(cls)          # super(Singleton, cls) : 父类 (Singleton类的父类是object)
        return cls._flag            # 现在返回的是一个对象, 往后,因为if条件不成立,就不再创建新的对象,返回的永远是第一个对象

70. 装饰器的写法以及应用场景。

def wrapper(func):
    def inner(*args, **kwargs):
        print("被装饰函数执行前...")
        ret = func(*args, **kwargs)
        print("被装饰函数执行后...")
        return ret

    return inner

场景: CBV dispatch的csrf_protect/csrf_exempt flask路由 Django的auth认证

71. 异常处理写法以及如何主动抛出异常(应用场景)

try:
  pass
except Exception as e:
  pass

场景:

  使用pymysql的时候,sql语句提交的时候,抛出异常回滚,

  评论,评论数量+1

  主动抛出异常:

    from rest_framework import exceptions

    raise exceptions.AuthenticationFaile("认证失败") 认证组件 三个返回值 (user,auth) None raise

72. 什么是面向对象的mro

mro 多继承属性查找机制,平常我们说的经典类(深度优先),新式类(广度优先),产生这两种情况,是因为算法不同

python2.3版本之前,是深度优先的搜索算法, 2.3版本后,采用C3算法,解决原来基于深度优先搜索算法不满足本地优先级,和单调性的问题。

本地优先级:指声明时父类的顺序,比如C(A,B),如果访问C类对象属性时,应该根据声明顺序,优先查找A类,然后再查找B类。

单调性:如果在C的解析顺序中,A排在B的前面,那么在C的所有子类里,也必须满足这个顺序。

73. isinstance作用以及应用场景?

isinstance(对象,类): 判断这个对象是不是这个类或这个类的子类的实例化

issubclass(子类,类): 判断一个类是否是另一个类的子类

场景: 给前端页面时间,重写json序列化时间datetime对象,

74. 写代码并实现:

Given an array of integers, return indices of the two numbers such that they add up to a
specific target.You may assume that each input would have exactly one solution, and you may
not use the same element twice.

Example:

Given nums = [2, 7, 11, 15], target = 9,

Because nums[0] + nums[1] = 2 + 7 = 9,

return [0, 1]


def foo(nums):
    n = len(nums) - 1
    while n > 0:
        for i in nums[0:n]:
            if i + nums[n] == 9:
                return i, nums[n]
        n -= 1

75. json序列化时,可以处理的数据类型有哪些?如何定制支持datetime类型?

字符串,字典,列表,元组

import json
import datetime

ctime = datetime.datetime.now()

def _default(obj):
    if isinstance(obj, datetime.datetime):
        return obj.strftime('%Y-%m-%d %H:%M:%S')
    raise TypeError("%s is not JSON serializable" % obj)

j = json.dumps(ctime, default=_default)
print(j)

76. json序列化时,默认遇到中文会转换成unicode,如果想要保留中文怎么办?

汉字: ensure_ascii=False

77. 什么是断言?应用场景?

满足条件,就继续执行,否则终止程序继续往下执行.

场景: 自己没写过,源码里面见到过,rest_framework的GenericViewSet类里面有个get_queryset()方法,里面用到,(坑)

78. 有用过with statement吗?它的好处是什么?

打开文件:
    with open('output.txt', 'w') as f:
        f.write('Hi there!')
多app离线脚本文件:
    from app_demo import app01, app02
    from flask import current_app

    with app01.app_context():
        print(current_app)
        with app02.app_context():
            print(current_app)
        print(current_app)

作用: 是通过某种方式简化异常处理,它是所谓的上下文管理器的一种

上下文管理器提供enter()和exit()方法,这些方法在进入和退出with语句的正文时被调用。

成对执行两个相关的操作的时候,这样就很方便,比如打开文件,读取文件,完成后自动关闭文件,如果过程中发生异常,会再异常前关闭文件,(或遇见return,breark,continue, 同样能关

闭文件)

79. 使用代码实现查看列举目录下的所有文件。

import os
# 三元组: (当前所遍历的目录, [当前所遍历的目录中的所有目录], [当前所遍历的目录中的所有文件])

def find_file(path):
    for root,_dirs,filenames in os.walk(path):
        for filename in filenames:
            print(os.path.abspath(os.path.join(root, filename)))

find_file('D:/一级目录')
不用os.walk:
import os

def find_file(path):
    for child in os.listdir(path):  # ['二级目录1', '二级目录2', '二级目录同级文档.txt']
        child_path = os.path.join(path, child)
        if os.path.isdir(child_path):
            find_file(child_path)
        else:
            print(child_path)

find_file('D:/一级目录')

80. 简述 yield和yield from关键字。

yield关键字:

  一个函数使用yield返回值,函数就变成一个生成器,

  执行函数的时候,遇到yield就暂停,使用next()函数和send()函数可以恢复生成器

yield from: 代替for循环

for i in a:
    yield i
等价于
yield from a

def func():
    s = 'abcd'
    yield from s
print(func())
print(func().__next__())
print(list(func()))

 

posted @ 2018-06-02 12:07  静静别跑  阅读(272)  评论(0)    收藏  举报