1.宏定义的使用有哪些需要注意的地方?宏和inline函数的区别?
宏定义需要注意“边际效应”,参数也要用括号括起来,否则容易导致歧义。
1)宏只是简单的字符替换,inline函数是嵌入到目标代码;
2)宏在预编译时期展开,inline函数在编译时展开;
3)inline函数有类型检查、语法判断等功能,而宏没有;
4)inline函数作为类的成员函数时可以访问类中的private和protected成员,宏不可以。
(C++引入inline函数就是为了解决宏定义的一些缺点,inline函数会在编译阶段将函数体代码复制到调用处,省去了中断调用
的开销,但是不能把所有的函数都作为inline函数,因为这是以空间换取时间的方式。inline适合代码小于10行,且被频繁调用
的函数功能,函数体内不能有for,while,switch语句。另外,构造函数和析构函数不能是inline函数)
2.数组和指针有什么区别?
数组对应一块内存,数组名指向的地址以及数组容量都是不能改名的,只有数组内容可以改变,而指针指向的地址可以任意更改。
3.设计一个简单的计数系统,如何进行扩容?如何避免雪崩?
计数系统肯定是很频繁的访问,比如微博的粉丝数,转发数等等,需要快速的进行读写,因此可以采用Redis或者memcached,但是
Redis支持更多的数据类型而且可以进行数据持久化,更倾向于Redis。而且Redis的incr,decr是原子操作,非常适合计数系统。
当系统需要处理的数据量超过了单个机器的物理内存就需要使用分布式集群进行扩容,比如Redis集群。
可以设置流量监控,当流量超过警戒值时直接拒掉,实现对系统的保护。当然client调用方也需要配合做些处理,防止不断的请求重试。
4.range和xrange的区别?
range返回的是包含所有元素的list列表,xrange返回的是一个生成器,它们都是可迭代的,生成器在被迭代的时候,元素是逐个
被创建,所以对大序列进行迭代的时候使用xrange效率更高,更省内存。
5.b = [1,3,5,6], b[10:]输出什么?
在l[a:b]的情况下,必须保证a所在的索引位置在前,b所在的索引位置在后,否则返回结果为空数组[]。在l[a:b:step]的情况下,
我们首先要根据a, b的位置来判断方向,a在前,b在后的话,step应该为正,否则应该为负。不符合这些情况的话,则返回空的数组。
也就是说,看a, b的位置来确定方向,不要犯方向性的错误。
>>> l = range(10)
>>> l[9:1:-1]
[9, 8, 7, 6, 5, 4, 3, 2]
6.Python中list作为参数是怎么传递的?
Python中对象传递全部为“引用”,所以函数内对list的修改会影响“形参”。总结,python中对参数的传递是:对于不可变对象,
不会改变对象自身的值,只会创建新的对象,相当于C++的值传递。对于可变对象,相当于C++的引用传递。number,string,tuple都是
不可变对象,list,dict是可变对象。python中一切皆对象。
7.函数默认参数为[]的时候,多次调用会有什么后果?
def foo(a, b=[])这种定义的情况,由于b是个变量,作为默认参数,在函数定义的时候就被计算出来了,它指向[]。而list是可变的,
如果调用该函数对默认参数b做了修改,则下次调用的时候,默认参数的内容就变了,不再是定义函数时的[]了。正确的做法是把默认
参数换成None这个不变对象来实现。
def foo(a, b=None):
if b is None:
b=[]
….
8.copy()和deepcopy()有什么区别?以及a = [1,3,5], b=a这种赋值又有什么区别?
copy()只拷贝对象,不拷贝对象内部的子对象,deepcopy()拷贝对象及子对象,复制后完全独立的两个对象,彼此改变都不会互相影响。
而赋值只是传对象的引用,原对象a如果是可变对象,a发生了改变,将直接反应在赋值后的变量b上。
9.http常见的错误码有哪些?
2XX代表请求成功,200代表服务器已经成功处理,3XX代表重定向,301是永久重定向,302是临时重定向。4XX代表客户端请求错误,
400是服务端无法理解当前请求,401代表未授权,403 forbidden代表请求被禁止,服务器拒绝请求,404代表文档找不到,
405 method not allowed请求的方法不被允许,408请求超时。5XX代表服务器错误,500代表服务器内部出错,无法完成请求,502
代表服务器作为网关或者代理,从上游服务器得到无效响应,504代表无法从上游服务器及时收到请求。