首页 > 技术文章 > python面试题

hanease 2022-03-17 09:07 原文

    • 熟练使用Python常用框架Django/Tornado/Flask,熟悉Restful API;

    • 了解分布式和微服务设计理念,熟练掌握常用的分布式开发框架,了解Kafka, Zookeeper,Redis等开源中间件。

    • 需具备独立数据库设计并且调优的能力;

    • 有良好的编码习惯,对代码和设计质量有严格要求,重视Code Review

    • 熟悉Git,GitHub开发流程,了解敏捷开发方法和DevOps;

    • 具有良好的编程思想、沟通、团队合作精神、优    秀的分析问题和解决问题的能力;具备强烈的责任心。

    • 实的面向对象编程思想,具备模块化编程的思维与经验,熟悉 Git;

    • 了解 python Web 开发框架如 Flask/Django 等优先;

    • 对代码和设计质量有严格要求,重视 Code Review,知道良好的编程习惯的标准;

    • 有基于 Python、Golang Web 的高并发设计和实现经验者加分;

    • 熟悉或了解服务器管理(如 CentOS/Debian/Ubuntu)、服务器缓存技术(如Redis/Memcache)、ELB 技术、CDN 技术者优先;

    • 熟悉 AWS 或其它云服务者加分;

    • 良好的沟通能力、协作能力、抗压能力

    • 熟悉mysql,熟悉sqlAlchemy;    

    • 对分布式和高可用性等相关知识有实际的了解和实践经验,熟悉业界内常用的开源工具,并在不同项目中有实际使用经验;

    • 能够独立完成较复杂的系统分析、设计,并主导完成详细设计和编码的任务,能多维度思考问题,确保项目的进度和质量;

    • 熟悉基本的数据结构和常用算法;

    • 熟悉Mysql/Postgres等关系型数据库;

    • 熟悉Mongo/Couch等NoSQL数据库;

    • 英语读写能力良好者优先;

    • 有小团队管理经验者优先;

    • 熟悉python, django, mysql,memcache,redis,kafka消息队列等常用WEB组件;

    • 握常见场景设计,如消息队列、缓存、高并发、高可用、高负载等;

    • 熟练Web开发框架, 深刻理解HTTP协议, 具备独立Linux、Nginx的使用及搭建、调试、排错、优化、部署等;

    • 熟悉 Docker, Kubernetes, DevOps, ETL/ELT, ELK 等相关技术加分

    • 对分布式系统设计有一定的经验

    • 熟悉MySQL的使用与调优、索引机制和事务机制

    • 对进程、线程、协程,对异步,非阻塞有一定了解与使用;

    • 熟练使用mysql,熟悉mysql的各种存储引擎,熟悉索引工作原理,有丰富的mysql性能优化经验以及高可用、集群实战经验;

    • 对代码和设计质量有严格要求, 重视 Code Review 和 单元测试;

    • 熟悉各种消息队列、分布式任务系统以及网络文件存储软件或平台、并能够给出稳定高效的技术架构;

    • 数据结构和算法功底扎实;

    • 精通Linux操作系统和TCP/IP协议,以及Websocket、HTTP2、MQTT协议等;

    • 有自动化&分布式平台开发经验者优先;

    • 熟悉常用算法和数据结构、操作系统、网络(TCP/IP、HTTP协议)等基础知识

    •  熟悉Docker的基础知识和相关用法

    • 熟悉 TCP/IP 协议及相关知识,有过网络开发经验者优先;

    • 深入了解TCP/UDP协议,进程间通讯编程,熟悉各类服务器架构并能合理的应用; 

    • 对系统的瓶颈、业务扩展性,有比较强的把控能力; 

    • 有大规模业务设计开发经验,并有高并发、同异步后端服务设计经验优先,有架构能力优先。

  1. 无锁、偏向锁、轻量级锁、重量级锁有什么差别?

  2. 线程间通信,同机器进程间通信,跨机器进程间通信,各有什么方法?

  3. 下列三种业务,应该如何使用线程池:

    • 高并发、任务执行时间短

    • 并发不高、任务执行时间长

    • 并发高、业务执行时间长

  4. 一个url从请求到响应都发生了什么?

  5. tcp三次握手,第三次握手是什么?

  6. celery是如何保证消息不丢失的

    1. 消息中间件的持久化

    2. celery的本身的消息ack确认机制

  7. 怎么提高系统的并发性能

    1. 缓存接入,读写分离,分库分表,队列流向小风

  8. 怎么保障接口的安全性,如何去测试一个接口的功能性

  9. mysql主从集群,从有很多,从提供读节点,多从向主同步数据,此刻有很多从连接主节点,如何进行优化

  10. 一起盗窃案,有四个犯罪嫌疑人,从供词中找出谁是那个小偷

    已知3个人说了真话,1个人说的是假话,请问谁是小偷,请用程序编写

    1. a说:不是我

    2. b说:是c

    3. c说:是d

    4. d说:c在胡说

  11. js ==和===区别

    1. == 抽象相等

    2. === 严格相等

  12. http2.0 多路复用1.0、 1.1、 2.0有什么区别

  13. http缓存(强缓存&协商缓存)

  14. tcp、udp区别属于那一层,tcp是怎么保证连接是可靠的

  15. python的数组是怎么进行内存管理,动态扩容

  16. redis AOF持久机制文件越来越大,怎么解决的

  17. python的内存管理和垃圾回收

  18. mysql为什么使用b+树

  19. redis基本数据类型

  20. redis底层数据结构的实现

  21. redis持久化机制,aof文件过大怎么进行优化

  22. 分布式锁

  23. io多路复用epoll模型边缘触发和水平触发

  24. asyncio机制,aiohttp与其关系,时间循环机制

  25. django源码流程

  26. django的中间件是什么

  27. celery的原理,如何配置worker的权重

  28. 如何定位内存过高或CPU过高的问题

  29. _newinit__的区别。

    init为初始化方法,创建对象后,就立刻被默认调用了,可接收参数。

    new方法是真正的构造函数。new是实例创建之前被调用,它的任务是创建并返回该实例。

    init有一个参数self,就是new返回的实例,initnew的基础上可以完成一些其它初始化的动作,init不需要返回值,init是实例创建之后被调用的,然后设置对象属性的初始值。

    总结:new方法在init方法之前被调用,并且new方法的返回值将传递给init方法作为第一个参数,最后init给这个实例设置一些参数。

    https://my.oschina.net/kinegratii/blog/334968

  30. Python自省。

    自省就是面向对象的语言所写的程序在运行时,所能知道对象的类型。简单一句话就是运行时能够获得对象的类型。比如:type()、dir()、getattr()、hasattr()、isinstance()

    https://kb.cnblogs.com/page/87128/

    提高python运行效率的方法

    1、使用生成器,因为可以节约大量内存

    2、循环代码优化,避免过多重复代码的执行

    3、核心模块用Cython PyPy等,提高效率

    4、多进程、多线程、协程

    5、多个if elif条件判断,可以把最有可能先发生的条件放到前面写,这样可以减少程序判断的次数,提高效率

    6、while 循环比基于迭代器的 for 循环慢的多,因为迭代器在 Python 内部是以 C 语言的速度运行的,而 while 循环则是通过 Python 虚拟机运行 Python 字节码的。[P419]

    列表推导比手动 for 循环语句运行得更快(往往速度快一倍),这是因为它们的迭代在解释器内部以 C 语言速度执行的,而不是手动以 Python 代码执行的。尤其对于较大的数据集合,使用列表推导能带来极大的性能优势。[P426]

  31. 简述多线程、多进程

    进程:

    1、操作系统进行资源分配和调度的基本单位,多个进程之间相互独立

    2、稳定性好,如果一个进程崩溃,不影响其他进程,但是进程消耗资源大,开启的进程数量有限制

    线程:

    1、CPU进行资源分配和调度的基本单位,线程是进程的一部分,是比进程更小的能独立运行的基本单位,一个进程下的多个线程可以共享该进程的所有资源

    2、如果IO操作密集,则可以多线程运行效率高,缺点是如果一个线程崩溃,都会造成进程的崩溃 应用: IO密集的用多线程,在用户输入,sleep 时候,可以切换到其他线程执行,减少等待的时间 CPU密集的用多进程,因为假如IO操作少,用多线程的话,因为线程共享一个全局解释器锁,当前运行的线程会霸占GIL,其他线程没有GIL,就不能充分利用多核CPU的优势

  32. 简述any()和all()方法

    都返回 bool 值。

    any():只要迭代器中有一个元素为真就为真

    all():迭代器中所有的判断项返回都是真,结果才为真

  33. sort()和sorted()有什么区别?

    sort() 只是 list 的方法,而 sorted() 可以接受任何的可迭代对象

    若 L 为列表,L.sort() 无返回值,就地更改列表

    sorted(L) 返回一个新的排好序的列表,原列表无变化

  34. Python多线程(multi-threading)。这是个好主意吗?

    Python并不支持真正意义上的多线程,Python提供了多线程包。Python中有一个叫Global Interpreter Lock(GIL)的东西,它能确保你的代码中永远只有一个线程在执行。经过GIL的处理,会增加执行的开销。这就意味着如果你先要提高代码执行效率,使用threading不是一个明智的选择,当然如果你的代码是IO密集型,多线程可以明显提高效率,相反如果你的代码是CPU密集型的这种情况下多线程大部分是鸡肋。

  35. is与==有什么区别?

    在Python中一切都是对象。Python中对象包含的三个基本要素,分别是:id(身份标识)、type(数据类型)和value(值)。对象之间比较是否相等可以用==,也可以用is。

    is 和 == 都是对对象进行比较判断作用的,但对对象比较判断的内容并不相同。

    is比较的是两个对象的id值是否相等,是对象同一性测试,比较地址。也就是比较两个对象是否为同一个实例对象,是否指向同一个内存地址。

    == 比较的是两个对象的内容是否相等,默认会调用对象的eq()方法。

     

  36. a = [1,2,3]
    b = a
    print(id(a),id(b))
    print('a is b? ', a is b)
    print('a == b? ', a == b)
    b = a[:]
    print('-' * 30)
    print(id(a),id(b))
    print('a is b? ', a is b)
    print('a == b? ', a == b)
    """
    输出:
    139944745517896 139944745517896
    a is b?  True
    a == b?  True
    ------------------------------
    139944745517896 139944677151688
    a is b?  False
    a == b?  True
    """
  37. 列出字符串常用操作

    1. s + s1 字符串拼接

    2. s * 3 字符串重复

    3. s.lower() 将字符串转换为小写,大小写仅限于英文字符

    4. s.upper() 将字符串转换为大写

    5. s.islower() 判断字符串是否为小写,输出为布尔类型

    6. s.isupper() 判断字符串是否为大写,输出为布尔类型

    7. s.isalpha() 判断字符串是否由字母组成,输出为布尔类型

    8. s.isdigit() 判断字符串是否由数字组成,输出为布尔类型

    9. s.isalnum() 判断字符串是由字母或数字字符组成,输出为布尔类型

    10. s.replace(s1, s2) 将字符串中的子字符串替换为其它的字符串,用 s2 替换掉s1

    11. s.replace(" ", "") 用 replace 来删除中间的空白字符, 其实就是将空白字符替换为空字符。

    12. s.strip() 删除字符串首尾的空白字符

    13. s.lstrip() 删除字符串首部的空白字符,这里的'l'是英文单词left

    14. s.rstrip() 删除字符串尾部的空白字符,这里的'r'是英文单词right

    15. s.find() 从左到右查找某字符串第一次出现的位置,如果查不到,则返回值为-1

    16. s.rfind() 从右到左查找某字符串第一次出现的位置,如果查不到,则返回值为-1

    17. s.count() 统计字符串出现的次数, 若没有相应的字符串,则返回0

    18. s.startswith()、s.endswith() 分别用来判断字符串是否以指定的子字符串开始或结束,返回值为布尔类型。

    19. s.join(s2) 将 s 插入到 s2 的每一个字符中

  38.  

https://github.com/jinbooooom/Programming-language-QA/blob/master/Python/python.md

Redis

 

  1. Redis 核心数据结构都有哪些?String类型都有哪些特点?

  2. Redis值类型中 hash 和 string 又什么区别呢?实际工作中如何选择?

  3. Redis 持久化是如何工作的?Redis在持久化过程中和可以对外服务么?如果可以的话,Redis又是如何处理新命令的?

  4. Redis 持久化方式Rdb和Aof的优缺点

  5. Redis 内存不够时间,如何处理新的请求?

  6. Redis 是如何处理过期数据的?

  7. Redis 内存淘汰算法 LRU/ LFU 可以将一下原理么?

  8. Redis 有序数据结构zset底层原理有了解过么?

  9. Redis 位图应用场景及实现原理可以讲一下么?

  10. Redis 的缓存穿透/缓存雪崩/缓存重建/这类问题,可以讲讲么

  11. Redis 集群分片原理是怎样的?

  12. Redis 单线程和Redis6.0 的多线程是如何工作的?

  13. Redis 数据结构,底层实现、ZSET 底层实现

  14. Redis 持久化实现方式,优缺点

  15. Redis 分布式锁实现,Redis 集群选举

web

  1. HTTP/GET/POST/PUT/PATCH之间的区别

  2. 状态码的含义以及出现场景,301,302,404,500,502,504等

  3. cookie和session的区别和联系

  4. 从url请求到返回,中间经历了什么

  5. HTTP和HTTPS的区别,HTTPS如何进行加密的

  6. http和https的区别 https的加密方式

  7. TCP三次握手的状态变化

  8. TCP四次挥手 TIME_WAIT出现在哪 为什么要有TIME_WAIT

 

数据库

  1. mysql的索引是什么,如何建立索引,B+树的结构

  2. mysql中的事务是什么,隔离等级是什么

  3. 如何优化sql语句

  4. mysql的性能优化等

算法

  1. 堆和栈的区别

  2. 常用排序算法及时间复杂度

  3. 数据扩容为什么需要翻倍扩容

  4. 8个球,大小相同,一个会重点,通过一个天平最少称几次可以找出这个球

  5. 52张牌那同一个花色概率

  6. 25匹马,5条赛道,最少要跑多少次可以跑出top3

  7. 找到整数列表的最大k个数,时间复杂度

  8. 输入一维数组array和n,找出和值为n的任意两个元素

  9. 常见的排序算法,时间复杂度分析

  10. 生成一个旋转矩阵

django

  1. Django的CSRF防御机制

    Django的CSRF保护主要是通过django.middleware.csrf.CsrfViewMiddleware中间件来实现的。主要流程如下: Django 第一次响应来自某个客户端的get请求时,会在服务器端随机生成一个 csrftoken(一串64位的随机字符串),把这个 token 放请求头的 cookie 里返回给用户。 所有通过POST方式提交的表单在渲染时中必须包含一个 csrfmiddlewaretoken 隐藏字段 (在模板中通过{% csrf_token %}标签生成)。 当用户通过POST提交表单时,Django会从请求头cookie取csrftoken这一项的值,再从POST表单里取csrfmiddlewaretoken交由中间件进行校验两者是否一致。如果一致表明这是一个合法请求,否则返回403 Forbidden.

    https://mp.weixin.qq.com/s?__biz=MjM5OTMyODA4Nw==&mid=2247484531&idx=1&sn=f145778f963b6c81e94700b986afbd0a&chksm=a73c644b904bed5d40c4ffd1b086217d568527bafd7e62bb96f47cb4042407fe5b38c482de34&scene=21#wechat_redirect

  2. 如何从数据表中获取一个随机对象?

    可以使用order_by('?').first()随机获取一个对象

    def get_random_object():
      return MyModel.objects.order_by("?").first()
  3. 如何在模板中获取当前访问url地址

  4. djago 生命周期

  5. Django的Queryset有哪些特性

    Django的QuerySet主要有两个特性:一是惰性的(lazy),二是自带缓存。

    下例中article_list试图从数据库查询一个标题含有django的全部文章列表。

    article_list = Article.objects.filter(title__contains="django")

    但是当我们定义article_list的时候,Django的数据接口QuerySet并没有对数据库进行任何查询。无论你加多少过滤条件,Django都不会对数据库进行查询。只有当你需要对article_list做进一步运算时(比如打印出查询结果,判断是否存在,统计查询结果长度),Django才会真正执行对数据库的查询(见下例1)。这个过程被称为queryset的执行(evaluation)。Django这样设计的本意是尽量减少对数据库的无效操作,比如查询了结果而不用是计算资源的很大浪费。

    for article in article_list:
       print(article.title)

    在例1中,当你遍历queryset(article_list)时,所有匹配的记录会从数据库获取。这些结果会载入内存并保存在queryset内置的cache中。这样如果你再次遍历或读取这个article_list时,Django就不需要重复查询了,这样也可以减少对数据库的查询。

  6. 如何给基于类的视图(CBV)使用装饰器

    需要借助django.utils模块的method_decorator方法实现,它还支持decorators列表, 如下所示:

    from django.utils.decorators import method_decorator

    decorators = [login_required, check_user_permission]


    @method_decorator(decorators, name='dispatch')
    class ArticleCreateView(CreateView):
       model = Article
       form_class = ArticleForm
       template_name = 'blog/article_manage_form.html'
  7. 基于类的视图(CBV)时get_queryset, get_context_data和get_object方法的作用

    get_queryset()方法

    正如其名,该方法可以返回一个量身定制的对象列表。当我们使用Django自带的ListView展示所有对象列表时,ListView默认会返回Model.objects.all()。

    # Create your views here.
    from django.views.generic import ListView
    from .models import Article

    class IndexView(ListView):

       model = Article

    然而这可能不是我们所需要的。当我们希望只展示作者自己发表的文章列表且按文章发布时间逆序排列时,我们就可以通过更具体的get_queryset方法来返回一个我们想要显示的对象列表。

    # Create your views here.
    from django.views.generic import ListView
    from .models import Article
    from django.utils import timezone

    class IndexView(ListView):

       template_name = 'blog/article_list.html'
       context_object_name = 'latest_articles'

       def get_queryset(self):
           return Article.objects.filter(author = self.request.user).order_by('-pub_date')

    get_context_data()

    get_context_data可以用于给模板传递模型以外的内容或参数,非常有用。例如现在的时间并不属于Article模型。如果你想把现在的时间传递给模板,你还可以通过重写get_context_data方法(如下图所示)。因为调用了父类的方法,

    # Create your views here.
    from django.views.generic import ListView
    from .models import Article
    from django.utils import timezone

    class IndexView(ListView):

       queryset = Article.objects.all().order_by("-pub_date")
       template_name = 'blog/article_list.html'
       context_object_name = 'latest_articles'

       def get_context_data(self, **kwargs):
           context = super().get_context_data(**kwargs)
           context['now'] = timezone.now() #只有这行代码有用
           return context

    get_object()方法

    DetailView和EditView都是从URL根据pk或其它参数调取一个对象来进行后续操作。下面代码通过DetailView展示一篇文章的详细信息。

    # Create your views here.
    from django.views.generic import DetailView
    from django.http import Http404
    from .models import Article
    from django.utils import timezone

    class ArticleDetailView(DetailView):

       queryset = Article.objects.all().order_by("-pub_date") #等同于model = Article
       template_name = 'blog/article_detail.html'
       context_object_name = 'article'

     

    然而上述代码可能满足不了你的需求。比如你希望一个用户只能查看或编辑自己发表的文章对象。当用户查看别人的对象时,返回http 404错误。这时候你可以通过更具体的get_object()方法来返回一个更具体的对象。代码如下:

    from django.views.generic import DetailView
    from django.http import Http404
    from .models import Article
    from django.utils import timezone

    class ArticleDetailView(DetailView):

       queryset = Article.objects.all().order_by("-pub_date")
       template_name = 'blog/article_detail.html'
       context_object_name = 'article'

       def get_object(self, queryset=None):
           obj = super().get_object(queryset=queryset)
           if obj.author != self.request.user:
               raise Http404()
           return obj
  8. Django的模型继承有哪几种方式? 它们有什么区别以及何时使用它们?

    Django的模型继承有如下3种方式:

    它们的区别如下: Django不会为抽象模型在数据库中生成自己的数据表。父类Meta中的abstract=True也不会传递给子类。如果你发现多模型有很多共同字段时,需使用抽象模型继承。 多表模型继承与抽象模型继承最大的区别在于Django也会为父类模型建立自己的数据表,同时隐式地在父类和子类之间建立一个一对一关系。 如果我们只想改变某个模型的行为方法,而不是添加额外的字段或创建额外的数据表,我们就可以使用代理模型(proxy model)。设置一个代理模型,需要在子类模型Meta选项中设置proxy=True, Django不会为代理模型生成新的数据表。

    1. 抽象模型继承(abstract model)

    2. 多表模型继承(multi-table inheritance)

    3. 代理模型(proxy model)

推荐阅读