最后
不知道你们用的什么环境,我一般都是用的Python3.6环境和pycharm解释器,没有软件,或者没有资料,没人解答问题,都可以免费领取(包括今天的代码),过几天我还会做个视频教程出来,有需要也可以领取~
给大家准备的学习资料包括但不限于:
Python 环境、pycharm编辑器/永久激活/翻译插件
python 零基础视频教程
Python 界面开发实战教程
Python 爬虫实战教程
Python 数据分析实战教程
python 游戏开发实战教程
Python 电子书100本
Python 学习路线规划
网上学习资料一大堆,但如果学到的知识不成体系,遇到问题时只是浅尝辄止,不再深入研究,那么很难做到真正的技术提升。
一个人可以走的很快,但一群人才能走的更远!不论你是正从事IT行业的老鸟或是对IT行业感兴趣的新人,都欢迎加入我们的的圈子(技术交流、学习资源、职场吐槽、大厂内推、面试辅导),让我们一起学习成长!
认证、权限(授权)、用户访问次数/频率限制、版本、解析器(parser)、序列化、分页、路由系统、视图、渲染器
* **说说Django rest framework框架的认证流程**
- 当用户进行登录的时候,运行了登录类的as_view()方法,进入了APIView类的dispatch方法
- 执行self.initialize_request这个方法,里面封装了request和认证对象列表等其他参数
- 执行self.initial方法中的self.perform_authentication,里面运行了user方法
- 再执行了user方法里面的self._authenticate()方法
## 4. Python基础知识
* **文件操作**
现在要处理一个大小为10G的文件,但是内存只有4G,如果在只修改get\_lines 函数而其他代码保持不变的情况下,应该如何实现?需要考虑的问题都有那些?
from mmap import mmap
def get_lines(fp):
with open(fp,“r+”) as f:
m = mmap(f.fileno(), 0)
tmp = 0
for i, char in enumerate(m):
if char==b"\n":
yield m[tmp:i+1].decode()
tmp = i+1
if name == “__main__”:
for i in get_lines(“fp_some_huge_file”):
print(i)
首先**要考虑的问题**:内存只有4G无法一次性读入10G文件,需要分批读入分批读入数据要记录每次读入数据的位置。分批每次读取数据的大小,太小会在读取操作花费过多时间
* **补充缺失的代码**
def print_directory_contents(sPath):
“”"
这个函数接收文件夹的名称作为输入参数
返回该文件夹中文件的路径
以及其包含文件夹中文件的路径
“”"
import os
for s_child in os.listdir(s_path):
s_child_path = os.path.join(s_path, s_child)
if os.path.isdir(s_child_path):
print_directory_contents(s_child_path)
else:
print(s_child_path)
* **输入日期, 判断这一天是这一年的第几天?**
import datetime
def dayofyear():
year = input("请输入年份: ")
month = input("请输入月份: ")
day = input("请输入天: ")
date1 = datetime.date(year=int(year),month=int(month),day=int(day))
date2 = datetime.date(year=int(year),month=1,day=1)
return (date1-date2).days+1
* **现有字典 d= {‘a’:24,‘g’:52,‘i’:12,‘k’:33}请按value值进行排序?**
sorted(d.items(),key=lambda x:x[1])
* **现有字典 d= {‘a’:24,‘g’:52,‘i’:12,‘k’:33}请按value值进行排序?**
sorted(d.items(),key=lambda x:x[1])
* **将字符串 “k:1 |k1:2|k2:3|k3:4”,处理成字典 {k:1,k1:2,…}**
str1 = “k:1|k1:2|k2:3|k3:4”
def str2dict(str1):
dict1 = {}
for iterms in str1.split(‘|’):
key,value = iterms.split(‘:’)
dict1[key] = value
return dict1
#字典推导式
d = {k:int(v) for t in str1.split(“|”) for k, v in (t.split(“:”), )}
* **python中内置的数据结构有几种?**
>
> **整型 int、 长整型 long、浮点型 float、 复数 complex、字符串 str、 列表 list、 元祖 tuple、字典 dict 、 集合 set、Python3 中没有 long,只有无限精度的 int**
>
>
>
* **python如何实现单例模式?请写出两种实现方式?**
#使用装饰器
def singleton(cls):
instances = {}
def wrapper(*args,**kwargs):
if cls not in instances:
instances[cls] = cls(*args,**kwargs)
return instances[cls]
return wrapper
@singleton
class Foo(object):
pass
foo1 = Foo()
foo2 = Foo()
print(foo1 is foo2) # True
#使用基类
class Singleton(object):
def new (cls, *args, **kwargs):
if not hasattr(cls, ‘_instance’):
cls._instance = super(Singleton, cls). new (cls, *args, **kwargs)
return cls._instance
class Foo(Singleton):
pass
foo1 = Foo()
foo2 = Foo()
print(foo1 is foo2) # True
* **请使用一行代码实现1-100之和**
sum(range(0,101))
* **is和==有什么区别?**
>
> **is: 比较的是两个对象的id值是否相等,也就是比较俩对象是否为同一个实例对象。是否指向同一个内存地址
> == : 比较的两个对象的内容/值是否相等,默认会调用对象的eq()方法**
>
>
>
* **统计一个文本中单词频次最高的10个单词?**
import re
方法一
def test(filepath):
distone = {}
with open(filepath) as f:
for line in f:
line = re.sub(“\W+”, " ", line)
lineone = line.split()
for keyone in lineone:
if not distone.get(keyone):
distone[keyone] = 1
else:
distone[keyone] += 1
num_ten = sorted(distone.items(), key=lambda x:x[1], reverse=True)[:10]
num_ten =[x[0] for x in num_ten]
return num_ten
方法二
使用 built-in 的 Counter 里面的 most_common
import re
from collections import Counter
def test2(filepath):
with open(filepath) as f:
return list(map(lambda c: c[0], Counter(re.sub(“\W+”," ", f.read()).split()).most_common(10)))
* **说说Python的内存管理机制及调优手段?**
>
> **内存管理机制: 引用计数、垃圾回收、内存池
> 引用计数:引用计数是一种非常高效的内存管理手段,当一个Python对象被引用时其引用计数增加1,
> 当其不再被一个变量引用时则计数减1,当引用计数等于0时对象被删除。弱引用不会增加引用计数
> 调优手段:手动垃圾回收、调高垃圾回收阈值、避免循环引用**
>
>
>
* **什么是lambda函数? 有什么好处?**
>
> **lambda 函数是一个可以接收任意多个参数(包括可选参数)并且返回单个表达式值的函数!它比较轻便,即用即仍,很适合需要完成一项功能,但是此功能只在此一处使用,连名字都很随意的情况下!匿名函数,一般用来给filter,map这样的函数式编程服务、作为回调函数,传递给某些应用,比如消息处理**
>
>
>
## 5. Python设计模式
* **对设计模式的理解,简述你了解的设计模式?**
>
> **设计模式是经过总结,优化的,对我们经常会碰到的一些编程问题的可重用解决方案。一个设计模式并不像一个类或一个库那样能够直接作用于我们的代码,反之,设计模式更为高级,它是一种必须在特定情形下实现的一种方法模板!常见的比如工厂模式和单例模式**
>
>
>
* **那既然说到单例,那你说书说单例模式的应用场景?**
>
> **单例模式应用的场景一般发现在资源共享的情况下,避免由于资源操作时导致的性能或损耗等,如日志文件,应用配置。控制资源的情况下,方便资源之间的互相通信。如线程池等**
>
>
>
网站的计数器、应用配置、多线程池、数据库配置、数据库连接池、应用程序的日志应用…
* **对装饰器的理解,并写出一个计时器记录方法执行性能的装饰器?**
>
> **装饰器本质上是一个callable object ,它可以让其他函数在不需要做任何代码变动的前提下增加额外功能,装饰器的返回值也是一个函数对象**
>
>
>
import time
from functools import wraps
def timeit(func):
@wraps(func)
def wrapper(*args, **kwargs):
start = time.clock()
ret = func(*args, **kwargs)
end = time.clock()
print(‘used:’,end-start)
return ret
return wrapper
@timeit
def foo():
print('in foo()'foo())
* **解释以下什么是闭包?**
>
> **在函数内部再定义一个函数,并且这个函数用到了外边函数的变量,那么将这个函数以及用到的一些变量称之为闭包**
>
>
>
* **说说生成器,迭代器的区别?**
>
> **迭代器是遵循迭代协议的对象。用户可以使用 iter() 以从任何序列得到迭代器(如 list, tuple,dictionary, set 等)。另一个方法则是创建一个另一种形式的迭代器 —— generator 。要获取下一个元
> 素,则使用成员函数 next()(Python 2)或函数 next() function(Python 3) 。当没有元素时,则引发 StopIteration 此例外。若要实现自己的迭代器,则只要实现 next()(Python 2)或 next ()
> ( Python 3)**
>
>
>
>
> **生成器(Generator),只是在需要返回数据的时候使用yield语句。每次next()被调用时,生成器会返回它脱离的位置(它记忆语句最后一次执行的位置和所有的数据值)**
>
>
>
>
> **区别: 生成器能做到迭代器能做的所有事,而且因为自动创建iter()和next()方法,生成器显得特别简洁,而且生成器也是高效的,使用生成器表达式取代列表解析可以同时节省内存。除了创建和保存程序 状态的自动方法,当发生器终结时,还会自动抛出StopIteration异常**
>
>
>
* **请用一行代码 实现将1-N 的整数列表以3为单位分组**
N =100
print ([[x for x in range(1,100)] [i:i+3] for i in range(0,100,3)])
* **Python中yield的用法?**
>
> **yield就是保存当前程序执行状态。你用for循环的时候,每次取一个元素的时候就会计算一次。用yield的函数叫generator,和iterator一样,它的好处是不用一次计算所有元素,而是用一次算一次,可以节
> 省很多空间,generator每次计算需要上一次计算结果,所以用yield,否则一return,上次计算结果就没了**
>
>
>
## 6. 系统编程
* **谈谈你对多进程,多线程,以及协程的理解,项目是否用?**
>
> **进程:一个运行的程序(代码)就是一个进程,没有运行的代码叫程序,进程是系统资源分配的最小单
> 位,进程拥有自己独立的内存空间,所有进程间数据不共享,开销大**
>
>
>
>
> **线程: cpu调度执行的最小单位,也叫执行路径,不能独立存在,依赖进程存在,一个进程至少有一个线
> 程,叫主线程,而多个线程共享内存(数据共享,共享全局变量),从而极大地提高了程序的运行效率**
>
>
>
>
> **协程: 是一种用户态的轻量级线程,协程的调度完全由用户控制。协程拥有自己的寄存器上下文和栈。协程调度时,将寄存器上下文和栈保存到其他地方,在切回来的时候,恢复先前保存的寄存器上下文和 栈,直接操中栈则基本没有内核切换的开销,可以不加锁的访问全局变量,所以上下文的切换非常快**
>
>
>
* **Python异步使用场景有那些?**
>
> **(1)不涉及共享资源,获对共享资源只读,即非互斥操作
> (2)没有时序上的严格关系
> (3)不需要原子操作,或可以通过其他方式控制原子性
> (4)常用于IO操作等耗时操作,因为比较影响客户体验和使用性能(5)不影响主线程逻辑**
>
>
>
* **什么是多线程竞争?**
>
> **线程是非独立的,同一个进程里线程是数据共享的,当各个线程访问数据资源时会出现竞争状态即:数据几乎同步会被多个线程占用,造成数据混乱,即所谓的线程不安全!**
>
>
>
那么怎么解决多线程竞争问题?-----------锁
>
> **锁的好处: 确保了某段关键代码(共享数据资源)只能由一个线程从头到尾完整地执行能解决多线程资源竞争下的原子操作问题**
>
>
>
>
> **锁的坏处: 阻止了多线程并发执行,包含锁的某段代码实际上只能以单线程模式执行,效率就大大地下降了**
>
>
>
锁的致命问题: 死锁
* **解释以下什么是锁,有哪几种锁?**
>
> **锁(Lock)是python提供的对线程控制的对象。有互斥锁,可重入锁,死锁**
>
>
>
* **那么什么是死锁?**
>
> **若干子线程在系统资源竞争时,都在等待对方对某部分资源解除占用状态,结果是谁也不愿先解锁,互相干等着,程序无法执行下去,这就是死锁**
>
>
>
* **说说同步,异步,阻塞,非阻塞?**
>
> **同步: 多个任务之间有先后顺序执行,一个执行完下个才能执行**
>
>
>
>
> **异步: 多个任务之间没有先后顺序,可以同时执行,有时候一个任务可能要在必要的时候获取另一个同时执行的任务的结果,这个就叫回调!**
>
>
>
>
> **阻塞与非阻塞: 如果卡住了调用者,调用者不能继续往下执行,就是说调用者阻塞了。如果不会卡住,可以继续执行,就是说非阻塞的**
>
>
>
* **python中进程与线程的使用场景?**
>
> **多进程适合在CPU密集操作(cpu操作指令比较多,如位多的的浮点运算)。多线程适合在IO密性型操作(读写数据操作比多的的,比如爬虫)**
>
>
>
* **python中asyncio的原理?**
>
> **asyncio这个库就是使用python的yield这个可以打断保存当前函数的上下文的机制, 封装好了selector摆脱掉了复杂的回调关系**
>
>
>
## 7. 数据结构
* **无重复字符的最长子串-Python实现**
>
> **可以利用滑动窗口、动态规划、双指针等方法解决该问题**
>
>
>
class Solution:
def lengthOfLongestSubstring(self, s: str) -> int:
res = 0
mark = set() # 用集合标明是否有出现重复字母
r = 0 # 右指针
for i in range(len(s)):
if i != 0:
mark.remove(s[i - 1])
while r < len(s) and s[r] not in mark: # 如果不满足条件说明r走到了s的尽头或r指向的元素
mark.add(s[r]) # 将当前r指向的字母加入集合
r += 1
res = max(res, r - i) # 在每一个位置更新最大值
return res
* **冒泡排序的思想?**
>
> **冒泡排序是一种简单直观的排序算法。它重复地走访过要排序的数列,一次比较两个元素,如果他们的顺序错误就把他们交换过来。走访数列的工作是重复地进行直到没有再需要交换,也就是说该数列已经排序完成**
>
>
>
**算法步骤:**
>
> **1、比较相邻的元素。如果第一个比第二个大,就交换他们两个
> 2、对每一对相邻元素作同样的工作,从开始第一对到结尾的最后一对。这步做完后,最后的元素会是最大的数
> 3、针对所有的元素重复以上的步骤,除了最后一个
> 4、持续每次对越来越少的元素重复上面的步骤,直到没有任何一对数字需要比较**
>
>
>
def bubbleSort(arr):
for i in range(1, len(arr)):
for j in range(0, len(arr)-i):
if arr[j] > arr[j+1]:
arr[j], arr[j + 1] = arr[j + 1], arr[j]
return arr
* **如何利用funtools.lru\_cache做缓存?**
from functools import lru_cache
@lru_cache(maxsize=32)
def fib(n):
感谢每一个认真阅读我文章的人,看着粉丝一路的上涨和关注,礼尚往来总是要有的:
① 2000多本Python电子书(主流和经典的书籍应该都有了)
② Python标准库资料(最全中文版)
③ 项目源码(四五十个有趣且经典的练手项目及源码)
④ Python基础入门、爬虫、web开发、大数据分析方面的视频(适合小白学习)
⑤ Python学习路线图(告别不入流的学习)
网上学习资料一大堆,但如果学到的知识不成体系,遇到问题时只是浅尝辄止,不再深入研究,那么很难做到真正的技术提升。
一个人可以走的很快,但一群人才能走的更远!不论你是正从事IT行业的老鸟或是对IT行业感兴趣的新人,都欢迎加入我们的的圈子(技术交流、学习资源、职场吐槽、大厂内推、面试辅导),让我们一起学习成长!