宣布一个事情,那就是我找到工作了!
还是做openstack的,我比较欣慰,我不知道自己适不适合做openstack,但是我肯定不喜欢做7*24的系统运维,我一点都不喜欢加班,我更加鄙视值夜班。也许就是命吧,经历那么多次面试,能进入实习公司学习openstack,虽然我离开了99,但是我觉得做这门会比其他运维好多了,学习压力至少少了一部分,什么各种乱七八糟的数据库我也不用太花时间了,各种复杂的应用服务器软件我也许不需要管。我的重点就是openstack和python,甚至ansible或salt,再用一些Linux基本的服务软件和shell,现在对我这个应届生来说,最大的困难就是服务器硬件设备本身了,这一点我有点难搞!
这次我进的是南京一个很小的创业公司,去年才成立,不是我没有野心去幻想大公司了,而是遭遇到了失败,或者说此时的心气已经没了。在面小公司之前,春招我也面过苏宁,上午很easy,下午一个是笑都不笑的面庞,表现很差,算了吧,进不去就进不去,我也不想做那种没完没完了的工作。如果小公司发展好了,我就是元老,几年后也就是技术总监,如果发展不好就会倒闭,我就又要找工作了,我一定要有随时准备面试的意识呀,我怕到时候压力一来,没做准备,容易扛不住!现在看来,运维真的是一个屌丝行业,运维开发才是主流,趁还有时间,我这python必须好好学了。
有段时间没写博客了,其实这篇面经也是整理很久了,不知道为什么我比较懒,现在才发出来,签了三方协议后,说玩也没有玩,反正就是偏向实践的学习了,理论方面有些放松。以后上班了就不再是系统的学习,而是遇到问题再学习,那时候的压力和急性子就是让人失望了。
不知道接下来还会遇到什么坎,希望勤于思考吧...
1、求10次以内的斐波那契数列,初始值是0
答:
def foo(list,num):
if num == 1:
list.append(0)
elif num == 2:
foo(list,1)
list.append(1)
elif num > 2:
foo(list,num-1) ##从10一直遍历到0为止,才执行下一句话
list.append(list[-1]+list[-2]) ##从倒数第1个,倒数第2个
mylist = []
foo(mylist,10)
print (mylist) ##输出[0, 1, 1, 2, 3, 5, 8, 13, 21, 34]
2、合并两个有序列表?
答:思想就是制造空列表,再填数据,这个方法我记得最熟了
list1 = [1,3,5]
list2 = [2,4,6,8]
temp = []
for i in range(len(list1)):
if list1[i] not in temp:
temp.append(list1[i])
for j in range(len(list2)):
if list2[j] not in temp:
temp.append(list2[j])
temp.sort() ##这里就不需要赋值了
print ("合并后的列表是",temp)
3、列表和字符串如何相互转换?
答:>>> str1 = 'abcdef'
>>> list(str1)
['a', 'b', 'c', 'd', 'e', 'f']
>>> mylist = list(str1)
>>> ''.join(list(mylist)) ##引号之间不加任何东西,结果就直接粘在一起,注意有一个点,点与单引号之间没有空格
'abcdef'
>>> '->'.join(list(mylist)) ##单引号之间加入任意字符,那么字符串结果就是以连接符构成的
'a->b->c->d->e->f'
4、分析a、b、c、d的值?
>>> a = [1, 2, 3, 4, ['a', 'b']]
>>> b = a ##赋值,就是把a对象的引用(地址)传给b,b相当于是a的标签
>>> import copy
>>> c = copy.copy(a) ##浅拷贝:只拷贝外围的对象的值,意思说外围值不会发生变化,以后内围对象的值随a的变化而变化
>>> d = copy.deepcopy(a) ##深拷贝,外围对象和內围对象的值都进行拷贝,以后都不会发生变化。
>>> a.append(5)
>>> a[4].append('c')
答:>>> print ('a = ', a)
a = [1, 2, 3, 4, ['a', 'b', 'c'], 5]
>>> print ('b = ', b)
b = [1, 2, 3, 4, ['a', 'b', 'c'], 5]
>>> print ('c = ', c)
c = [1, 2, 3, 4, ['a', 'b', 'c']]
>>> print ('d = ', d)
d = [1, 2, 3, 4, ['a', 'b']]
5、select、poll、epoll之间的区别?(反正我是记不住的)
答:select的几大缺点:
(1)每次调用select,都需要把fd集合从用户态拷贝到内核态,这个开销在fd很多时会很大
(2)同时每次调用select都需要在内核遍历传递进来的所有fd,这个开销在fd很多时也很大
(3)select支持的文件描述符数量太小了,默认是1024
poll改善了第三个缺点,epoll改善了三个缺点。
参考文档:http://www.cnblogs.com/Anker/p/3265058.html
6、Linux系统的CPU和内存使用率比较高怎么办?(居然这个问题问开发,果然是大厂,就是叼,就算我运维我一时也拿不出最好的解决办法,这不是一件容易的事情)
答:(1)用top命令查看哪个进程占用CPU高,[root@python ~]# top -b -n 1 >top.txt ## -b bacth mode,-n 1次循环
(2)用top -H -p pid命令查看进程内各个线程占用的CPU百分比
(3)查看这个线程所有系统调用所花费时间 strace -p 【线程ID】
(4)使用nice命令降低该进程任务的优先级
参考文档:http://blog.sina.com.cn/s/blog_48eef8410101fl4p.html
7、Linux中进程A能否直接访问进行进程B?为什么?(我擦,拓麻这种问题太底层了,不过是操作系统概念,说到linux就反而觉得太高深了)
答:显然不能。(1)B进程为避免破坏数据的一致性,可能有互斥锁。(2)A与B的进程通信需要一些手段如消息队列、共享内存、socket、信号量、管道等实现。(3)A进程的三态(运行、就绪、阻塞)都需要CPU来调度,而调度又有一些算法(先来先服务、最高优先级、最短时间优先)才能来实现进程的状态转换,如果进程B在使用CPU,A进程就只能阻塞,那么A进程又怎么能访问B呢。
8、如何实现对cinder进行备份?(这个被问到过,想了半天说快照,其实错了)
答:(1)首先快照不是备份,没有冗余作用,只是用来恢复某个时间点的状态,如果原有卷挂掉,卷也是不能用的。因为快照要求卷是available的(即不能被挂载),所以一旦原有卷做了快照,是不能删除原有卷的,必须先删除其关联的快照才行。在快照的基础上,再进行创建volume(如果基于快照创建了硬盘,快照删除不掉)。快照命令:cinder snapshot-list
参考文档:http://blog.csdn.net/hhp_hhp/article/details/49175101
(2)备份前,卷需要是available状态(即不能被挂载),备份一旦完成,对卷就不具有依赖性。cinder backup-create
(3)使用后端驱动进行备份,比如swift或NFS共享存储,块存储节点写入数据,而后上传到NFS服务端(局域网中的另一个节点)。
(4)目前Freezer已正式引入OpenStack,能够进行数据库和nova实例、cinder卷的备份。
参考文档:http://www.aixchina.net/Article/159885
9、某公司系统突然发生访问异常,经程序员排查确定程序里没有死循环和定时任务等,该线上系统采用的是nginx+tomcat方式部署,现在让你快速分析系统最有可能的异常原因,后期防范这种异常可以采用什么方案。其他信息和答题要求如下:
(1)该线上系统周一到周五压力较高,周六周日压力较低;
(2)异常发生在周日;
(3)外界只能通过nginx访问到系统,不能通过tomcat直接访问;
(4)系统分配给tomcat的内存被耗尽了;
(5)nginx已经记录了详细的访问日志;
(6)定位异常原因的主要操作步骤和主要命令写出来;
(7)防范方案的原理和主要命令要写出来
分析:(1)周一周五压力高,说明访问量和负载比较大,用户人群多,但是周末压力很小,异常却发生在周末,说明不是并发连接数受限的问题,nginx和数据库肯定还撑得住。
(2)外界只能通过Nginx代理到tomcat,tomcat自身不开放8080端口,这一点是完全可以的,让tomcat专心处理动态页面
(3)系统分配给tomcat的内存用光了,这句话不太好理解,是说tomcat内存利用率高达95%以上吗?按理说服务器的内存一般都是够的,那么内存使用率很高,不知道CPU使用率高不高,使用top命令查看一下,另外查杀相应的僵死进程。
(4)awk '{arr[$1++]}END {for i in arr {print i ,arr[i]}}' nginx.log 统计nginx每个IP的访问人数,判断有没有恶意攻击,另外分析服务
器响应的状态码,这一点可能是排错的关键,如果都是200 OK或则304都没啥大问题,。
10、linux下的压力测试工具有哪些?注意事项有什么?
答:(1)webbench、ab:访问web服务器的压力测试
1、压力及性能测试工作应该放到产品上线之前,而不是上线以后;
2、测试时并发应当由小逐渐加大,比如并发100时观察一下网站负载是多少、打开页面是否流畅,并发200时又是多少、网站打开缓慢时并发是多少、网站打不开时并发又是多少;
3、更详细的进行某个页面测试,如电商网站可以着重测试购物车、推广页面等,因为这些页面占整个网站访问量比重较大。
备注:webbench 做压力及性能测试时,该软件自身也会消耗CPU和内存资源,为了测试准确,建议将 webbench安装在其他的服务器上,已达到测试数据更加精确
(2)mysqlslap对数据库的并发连接测试、sysbench对磁盘IO进行压力测试,两者可以结合起来。
参考文档:http://www.cnblogs.com/chenmh/p/5866058.html
(3)除了这些之外,还可以说系统性能测试命令,如top、vmstat、free等常用命令,其实对于uptime命令我始终无法衡量它的上限达到怎样才算不合适?还有top的CPU使用率描述太混乱了!
(4)ipperf测试网络带宽和丢包率,突然想起pstree命令是个好东西 ,找父进程,多线程。[root@kvm ~]# yum -y install psmisc 依赖安装pstree
11、如何在Linux多级目录下,搜索某个关键字?
答:[root@python ppp]# grep -Rn 'mask' ./ ##用grep递归查找,但是find仅仅能够找到该关键字是否存在,暂时不知道如何打印该关键字所在的文件
12、迭代器和生成器?
答:(1)迭代器(iterator)代表一个数据流对象,不断重复调用迭代器的next()方法可以逐次地返回数据流中的每一项,当没有更多数据可用时,next()方法会抛出异常StopIteration。
(2)生成器(generator)也是一个迭代器,但是你只可以迭代他们一次,不能重复迭代,因为它并没有把所有值存储在内存中,而是实时地生成值。Yield是关键字,它类似于return,只是函数会返回一个生成器。对于类似资源的访问控制等场景,生成器显得很实用。其实最好的理解就是,每执行这个函数,yield都会保存结果值,打印的时候全部打印所有结果。
val = False
while not val:
print '这句话的意思是当val变量为假的时候死循环执行!'
def test():
yield "$1000"
13、zabbix如何去监控一个web服务器的性能?
答:监控指标:(1)打开网页的响应时间(2)每秒的下载速度(3)服务器返回的http状态码(4)验证用户密码登录是否成功
14、Python是强类型还是弱类型的语言?(这个东西我肯定要说错)
答:python是强类型。强弱是对类型而言的。强类型,你有一个值之后这个值是什么类型是确定的,比如n='1',n的类型是确定的(字符串),因此你不能在Python做n='3'm=n+1运算。而弱类型就不是这样的,值的类型可以在需要的时候再去确定,比如PHP里面你可以$n='3'; $m=$n+1,运算的时候'3'就可以当作整型来进行计算。
参考文档:https://segmentfault.com/q/1010000002230156
15、python的动态性体现在哪?
答:(1)定义变量的时候无需指定它的数据类型,根据运行时具体情况确定。
(2)类class不提供private私有属性的关键字;无法定义常量;函数参数无类型
(3)python中的namespace是可以动态变化的,类的成员,类实例的成员都可以动态添加
16、python的namespace有几种?
答:(1)locals:函数内部的名字空间,一般包括函数的局部变量以及形式参数。
(2)enclosing function:在嵌套函数中外部函数的名字空间。
(3)globals:当前的模块空间,模块就是一些py文件。也就是说,globals()类似全局变量。
(4)__builtins__: 内置模块空间,也就是内置变量或者内置函数的名字空间。比如len()等函数的命名空间就是BIF命名空间
参考文档:http://www.jianshu.com/p/7f3fdd41096f
17、awk实现下列文本的转换?
[root@ssd tmp]# cat 5.sh
1
D
2
E
3
V
[root@ssd tmp]# cat 5.sh |awk '{if(NR%2!=0)ORS=" ";else ORS="\n";print}'
1 D
2 E
3 V
18、怎么实现迭代器?迭代器比for循环有什么优势吗?(这个东西我怎么就记不住呢!)
答:迭代器和经典for循环的索引访问相比并无优势,反而丢失了索引值(可以使用内建函数enumerate()找回这个索引值)。但对于无法随机访问的数据结构(比如set)而言,迭代器是唯一的访问元素的方式。
next方法:返回迭代器的下一个元素
__iter__方法:返回迭代器对象本身
参考文档:http://www.cnblogs.com/kaituorensheng/p/3826911.html
19、python的三目运算符有吗? 怎么用一行代码实现三目运算?
答:python没有三目运算符。使用If-else可以模拟三目运算
>>> x, y = 50, 25
>>> small = x if x < y else y
>>> small
25
>>>
20、磁盘利用率快用尽时,如何看哪个目录使用的最多?
答:(1)find命令:find / -type d -size +2G -print
(2)du -sh /etc ##×××了,这个命令没记住,记成df了
21、python多线程与多进程有何区别?
答:多线程用来并行处理多个任务,以提高处理效率,在python中导入threading模块。join()方法的作用是必须在子线程运行完毕之后,父线程才能运行,即父线程被阻塞,因为如果父线程一旦运行完毕,子线程就不会再运行了。
(1)多线程可以共享全局变量(内存地址空间),当然锁问题也变成麻烦了;多进程独占资源,进程通信变得就比较麻烦了。
(2)多线程中,所有子线程的线程号相同;多进程中,不同的子进程进程号不同
(3)多线程只使用一颗CPU内核,属于IO密集型,比如在读取文件以及网络IO的时候使用多线程;多进程充分发挥多核的优势,属于计算密集型执行任务。
22、简要说明nova compute创建实例的大体步骤?(这个问题总结很多遍了,但是下面是最简单的描述)
答:(1)nova compute准备创建虚拟机实例的资源,比如根据flavor配置使用多大内存、多少颗CPU、多大磁盘?
(2)nova 从glance下载镜像文件,会对计算节点的_base目录进行缓存
(3)定义实例的XML文件,描述实例的元数据信息,以便下次可以正常启动
(4)nova请求neutron获取虚拟网卡的参数,实例得到诸如IP地址、MAC地址的信息,而后引导虚拟机。
23、虚拟机迁移如何防止调度到源节点的机制?
答:nova-compute 在做 migrate 的时候会检查目标节点,如果发现目标节点与源节点相同,会抛出 UnableToMigrateToSelf 异常。Nova-compute 失败之后,scheduler 会重新调度,由于有RetryFilter,会将之前选择的源节点过滤掉,这样就能选到不同的
计算节点了。
24、计算节点宕机,虚拟机实例还能运行吗?如果不能,怎么恢复呢?
答:虚拟机实例当然不能运行,如果只是nova-compute进程已经挂掉,Rebuild 可以恢复损坏的 instance。
但是计算节点宕机就不行,可以把虚拟机实例撤离到正常的计算节点上去。Evacuate可在 nova-compute 无法工作的情况下将节点上的instance 迁移到其他计算节点上。但有个前提: Instance 的镜像文件必须放在共享存储上。
流程:(只能在后台执行)
执行命令nova evacuate 主机名 --no-shared-storage -> 消息下发到nova-api -> nova-schedule筛选好主机 -> nova-compute分配资源,使用共享存储上的镜像文件 -> 启动instance
参考文档:http://www.mamicode.com/info-detail-1608057.html
25、网卡绑定的工作模式?(这个问题曾经在去年6月份才学过这点,现在都忘了,只记得3种,而且平衡二字又说不出来)
答:如果不同主机的网卡绑定的话,交换机也要进行配置链路聚合才行。总共7种,主要3种
(1)平衡模式
(2)主动备份
(3)广播
bond的好处:(1)提高整体带宽(2)负载均衡
参考文档:http://alanwu.blog.51cto.com/3652632/1095566
26、MySQL 5.5是单线程复制还是多线程复制?如果有大量的DML语句,如何解决主从延迟同步问题?(卧了个槽,这种
问题从来没思考过,又差点栽在数据库集群上了)
答:mysql从5.6才开始支持多线程复制。DML(一瞬间有点懵逼,反应好久才想起来是数据库操作语言)就是Insert、update等。
呵,我是记得到被思必驰狠狠虐过,固态硬盘做RAID阵列和分库分表记得最熟了。
MySQL的高可用知道多少?MMM、MHA架构熟悉吗?(日了狗,我又不是DBA,只听说过,又没做过)
答:只知道一主多从中,对从集群的HAProxy+Keepalived架构。
27、Linux Bridge与Open Vswitch有什么区别?(这段时间我没有全身心放在openstack上,知识尚缺,以后还会补充)
答:(1)基于vlan的隔离方式不同,ovs使用flow rule实现外部vlan以及内部vlan的转换
(2)iptables只能用于linux bridage而非OVS bridge,linux bridge 不支持GRE,但OVS支持。
(3)OVS的patch port用来连接集成网桥br-int和隧道网桥br-tun,而linux bridage使用veth对连接br-int和外部网桥br-eth1
(4)OVS的功能应该强于Linux Bridge,否则官网使用Linux Bridge,但是很多企业都用的是OVS。根据测试结果,Linux Bridge的性能(如网络吞吐量、虚拟之间的文件传输速度)略强于OVS。
(5)OVS 将各种功能都原生地实现在其中,而Linux Bridge依赖各种其他模块来实现各种功能。
参考文档:http://www.cnblogs.com/sammyliu/p/4985907.html
28、数据包流过OVS的过程?(先来个很简单的印象吧,其实OVS的很多桥还是比较麻烦的,脑壳里一定要想那个拓扑图)
答:1 VM实例instance的网络协议栈产生一个数据包并发送至实例内的虚拟网络接口VNIC,就是instance中的eth0.
2 这个数据包会传送到物理节点上的VNIC接口,就是vnet接口。
3 数据包从vnet NIC出来,到达桥(虚拟交换机)br100上.
4 数据包经过交换机的处理,从物理节点上的物理接口发出,如物理节点上的eth0.
5 数据包从eth0出去的时候,是按照物理节点上的二层交换机以及默认网关操作的,这个时候该数据包其实已经不受OVS的控制了
29、python要求输入一个列表,其中值为整数,输出为偶数,并且偶数所在的索引值也是偶数,例:输入[1,3,2,5,4,6],输出[2,4]
答:这个最大问题是要求随机输入,那么输入的列表就变成字符串型了,必须想个办法替换掉列表外边的单引号,使用eval方法
list1 = eval(input("请输入一个列表:")) ##如果不加eval.那么list1就是<str>类型的。
list2 = [] ##eval将字符串str当成有效的表达式来求值并返回计算结果
def fun(list1):
count = len(list1)
for i in range(count):
if list1[i] % 2 == 0 and i%2 == 0:
list2.append(list1[i])
print ('输出后的列表是:',list2)
return list2
fun(list1)
30、分析简单代码,求输出结果。
class p(object):
attr = 'a'
class c1(p):
pass
class c2(p):
attr = 'd'
class c3(p):
pass
print ('第1次',p.attr,c1.attr,c2.attr)
c1.attr = 'b'
print ('第2次',p.attr,c1.attr,c2.attr)
p.attr= 'c'
print ('第3次',p.attr,c1.attr,c2.attr,c3.attr)
答:#第1次 a a d
#第2次 a b d
#第3次 c b d c