python常见面试问题(一)

python面试常见问题(一)

一. 装饰器

装饰器本质上是一个Python函数,它可以让其他函数在不需要做任何代码变动的前提下增加额外功能,
装饰器的返回值也是一个函数对象。它经常用于有切面需求的场景,比如:插入日志、性能测试、事务处理、
缓存、权限校验等场景。装饰器是解决这类问题的绝佳设计,有了装饰器,我们就可以抽离出大量与函数功能
本身无关的雷同代码并继续重用.

装饰器实际上就是为了给某程序增添功能,但该程序已经上线或已经被使用,那么就不能大批量的修改源代码,这样是不科学的也是不现实的,因为就产生了装饰器,使得其满足:

  1. 不能修改被装饰的函数的源代码
  2. 不能修改被装饰的函数的调用方式
    满足1、2的情况下给程序增添功能

二. 关系型数据库和非关系型数据库:

非关系型数据库优势:

  1. 可扩展性:同样是因为是基于键值对的,数据之间无关系,这样就非常容易扩展
  2. 大数据量,高性能,NoSQL数据库都具有非常高的读写性能,尤其在大数据量下,同样表现优秀。这得益于它的无关系性
  3. 数据库的结构简单

非关系型数据库劣势:

  1. 不提供sql支持,学习和使用成本较高;
  2. 无事务处理;

关系型数据库的优势:

  1. 复杂查询:可以用SQL语句方便地在一个表以及多个表之间做非常复杂的数据查询
  2. 事务支持:使得对于安全性能很高的数据访问要求得以实现
  3. 容易理解:关系模型指的就是二维表格模型
  4. 使用方便:通用的SQL语言使得操作关系型数据库非常方便;

关系型数据库的劣势

  1. 为了维护一致性所付出的巨大代价就是其读写性能比较差;
  2. 固定的表结构;
  3. 高并发读写需求;
  4. 海量数据的高效率读写;

三. cherrypick & git reverse

git cherry-pick可以理解为”挑拣”提交,它会获取某一个分支的单笔提交,并作为一个新的提交引入到你当前分支上。
、当我们需要在本地合入其他分支的提交时,如果我们不想对整个分支进行合并,而是只想将某一次提交合入到本地当前分支上,
那么就要使用git cherry-pick了。

git cherry-pick [<options>] <commit-ish>...

常用options:
    --quit                退出当前的chery-pick序列
    --continue            继续当前的chery-pick序列
    --abort               取消当前的chery-pick序列,恢复当前分支
    -n, --no-commit       不自动提交
    -e, --edit            编辑提交信息


git cherry-pick 2555c6e

当cherry-pick时,没有成功自动提交,这说明存在冲突,因此首先需要解决冲突,
解决冲突后需要git commit手动进行提交:

$ git commit 
[branch1 790f431] [Description]:branch2 commit 2
 Date: Fri Jul 13 18:36:44 2018 +0800
 1 file changed, 1 insertion(+)
 create mode 100644 only-for-branch2.txt

或者git add .后直接使用git cherry-pick --continue继续。

git reset --hard HEAD~
git cherry-pick -n 23d9422
git cherry-pick -e 23d9422
git cherry-pick --quit
git cherry-pick --abort
git cherry-pick master

# 如果在git cherry-pick后加一个分支名,则表示将该分支顶端提交进cherry-pick
$ git cherry-pick master

在这里插入图片描述

1,commit  之前的撤销


未添加至暂存区的撤销(add 之前)
git status
git checkout .


已添加至暂存区的撤销(add 之后,有或者没有commit操作都可以执行)
git reflog
git reset --hard  bca6882(relog 中展示的commitId)



2,push之后的撤销

(
git add .

git commit -m "commit"

git  push  origin brandname
)
等一系列操作后的撤销


不想将本次的操作生效


git revert  commitId(提交的id)


git push origin brandname

此次操作就会撤销掉上一次的push



在这个分支上,会生成一条revert 的提交记录


revert 是负负得正,什么意思呢,就是说第一次revert的时候,
上一次push的命令就失效了,再一次revert 后,会回退到之前的之前的状态,


详细的介绍一下

比如我操作一个文件UserController.java
 
 将userName 改为username 经过一系列的git操作
 git add .
 git commit -m "commit"
 git push orgin 
 后,再进行git revert commitId
 再进行git push origin branchname
 userName 还是userName,


如果我再revert 的时候,
git revert
git push origin branchname
将userName 还是改为username.

总结为:

git revert 为奇数时生效,为偶数时,失效

3,git 回滚:
将git 回滚到某一次commit操作,在该commitId之前的操作,将全部失效(此方法不建议使用,有风险),

git reset --hard commitId


git push  origin branchname --force   (强制覆盖)

因为是不可逆的,不建议使用


git reflog
git reset --hard bca6882(relog 中展示的commitId)
git push origin branchname --force

git revert commitId
git push origin branchname

二者区别:
revert 是放弃指定提交的修改,但是会生成一次新的提交,需要填写提交注释,以前的历史记录都在;
reset 是指将HEAD指针指到指定提交,历史记录中不会出现放弃的提交记录。

Git中tag的用法及作用
 

首先说一下作用:Git 中的tag指向一次commit的id,通常用来给开发分支做一个标记,如标记一个版本号。

下面就说一下具体的用法:
1.添加标签: git tag -a version -m "note" commitId
注解:git tag 是打标签的命令,-a 是添加标签,其后要跟新标签号,-m 及后面的字符串是对该标签的注释。
2.提交标签到远程仓库
:git push origin -tags注解:就像git push origin master 把本地修改提交到远程仓库一样,-tags可以把本地的打的标签全部提交到远程仓库。
3.删除标签:git tag -d

version注解:-d 表示删除,后面跟要删除的tag名字
4.删除远程标签:git push origin :refs/tags/version注解:就像git push origin :branch_1 可以删除远程仓库的分支branch_1一样, 冒号前为空表示删除远程仓库的tag。
5.查看标签:git tag或者git
 tag -l

git tag -a version -m "note" commitId
git show version
git push or --tags
git tag -d version
git push or :refs/tags/version

$ git checkout mywork
$ git rebase origin

git add -u
git rebase --continue
git rebase --abort

四. es机制

Lucene实现快速搜索的核心就是倒排索引,那什么是倒排索引(单词到文档id的关联关系)一个字段有一个自己的倒排索引。18,20这些叫做term,而[1,3]就是posting list。Posting list就是一个int的数组,
存储了所有符合某个term的文档id和term Index
假设我们有很多个term,比如:
Carla,Sara,Elin,Ada,Patty,Kate,Selena
如果按照这样的顺序排列,找出某个特定的term一定很慢,因为term没有排序,需要全部过滤一遍才能找出特定的term。排序之后就变成了:
Ada,Carla,Elin,Kate,Patty,Sara,Selena
这样我们可以用二分查找的方式,比全遍历更快地找出目标的term。这个就是 term dictionary。有了term dictionary之后,可以用 logN 次磁盘查找得到目标。但是磁盘的随机读操作仍然是非常昂贵的(一次random access大概需要10ms的时间)。
所以尽量少的读磁盘,有必要把一些数据缓存到内存里。但是整个term dictionary本身又太大了,无法完整地放到内存里。于是就有了term index。term index有点像一本字典的大的章节表。比如:
A开头的term ……………. Xxx页
C开头的term ……………. Xxx页
E开头的term ……………. Xxx页
如果所有的term都是英文字符的话,可能这个term index就真的是26个英文字符表构成的了。但是实际的情况是,term未必都是英文字符,term可以是任意的byte数组。而且26个英文字符也未必是每一个字符都有均等的term,比如x字符开头的term可能一个都没有,而s开头的term又特别多。实际的term index是一棵树。

lucene/Elasticsearch就是尽量将磁盘里的东西搬进内存(term index是放在内存里面的),
减少磁盘随机读取次数(同时也利用磁盘顺序读特性),结合各种压缩算法(term index用FST进行压缩, term dictionary压缩),高效使用内存,从而达到快速搜索的特性。

五. flask和django的区别

大大提升开发效率
让应用开发更加规范、拓展性更强
让程序员把更多的精力放在业务逻辑的实现上,而不是重复、而复杂的基础环境上(比如web服务器、底层实现等)

flask的优点:

  1. 小巧、灵活,让程序员自己决定定制哪些功能,非常适用于小型网站。
  2. 对于普通的工人来说将毛坯房装修为城市综合体还是很麻烦的,使用Flask来开发大型网站也一样,开发的难度较大,代码架构需要自己设计,开发成本取决于开发者的能力和经验。

Django:

  1. 大而全,功能极其强大,是Python web框架的先驱,用户多,第三方库极其丰富。
  2. 非常适合企业级网站的开发,但是对于小型的微服务来说,总有“杀鸡焉有宰牛刀”的感觉,体量较大,非常臃肿,定制化程度没有Flask高,也没有Flask那么灵活。

Tornado:

天生异步,性能强悍是 Tornado 的名片,然而 Tornado 相比 Django 是较为原始的框架,
诸多内容需要自己去处理。当然,随着项目越来越大,框架能够提供的功能占比越来越小,更多的内容需要团队自己去实现,而大项目往往需要性能的保证,这时候 Tornado 就是比较好的选择。Tornado项目代表:知乎

六. 微服务和分布式

集群是个物理形态,分布式是个工作方式。
分布式:一个业务分拆多个子业务,部署在不同的服务器上
集群:同一个业务,部署在多个服务器上
分布式中的每一个节点,都可以做集群。而集群并不一定就是分布式的。

分布式是以缩短单个任务的执行时间来提升效率的,而集群则是通过提高单位时间内执行的任务数来提升效率。

好的设计应该是分布式和集群的结合,先分布式再集群,具体实现就是业务拆分成很多子业务,然后针对每个子业务进行集群部署,
这样每个子业务如果出了问题,整个系统完全不会受影响

微服务是一种架构风格,一个大型复杂软件应用由一个或多个微服务组成。系统中的各个微服务可被独立部署,各个微服务之间是松耦合的。每个微服务仅关注于完成一件任务并很好地完成该任务。
在所有情况下,每个任务代表着一个小的业务能力。

集群模式是不同服务器部署同一套服务对外访问,实现服务的负载均衡。区别集群的方式是根据部署多台服务器业务是否相同。
注:集群模式需要做好session共享,确保在不同服务器切换的过程中不会因为没有获取到session而中止退出服务。
一般配置Nginx*的负载容器实现:静态资源缓存、Session共享可以附带实现,Nginx支持5000个并发量。

七. 快排 & 冒泡排序的时间复杂度

快排在最糟糕得情况下时间复杂度是O(n²),平均的复杂度是O(nlogn),
这里的n和logn, 分别代表了调用栈的高度,和完成每层的时间,在a取
数组的第一项时候,是最糟的情况,完成每层需要的时间是n,栈的高
读是n,时间复杂度就是n²,当取中间的值得时候,完成每层的时间是
n,但是调用栈的高度变成了logn,所以这个时候时间复杂度是nlogn

退出服务。
一般配置Nginx*的负载容器实现:静态资源缓存、Session共享可以附带实现,Nginx支持5000个并发量。

七. 快排 & 冒泡排序的时间复杂度

快排在最糟糕得情况下时间复杂度是O(n²),平均的复杂度是O(nlogn),
这里的n和logn, 分别代表了调用栈的高度,和完成每层的时间,在a取
数组的第一项时候,是最糟的情况,完成每层需要的时间是n,栈的高
读是n,时间复杂度就是n²,当取中间的值得时候,完成每层的时间是
n,但是调用栈的高度变成了logn,所以这个时候时间复杂度是nlogn

冒泡排序的时间复杂度是O(n^2)

  • 3
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值