面试题_day0213
1.python是如何进行内存管理的?
python的内存管理,主要涉及到以下的3个方面: 1.python内部使用引用计数,来保持追踪内存中的对象,Python内部记录了对象有多少个引用,即引用计数,当对象被创建时就创建了一个引用计数,当对象不再需要时,这个对象的引用计数为0时,它被垃圾回收。 2.那什么是垃圾回收机制呢? 1、当内存中有不再使用的部分时,垃圾收集器就会把他们清理掉。它会去检查那些引用计数为0的对象,然后清除其在内存的空间。
当然除了引用计数为0的会被清除,还有一种情况也会被垃圾收集器清掉:当两个对象相互引用时,他们本身其他的引用已经为0了。 3.Python提供了对内存的垃圾收集机制,但是它将不用的内存放到内存池而不是返回给操作系统。 Python中所有小于256个字节的对象都使用pymalloc实现的分配器,而大的对象则使用系统的 malloc。
另外Python对象,如整数,浮点数和List,都有其独立的私有内存池,对象间不共享他们的内存池。也就是说如果你分配又释放了大量的整数,用于缓存这些整数的内存就不能再分配给浮点数。
2.解释python脚本程序‘__name__’变量及其作用
我们编写模块的时候,是为了给自己或者别人在适当的时候进行调用的,但是我们在编写模块时,也是需要测试的,会写一些测试代码,但是我们想在别人调用时,测试代码不起作用。 为了解决这一问题,python提供了一个系统变量:__name__ __name__有2个取值:当模块是被调用执行的,取值为模块的名字。当模块是直接执行的,则该变量取值为:__main__ 一般的用法: def addFunc(a,b): return a+b if __name__ == '__main__': print('结果:',addFunc(1,1))
3.mysql表中的数据越来越大,请给出优化的简易的优化方案
我们一般的步骤是找问题,再优化: 优化sql的一般步骤(找问题) 1.通过show status了解各种sql的执行频率 2.定位执行效率低的sql语句 3.通过explain分析效率低的sql 4.通过show profile分析sql 5.通过trace分析优化器如何选择执行计划 6.确定问题,采取措施优化 问题优化: 1.优化你的sql和索引; 2.加缓存,memcached,redis; 3.就做主从复制或主主复制,读写分离,可以在应用层做,效率高,也可以用三方工具,第三方工具推荐360的atlas,其它的要么效率不高,要么没人维护; 4.mysql自带分区表,对你的应用是透明的,无需更改代码,但是sql语句是需要针对分区表做优化的,
sql条件中要带上分区条件的列,从而使查询定位到少量的分区上,否则就会扫描全部分区,另外分区表还有一些坑,在这里就不多说了; 5.先做垂直拆分,其实就是根据你模块的耦合度,将一个大的系统分为多个小的系统,也就是分布式系统; 6.水平切分,针对数据量大的表,这一步最麻烦,最能考验技术水平,要选择一个合理的sharding key,为了有好的查询效率,表结构也要改动,做一定的冗余,应用也要改,
sql中尽量带sharding key,将数据定位到限定的表上去查,而不是扫描全部的表
4.简述python的GIL锁
python代码的执行由解释器主循环来控制(虚拟机),python在设计之初,就决定每次在解释器主循环中,同一时刻,只有一个线程。
对python解释器的访问,就是有GIL(全局解释器锁)来控制,正是这把锁,控制了同一时刻,只有一个线程在解释器中。 在多线程环境中,Python 解释器按以下方式执行: 1. 设置GIL 2. 切换到一个线程去运行 3. 运行: a. 指定数量的字节码指令,或者 b. 线程主动让出控制(可以调用time.sleep(0)) 4. 把线程设置为睡眠状态 5. 解锁GIL 6. 再次重复以上所有步骤 锁住全局解释器使得比较容易的实现对多线程的支持,但也损失了多处理器主机的并行计算能力。 但是,不论标准的,还是第三方的扩展模块,都被设计成在进行密集计算任务时,释放GIL。 还有,就是在做I/O操作时,GIL总是会被释放。对所有面向I/O 的程序来说,GIL 会在这个I/O 调用之前被释放,以允许其它的线程在这个线程等待I/O 的时候运行。 如果是纯计算的程序,没有 I/O 操作,解释器会每隔一定时间就释放这把锁,让别的线程有机会执行(这个次数可以通过 sys.setcheckinterval 来调整)。 I/O 密集型的Python 程序比计算密集型的程序更能充分利用多线程环境的好处。
5.多进程开发中,join和daemon的区别
一个程序至少有一个主线程,主线程启动子线程后,它们之间并没有隶属关系。主线程和子线程执行是并行的,相互独立。
主线程执行完毕后默认不等子线程执行结束就接着往下走了,如果有其他程序就会运行另外的程序,如果没有就等待子线程执行完成后结束程序。
主线程创建一个子线程后,如果子线程调用join()方法,主线程会在调用的地方等待,直到该子线程运行完成才会接着往下执行。
setDaemon()方法:在主线程中创建子线程,该子线程调用setDaemon方法后成为主线程的守护线程。这种情况下如果主线程执行结束,那么不管子线程是否完成,一并和主线程退出。
这里基本和join()方法相反。此外,还有个要特别注意的:必须在start() 方法调用之前设置,如果不设置为守护线程,程序会被无限挂起。
其他.mysql数据库查询练习,使用egon老师在周末布置的题目,以下觉得稍绕。
1、查询所有学生的学号,姓名,选课数,总成绩
select sid,sname,选课数,总成绩 from student left join
(select student_id,count(course_id) 选课数,sum(num) 总成绩 from score group by student_id) as t1
on student.sid = t1.student_id;
2.查询物理课程比生物课程成绩高的学生的学号 select wuli_student_id as student_id from (select wuli.student_id as wuli_student_id,wuli.num as wuli_num,shengwu.student_id as shengwu_student_id,shengwu.num as shengwu_num from (select student_id,num from score where course_id = (select cid from course where cname = '物理')) as wuli,(select student_id,num from score where course_id = (select cid from course where cname = '生物')) as shengwu where wuli.student_id = shengwu.student_id ) as total where wuli_num > shengwu_num;
3.查询没有同时选修物理课程和体育课程的学生姓名 select sid,sname from student where sid not in (select student_id from score inner join course on score.course_id = course.cid where cname = '物理' or cname = '体育' group by student_id having count(course_id) >1);
4.查询挂科超过两门(包括两门)的学生姓名和班级 表:score student class 思路:把3张表链接起来,用student_id 分组,count(course_id) >=2 的则是满足需要的。 select student_id,sname,caption from score inner join student on student.sid = score.student_id inner join class on student.class_id = class.cid where num < 60 group by student_id having count(course_id) >=2;
5.查询全部学生都选修了的课程号和课程名 根据course_id分组,如果查询到每个课程选修的学生数= 学生的总数量, select course_id from score group by course_id having count(num) = (select count(sid) from student) ;
6.查询所有学生考出的成绩并按从高到低排序(成绩去重)
select distinct num from score order by num desc;
7.查询平均成绩大于85的学生姓名和平均成绩
select sname,avg(num) from score inner join student on score.student_id = student.sid group by student_id having avg(num) > 85;
8.查询在所有选修了李平老师课程的学生中,这些课程(李平老师的课程,不是所有课程)平均成绩最高的学生姓名 select cid from course inner join teacher on course.teacher_id = teacher.tid and tname = '李平老师'; 先得到选修李平老师课程的学生, select sname,平均成绩 from student inner join (select student_id,avg(num) 平均成绩 from score where course_id in (select cid from course inner join teacher on course.teacher_id = teacher.tid and tname = '李平老师') group by student_id order by avg(num) desc limit 1) as t1 on student.sid = t1.student_id ;