今天继续分享 Python 相关的面试题,在学习的路上,与君共勉,个人文采好棒哦!html
基础篇(二) 第一部分能够在这里查看(我是超连接)python
print("This is for %s" % "Python")
print("This is for %s, and %s" %("Python", "You"))
复制代码
outputweb
This is for Python
This is for Python, and You
复制代码
在 Python3 中,引入了这个新的字符串格式化方法。面试
print("This is my {}".format("chat"))
print("This is {name}, hope you can {do}".format(name="zhouluob", do="like"))
复制代码
output正则表达式
This is my chat
This is zhouluob, hope you can like
复制代码
在 Python3-6 中,引入了这个新的字符串格式化方法。数据库
name = "luobodazahui"
print(f"hello {name}")
复制代码
output编程
hello luobodazahui
复制代码
一个复杂些的例子:json
def mytest(name, age):
return f"hello {name}, you are {age} years old!"
people = mytest("luobo", 20)
print(people)
复制代码
outputflask
hello luobo, you are 20 years old!
复制代码
str1 = "hello world"
print(str1.title())
" ".join(list(map(lambda x: x.capitalize(), str1.split(" "))))
复制代码
outputapi
Hello World
'Hello World'
复制代码
如:[1, 2, 3] -> ["1", "2", "3"]
list1 = [1, 2, 3]
list(map(lambda x: str(x), list1))
复制代码
output
['1', '2', '3']
复制代码
如:("zhangfei", "guanyu"),(66, 80) -> {'zhangfei': 66, 'guanyu': 80}
a = ("zhangfei", "guanyu")
b = (66, 80)
dict(zip(a,b))
复制代码
output
{'zhangfei': 66, 'guanyu': 80}
复制代码
例子1:
a = (1,2,3,[4,5,6,7],8)
a[3] = 2
复制代码
output
TypeError Traceback (most recent call last)
<ipython-input-35-59469d550eb0> in <module>
1 a = (1,2,3,[4,5,6,7],8)
----> 2 a[3] = 2
3 #a
TypeError: 'tuple' object does not support item assignment
复制代码
例子2:
a = (1,2,3,[4,5,6,7],8)
a[3][2] = 2
a
复制代码
output
(1, 2, 3, [4, 5, 2, 7], 8)
复制代码
从例子1的报错中也能够看出,tuple 是不可变类型,不能改变 tuple 里的元素,例子2中,list 是可变类型,改变其元素是容许的。
反射就是经过字符串的形式,导入模块;经过字符串的形式,去模块寻找指定函数,并执行。利用字符串的形式去对象(模块)中操做(查找/获取/删除/添加)成员,一种基于字符串的事件驱动!
简单理解就是用来判断某个字符串是什么,是变量仍是方法
class NewClass(object):
def __init__(self, name, male):
self.name = name
self.male = male
def myname(self):
print(f'My name is {self.name}')
def mymale(self):
print(f'I am a {self.male}')
people = NewClass('luobo', 'boy')
print(hasattr(people, 'name'))
print(getattr(people, 'name'))
setattr(people, 'male', 'girl')
print(getattr(people, 'male'))
复制代码
output
True
luobo
girl
复制代码
getattr,hasattr,setattr,delattr 对模块的修改都在内存中进行,并不会影响文件中真实内容。
使用 flask 构造 web 服务器
from flask import Flask, request
app = Flask(__name__)
@app.route('/', methods=['POST'])
def simple_api():
result = request.get_json()
return result
if __name__ == "__main__":
app.run()
复制代码
类与实例: 首先定义类之后,就能够根据这个类建立出实例,因此:先定义类,而后建立实例。 类与元类: 先定义元类, 根据 metaclass 建立出类,因此:先定义 metaclass,而后建立类。
class MyMetaclass(type):
def __new__(cls, class_name, class_parents, class_attr):
class_attr['print'] = "this is my metaclass's subclass %s" %class_name
return type.__new__(cls, class_name, class_parents, class_attr)
class MyNewclass(object, metaclass=MyMetaclass):
pass
myinstance = MyNewclass()
myinstance.print
复制代码
output
"this is my metaclass's subclass MyNewclass"
复制代码
sort() 是可变对象列表(list)的方法,无参数,无返回值,sort() 会改变可变对象.
dict1 = {'test1':1, 'test2':2}
list1 = [2, 1, 3]
print(list1.sort())
list1
复制代码
output
None
[1, 2, 3]
复制代码
sorted() 是产生一个新的对象。sorted(L) 返回一个排序后的L,不改变原始的L。sorted() 适用于任何可迭代容器。
dict1 = {'test1':1, 'test2':2}
list1 = [2, 1, 3]
print(sorted(dict1))
print(sorted(list1))
复制代码
output
['test1', 'test2']
[1, 2, 3]
复制代码
GIL 是 Python 的全局解释器锁,同一进程中假若有多个线程运行,一个线程在运行 Python 程序的时候会占用 Python 解释器(加了一把锁即 GIL),使该进程内的其余线程没法运行,等该线程运行完后其余线程才能运行。若是线程运行过程当中遇到耗时操做,则解释器锁解开,使其余线程运行。因此在多线程中,线程的运行还是有前后顺序的,并非同时进行。
import random
"".join(random.choice(string.printable[:-7]) for i in range(8))
复制代码
output
'd5^NdNJp'
复制代码
print('hello\nworld')
print(b'hello\nworld')
print(r'hello\nworld')
复制代码
output
hello
world
b'hello\nworld'
hello\nworld
复制代码
list1 = [{'name': 'guanyu', 'age':29},
{'name': 'zhangfei', 'age': 28},
{'name': 'liubei', 'age':31}]
sorted(list1, key=lambda x:x['age'])
复制代码
output
[{'name': 'zhangfei', 'age': 28},
{'name': 'guanyu', 'age': 29},
{'name': 'liubei', 'age': 31}]
复制代码
all 若是存在 0 Null False 返回 False,不然返回 True;
any 若是都是 0,None,False,Null 时,返回 True。
print(all([1, 2, 3, 0]))
print(all([1, 2, 3]))
print(any([1, 2, 3, 0]))
print(any([0, None, False]))
复制代码
output
False
True
True
False
复制代码
def reverse_int(x):
if not isinstance(x, int):
return False
if -10 < x < 10:
return x
tmp = str(x)
if tmp[0] != '-':
tmp = tmp[::-1]
return int(tmp)
else:
tmp = tmp[1:][::-1]
x = int(tmp)
return -x
reverse_int(-23837)
复制代码
output
-73832
复制代码
首先判断是不是整数,再判断是不是一位数字,最后再判断是否是负数
函数式编程是一种抽象程度很高的编程范式,纯粹的函数式编程语言编写的函数没有变量,所以,任意一个函数,只要输入是肯定的,输出就是肯定的,这种纯函数称之为没有反作用。而容许使用变量的程序设计语言,因为函数内部的变量状态不肯定,一样的输入,可能获得不一样的输出,所以,这种函数是有反作用的。因为 Python 容许使用变量,所以,Python 不是纯函数式编程语言。
函数式编程的一个特色就是,容许把函数自己做为参数传入另外一个函数,还容许返回一个函数!
函数做为返回值例子:
def sum(*args):
def inner_sum():
tmp = 0
for i in args:
tmp += i
return tmp
return inner_sum
mysum = sum(2, 4, 6)
print(type(mysum))
mysum()
复制代码
output
<class 'function'>
12
复制代码
若是在一个内部函数里,对在外部做用域(但不是在全局做用域)的变量进行引用,那么内部函数就被认为是闭包(closure)。
附上函数做用域图片
闭包特色 1.必须有一个内嵌函数 2.内嵌函数必须引用外部函数中的变量 3.外部函数的返回值必须是内嵌函数
装饰器是一种特殊的闭包,就是在闭包的基础上传递了一个函数,而后覆盖原来函数的执行入口,之后调用这个函数的时候,就能够额外实现一些功能了。 一个打印 log 的例子:
import time
def log(func):
def inner_log(*args, **kw):
print("Call: {}".format(func.__name__))
return func(*args, **kw)
return inner_log
@log
def timer():
print(time.time())
timer()
复制代码
output
Call: timer
1560171403.5128365
复制代码
本质上,decorator就是一个返回函数的高阶函数
子程序切换不是线程切换,而是由程序自身控制 没有线程切换的开销,和多线程比,线程数量越多,协程的性能优点就越明显 不须要多线程的锁机制,由于只有一个线程,也不存在同时写变量冲突,在协程中控制共享资源不加锁
斐波那契数列: 又称黄金分割数列,指的是这样一个数列:一、一、二、三、五、八、1三、2一、3四、……在数学上,斐波纳契数列以以下被以递归的方法定义:F(1)=1,F(2)=1, F(n)=F(n-1)+F(n-2)(n>=2,n∈N*)
生成器法:
def fib(n):
if n == 0:
return False
if not isinstance(n, int) or (abs(n) != n): # 判断是正整数
return False
a, b = 0, 1
while n:
a, b = b, a+b
n -= 1
yield a
[i for i in fib(10)]
复制代码
output
[1, 1, 2, 3, 5, 8, 13, 21, 34, 55]
复制代码
递归法:
def fib(n):
if n == 0:
return False
if not isinstance(n, int) or (abs(n) != n):
return False
if n <= 1:
return n
return fib(n-1)+ fib(n-2)
[fib(i) for i in range(1, 11)]
复制代码
output
[1, 1, 2, 3, 5, 8, 13, 21, 34, 55]
复制代码
import re
str1 = 'hello world:luobo dazahui'
result = re.split(r":| ", str1)
print(result)
复制代码
output
['hello', 'world', 'luobo', 'dazahui']
复制代码
yield 是用来生成迭代器的语法,在函数中,若是包含了 yield,那么这个函数就是一个迭代器。当代码执行至 yield 时,就会中断代码执行,直到程序调用 next() 函数时,才会在上次 yield 的地方继续执行
def foryield():
print("start test yield")
while True:
result = yield 5
print("result:", result)
g = foryield()
print(next(g))
print("*"*20)
print(next(g))
复制代码
output
start test yield
5
********************
result: None
5
复制代码
能够看到,第一个调用 next() 函数,程序只执行到了 "result = yield 5" 这里,同时因为 yield 中断了程序,因此 result 也没有被赋值,因此第二次执行 next() 时,result 是 None。
list1 = [2, 5, 8, 9, 3, 11]
def paixu(data, reverse=False):
if not reverse:
for i in range(len(data) - 1):
for j in range(len(data) - 1 - i):
if data[j] > data[j+1]:
data[j], data[j+1] = data[j+1], data[j]
return data
else:
for i in range(len(data) - 1):
for j in range(len(data) - 1 - i):
if data[j] < data[j+1]:
data[j], data[j+1] = data[j+1], data[j]
return data
print(paixu(list1, reverse=True))
复制代码
output
[11, 9, 8, 5, 3, 2]
复制代码
快排的思想:首先任意选取一个数据(一般选用数组的第一个数)做为关键数据,而后将全部比它小的数都放到它前面,全部比它大的数都放到它后面,这个过程称为一趟快速排序,以后再递归排序两边的数据。
挑选基准值:从数列中挑出一个元素,称为"基准"(pivot); 分割:从新排序数列,全部比基准值小的元素摆放在基准前面,全部比基准值大的元素摆在基准后面(与基准值相等的数能够到任何一边)。在这个分割结束以后,对基准值的排序就已经完成; 递归排序子序列:递归地将小于基准值元素的子序列和大于基准值元素的子序列排序。
list1 = [8, 5, 1, 3, 2, 10, 11, 4, 12, 20]
def partition(arr,low,high):
i = ( low-1 ) # 最小元素索引
pivot = arr[high]
for j in range(low , high):
# 当前元素小于或等于 pivot
if arr[j] <= pivot:
i = i+1
arr[i],arr[j] = arr[j],arr[i]
arr[i+1],arr[high] = arr[high],arr[i+1]
return ( i+1 )
def quicksort(arr,low,high):
if low < high:
pi = partition(arr,low,high)
quicksort(arr, low, pi-1)
quicksort(arr, pi+1, high)
quicksort(list1, 0, len(list1)-1)
print(list1)
复制代码
output
[1, 2, 3, 4, 5, 8, 10, 11, 12, 20]
复制代码
一个更加简单的快排写法
def quick_sort(arr):
if arr == []:
return []
else:
first = arr[0]
left = quick_sort([l for l in arr[1:] if l < first])
right = quick_sort([r for r in arr[1:] if r >= first])
return left + [first] + right
arr = [1, 4, 5, 2, 0, 8, 11, 6]
result = quick_sort(arr)
print(result)
复制代码
output
[0, 1, 2, 4, 5, 6, 8, 11]
复制代码
该库是发起 HTTP 请求的强大类库,调用简单,功能强大。
import requests
url = "http://www.luobodazahui.top"
response = requests.get(url) # 得到请求
response.encoding = "utf-8" # 改变其编码
html = response.text # 得到网页内容
binary__content = response.content # 得到二进制数据
raw = requests.get(url, stream=True) # 得到原始响应内容
headers = {'user-agent': 'my-test/0.1.1'} # 定制请求头
r = requests.get(url, headers=headers)
cookies = {"cookie": "# your cookie"} # cookie的使用
r = requests.get(url, cookies=cookies)
复制代码
dict1 = {"zhangfei": 12, "guanyu": 13, "liubei": 18}
dict2 = {"zhangfei": 12, "guanyu": 13, "liubei": 18}
def compare_dict(dict1, dict2):
issame = []
for k in dict1.keys():
if k in dict2:
if dict1[k] == dict2[k]:
issame.append(1)
else:
issame.append(2)
else:
issame.append(3)
print(issame)
sum_except = len(issame)
sum_actually = sum(issame)
if sum_except == sum_actually:
print("this two dict are same!")
return True
else:
print("this two dict are not same!")
return False
test = compare_dict(dict1, dict2)
复制代码
output
[1, 1, 1]
this two dict are same!
复制代码
input() 函数
def forinput():
input_text = input()
print("your input text is: ", input_text)
forinput()
复制代码
output
hello
your input text is: hello
复制代码
enumerate() 函数用于将一个可遍历的数据对象(如列表、元组或字符串)组合为一个索引序列,同时列出数据和数据下标,通常用在 for 循环当中。
data1 = ['one', 'two', 'three', 'four']
for i, enu in enumerate(data1):
print(i, enu)
复制代码
output
0 one
1 two
2 three
3 four
复制代码
pass 是空语句,是为了保持程序结构的完整性。pass 不作任何事情,通常用作占位语句。
def forpass(n):
if n == 1:
pass
else:
print('not 1')
forpass(1)
复制代码
import re
email_list= ["test01@163.com","test02@163.123", ".test03g@qq.com", "test04@gmail.com" ]
for email in email_list:
ret = re.match("[\w]{4,20}@(.*)\.com$",email)
if ret:
print("%s 是符合规定的邮件地址,匹配后结果是:%s" % (email,ret.group()))
else:
print("%s 不符合要求" % email)
复制代码
output
test01@163.com 是符合规定的邮件地址,匹配后结果是:test01@163.com
test02@163.123 不符合要求
.test03g@qq.com 不符合要求
test04@gmail.com 是符合规定的邮件地址,匹配后结果是:test04@gmail.com
复制代码
str2 = 'werrQWSDdiWuW'
counter = 0
for i in str2:
if i.isupper():
counter += 1
print(counter)
复制代码
output
6
复制代码
普通序列化:
import json
dict1 = {'name': '萝卜', 'age': 18}
dict1_new = json.dumps(dict1)
print(dict1_new)
复制代码
output
{"name": "\u841d\u535c", "age": 18}
复制代码
保留中文
import json
dict1 = {'name': '萝卜', 'age': 18}
dict1_new = json.dumps(dict1, ensure_ascii=False)
print(dict1_new)
复制代码
output
{"name": "萝卜", "age": 18}
复制代码
一个类继承自另外一个类,也能够说是一个孩子类/派生类/子类,继承自父类/基类/超类,同时获取全部的类成员(属性和方法)。
继承使咱们能够重用代码,而且还能够更方便地建立和维护代码。
Python 支持如下类型的继承:
单继承- 一个子类类继承自单个基类
多重继承- 一个子类继承自多个基类
多级继承- 一个子类继承自一个基类,而基类继承自另外一个基类
分层继承- 多个子类继承自同一个基类
混合继承- 两种或两种以上继承类型的组合
猴子补丁是指在运行时动态修改类和模块。 猴子补丁主要有如下几个用处:
help() 函数返回帮助文档和参数说明:
help(dict)
复制代码
output
Help on class dict in module builtins:
class dict(object)
| dict() -> new empty dictionary
| dict(mapping) -> new dictionary initialized from a mapping object's | (key, value) pairs | dict(iterable) -> new dictionary initialized as if via: | d = {} | for k, v in iterable: | d[k] = v | dict(**kwargs) -> new dictionary initialized with the name=value pairs | in the keyword argument list. For example: dict(one=1, two=2) ...... 复制代码
dir() 函数返回对象中的全部成员 (任何类型)
dir(dict)
复制代码
output
['__class__',
'__contains__',
'__delattr__',
'__delitem__',
'__dir__',
'__doc__',
'__eq__',
'__format__',
'__ge__',
'__getattribute__',
'__getitem__',
......
复制代码
// 运算符执行地板除法,返回结果的整数部分 (向下取整)
% 是取模符号,返回除法后的余数
** 符号表示取幂. a**b 返回 a 的 b 次方
print(5//3)
print(5/3)
print(5%3)
print(5**3)
复制代码
output
1
1.6666666666666667
2
125
复制代码
使用 raise
def test_raise(n):
if not isinstance(n, int):
raise Exception('not a int type')
else:
print('good')
test_raise(8.9)
复制代码
output
Exception Traceback (most recent call last)
<ipython-input-262-b45324f5484e> in <module>
4 else:
5 print('good')
----> 6 test_raise(8.9)
<ipython-input-262-b45324f5484e> in test_raise(n)
1 def test_raise(n):
2 if not isinstance(n, int):
----> 3 raise Exception('not a int type')
4 else:
5 print('good')
Exception: not a int type
复制代码
tuple1 = (1, 2, 3, 4)
list1 = list(tuple1)
print(list1)
tuple2 = tuple(list1)
print(tuple2)
复制代码
output
[1, 2, 3, 4]
(1, 2, 3, 4)
复制代码
Python 的断言就是检测一个条件,若是条件为真,它什么都不作;反之它触发一个带可选错误信息的 AssertionError。
def testassert(n):
assert n == 2, "n is not 2"
print('n is 2')
testassert(1)
复制代码
output
AssertionError Traceback (most recent call last)
<ipython-input-268-a9dfd6c79e73> in <module>
2 assert n == 2, "n is not 2"
3 print('n is 2')
----> 4 testassert(1)
<ipython-input-268-a9dfd6c79e73> in testassert(n)
1 def testassert(n):
----> 2 assert n == 2, "n is not 2"
3 print('n is 2')
4 testassert(1)
AssertionError: n is not 2
复制代码
同步异步指的是调用者与被调用者之间的关系。
所谓同步,就是在发出一个功能调用时,在没有获得结果以前,该调用就不会返回,一旦调用返回,就获得了返回值。
异步的概念和同步相对。调用在发出以后,这个调用就直接返回了,因此没有返回结果。当该异步功能完成后,被调用者能够经过状态、通知或回调来通知调用者。
阻塞非阻塞是线程或进程之间的关系。
阻塞调用是指调用结果返回以前,当前线程会被挂起(如遇到io操做)。调用线程只有在获得结果以后才会返回。函数只有在获得结果以后才会将阻塞的线程激活。
非阻塞和阻塞的概念相对应,非阻塞调用指在不能马上获得结果以前也会马上返回,同时该函数不会阻塞当前线程。
Python 中的序列是有索引的,它由正数和负数组成。正的数字使用'0'做为第一个索引,'1'做为第二个索引,以此类推。
负数的索引从'-1'开始,表示序列中的最后一个索引,' - 2'做为倒数第二个索引,依次类推。
不是的,那些具备对象循环引用或者全局命名空间引用的变量,在 Python 退出时每每不会被释放。 另外不会释放 C 库保留的部份内容。
Flask 是 “microframework”,主要用来编写小型应用程序,不过随着 Python 的普及,不少大型程序也在使用 Flask。同时,在 Flask 中,咱们必须使用外部库。
Django 适用于大型应用程序。它提供了灵活性,以及完整的程序框架和快速的项目生成方法。能够选择不一样的数据库,URL结构,模板样式等。
import os
f = open('test.txt', 'w')
f.close()
os.listdir()
os.remove('test.txt')
复制代码
logging 模块是 Python 内置的标准模块,主要用于输出运行日志,能够设置输出日志的等级、日志保存路径、日志文件回滚等;相比 print,具有以下优势:
import logging
logging.debug("debug log")
logging.info("info log")
logging.warning("warning log")
logging.error("error log")
logging.critical("critica log")
复制代码
output
WARNING:root:warning log
ERROR:root:error log
CRITICAL:root:critica log
复制代码
默认状况下,只显示了大于等于WARNING级别的日志。logging.basicConfig()函数调整日志级别、输出格式等。
from collections import Counter
str1 = "nihsasehndciswemeotpxc"
print(Counter(str1))
复制代码
output
Counter({'s': 3, 'e': 3, 'n': 2, 'i': 2, 'h': 2, 'c': 2, 'a': 1, 'd': 1, 'w': 1, 'm': 1, 'o': 1, 't': 1, 'p': 1, 'x': 1})
复制代码
re.compile 是将正则表达式编译成一个对象,加快速度,并重复使用。
try..except..else 没有捕获到异常,执行 else 语句 try..except..finally 不论是否捕获到异常,都执行 finally 语句
使用 re 正则替换
import re
str1 = '我是周萝卜,今年18岁'
result = re.sub(r"\d+","20",str1)
print(result)
复制代码
output
我是周萝卜,今年20岁
复制代码
面试题系列第二部分就到这里了,咱们下次见!
欢迎关注个人微信公众号--萝卜大杂烩,或者扫描下方的二维码,你们一块儿交流,学习和进步!