一、Python基础
在Django2.0之前外键不需要只需要models.ForeignKey(‘外键关联’)就可以实现了
但是在Django发布2.0之后,需要在这个方法里添加另外一个参数 on_delete=models.CASCADE,否则会报错误
1、一行代码实现1–100之和?
答:sum(range(1,101))
逻辑外键是通过代码去限制表之间的关联,物理外键是通过mysql数据库硬性限制表之间的关联
2、如何在一个函数内部修改全局变量?
答:利用global 修改全局变量
3、列出5个Python标准库?
答:
os:提供了不少与操作系统相关联的函数
sys:通常用于命令行参数
re:正则匹配
math:数学运算
datetime:处理日期时间
Pillow 图像
4、字典如何删除键和合并两个字典?
答:del和update方法
Infor = {‘name’:’aaa’, ‘sex’:’nan’}
del infor[‘name’] #删除键
Infor2 = {‘name’:’aaa’}
Infor.update(infor2) #字典合并
5、谈下python的GIL?
答:GIL 是python的全局解释器锁,同一进程中假如有多个线程运行,一个线程在运行python程序的时候会霸占python解释器(加了一把锁即GIL),使该进程内的其他线程无法运行,等该线程运行完后其他线程才能运行。如果线程运行过程中遇到耗时操作,则解释器锁解开,使其他线程运行。所以在多线程中,线程的运行仍是有先后顺序的,并不是同时进行。
多进程中因为每个进程都能被系统分配资源,相当于每个进程有了一个python解释器,所以多进程可以实现多个进程的同时运行,缺点是进程系统资源开销大
6、python实现列表去重的方法?
答:先通过集合去重(集合元素具有唯一性),在转列表
7、fun(args,**kwargs)中的args,kwargs什么意思?
答:*args和kwargs主要用于函数定义,可以实现将不定数量的参数传递给一个函数。*args用来发送一个非键值对的可变数量的参数列表给一个函数。而**kwargs可以将不定长度的键值对作为参数传递给一个函数。
8、python2和python3的range(100)的区别?
答:python2返回列表,python3返回迭代器,节约内存。
9、一句话解释什么样的语言能够用装饰器?
答:函数可以作为参数传递的语言,可以使用装饰器。
10、python内建数据类型有哪些?
答:整型–int
布尔型–bool
字符串–str
列表–list
元组–tuple
字典–dict
11、简述面向对象中__new__和__init__区别?
答:1、__new__至少要有一个参数cls,代表当前类,此参数在实例化时由Python解释器自动识别
2、__new__必须要有返回值,返回实例化出来的实例。
3、__init__有一个参数self,就是这个__new__返回的实例,__init__在__new__的基础上可以完成一些其它初始化的动作,__init__不需要返回值
4、如果__new__创建的是当前类的实例,会自动调用__init__函数,通过return语句里面调用的__new__函数的第一个参数是cls来保证是当前类实例,如果是其他类的类名,那么实际创建返回的就是其他类的实例,此时就不会调用当前类的__init__函数,也不会调用其他类的__init__函数。
12、简述with方法打开处理文件帮我我们做了什么?
答:打开文件在进行读写的时候可能会出现一些异常状况,如果按照常规的f.open
写法,我们需要try,except,finally,做异常判断,并且文件最终不管遇到什么情况,都要执行finally f.close()关闭文件,with方法帮我们实现了finally中f.close
13、列表[1,2,3,4,5],请使用map()函数输出[1,4,9,16,25],并使用列表推导式提取出大于10的数,最终输出[16,25]?
答:map()函数第一个参数是fun,第二个参数是一般是list,第三个参数可以写list,也可以不写,根据需求。
map()是 Python 内置的高阶函数,它接收一个函数 f 和一个 list,并通过把函数 f 依次作用在 list 的每个元素上,得到一个新的 list 并返回。
14、python中生成随机整数、随机小数、0–1之间小数方法?
答:随机整数:random.randint(a,b),生成区间内的整数
随机小数:习惯用numpy库,利用np.random.randn(5)生成5个随机小数
0-1随机小数:random.random(),括号中不传参
15、避免转义给字符串加哪个字母表示原始字符串?
答:r , 表示需要原始字符串,不转义特殊字符。
16、
17、python中断言方法举例?
答:assert()方法,断言成功,则程序继续执行,断言失败,则程序报错
18、数据表student有id,name,score,city字段,其中name中的名字可有重复,需要消除重复行,请写sql语句?
答:select distinct name from student
19、10个Linux常用命令?
答:ls pwd cd touch rm mkdir tree cp mv cat more grep echo 等
20、python2和python3区别?列举5个?
答:1、Python3 使用 print 必须要以小括号包裹打印内容,比如 print(‘hi’)
Python2 既可以使用带小括号的方式,也可以使用一个空格来分隔打印内容,比如 print ‘hi’
2、python2 range(1,10)返回列表,python3中返回迭代器,节约内存
3、python2中使用ascii编码,python中使用utf-8编码
4、python2中unicode表示字符串序列,str表示字节序列,python3中str表示字符串序列,byte表示字节序列
5、python2中为正常显示中文,引入coding声明,python3中不需要
6、python2中是raw_input()函数,python3中是input()函数
21、列出python中可变数据类型和不可变数据类型,并简述原理?
答:
1、不可变数据类型:数值型、字符串型string和元组tuple
不允许变量的值发生变化,如果改变了变量的值,相当于是新建了一个对象,而对于相同的值的对象,在内存中则只有一个对象(一个地址),如下图用id()方法可以打印对象的id
2、可变数据类型:列表list和字典dict;
允许变量的值发生变化,即如果对变量进行append、+=等这种操作后,只是改变了变量的值,而不会新建一个对象,变量引用的对象的地址也不会变化,不过对于相同的值的不同对象,在内存中则会存在不同的对象,即每个对象都有自己的地址,相当于内存中对于同值的对象保存了多份,这里不存在引用计数,是实实在在的对象。
22、s = “ajldjlajfdljfddd”,去重并从小到大排序输出"adfjl"?
答:
23、用lambda函数实现两个数相乘?
答:
24、字典根据键从小到大排序
dict={“name”:“zs”,“age”:18,“city”:
“深圳”,“tel”:“1362626627”}?
答:
25、利用collections库的Counter方法统计字符串每个单词出现的次数"kjalfj;ldsjafl;hdsllfdhg;lahfbl;hl;ahlf;h"?
答:
26、字符串a = “not 404 found 张三 99 深圳”,每个词中间是空格,用正则过滤掉英文和数字,最终输出"张三 深圳"?
答:
27、filter方法求出列表所有奇数并构造新列表,a = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]?
答:filter() 函数用于过滤序列,过滤掉不符合条件的元素,返回由符合条件元素组成的新列表。该接收两个参数,第一个为函数,第二个为序列,序列的每个元素作为参数传递给函数进行判,然后返回 True 或 False,最后将返回 True 的元素放到新列表
28、列表推导式求列表所有奇数并构造新列表,a = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]?
答:
29、正则re.complie作用?
答:re.compile是将正则表达式编译成一个对象,加快速度,并重复使用
30、a=(1,)b=(1),c=(“1”) 分别是什么类型的数据?
答:tuple,int,str
31、两个列表[1,5,7,9]和[2,2,6,8]合并为[1,2,2,5,6,7,8,9]?
答:list1 = [1,5,7,9]
list2 = [2,2,6,8]
list1.extend(list2)
list1.sort()
32、用python删除文件和用linux命令删除文件方法?
答:python os.remove(path),linux rm -f /var/log/httpd/access.log
33、log日志中,我们需要用时间戳记录error,warning等的发生时间,请用datetime模块打印当前时间戳 “2018-04-01 11:38:54”
答:datetime.datetime.now().strftime("%Y-%m-%d %H:%M:%S")
34、数据库优化查询方法?
答:1、原始数据预处理(物化视图);
2、命令查询职责分离(数据库读写分离);
3、分布式数据库应用(分库/分表)等技术;
35、正则表达式匹配中,(.)和(.?)匹配区别?
答:表达式 .* 就是单个字符匹配任意次,即贪婪匹配。 表达式 .*? 是满足条件的情况只匹配一次,即最小匹配。
36、[[1,2],[3,4],[5,6]]一行代码展开该列表,得出[1,2,3,4,5,6]?
答:list1 = [para for item in [[1,2],[3,4],[5,6]] for para in item]
37、x=“abc”,y=“def”,z=[“d”,“e”,“f”],分别求出x.join(y)和x.join(z)返回的结果?
答:dabceabcf, dabceabcf
38、举例说明异常模块中try except else finally的相关意义?
答:
try:
# 尝试执行的代码
pass
except 错误类型1: # 下面几句是排除常见的异常,并进行提示等处理
# 针对错误类型1,对应的代码处理
pass
except 错误类型2:
# 针对错误类型2,对应的代码处理
pass
except (错误类型3, 错误类型4):
# 针对错误类型3 和 4,对应的代码处理
pass
…
…
except Exception as result: # 编程中很难一次排除所有的错误,所有用这个语句,其中result是一个变量。这里相当于一个篮子,装了其他所有错误类型
# 打印错误信息
print(“未知类型错误:%s” % result)
else:
# 没有异常才会执行的代码,作为奖励执行的代码
pass
finally:
# 无论是否有异常,都会执行的代码
print(“无论是否有异常,都会执行的代码”)
39、Python有哪些特点和优点?
答:作为一门编程入门语言,Python主要有以下特点和优点:
可解释、具有动态特性、 面向对象、 简明简单、 开源、 具有强大的社区支持
40、深拷贝和浅拷贝之间的区别是什么?
答:深拷贝就是将一个对象拷贝到另一个对象中,这意味着如果你对一个对象的拷贝做出改变时,不会影响原对象。在Python中,我们使用函数deepcopy()执行深拷贝,导入模块copy,如下所示:
import copy
b=copy.deepcopy(a)
而浅拷贝则是将一个对象的引用拷贝到另一个对象上,所以如果我们在拷贝中改动,会影响到原对象。我们使用函数function()执行浅拷贝,使用如下所示:b=copy.copy(a)
41、列表和元组之间的区别是?
答:二者的主要区别是列表是可变的,而元组是不可变的。
42、在Python中如何实现多线程?
答:一个线程就是一个轻量级进程,多线程能让我们一次执行多个线程。我们都知道,Python是多线程语言,其内置有多线程工具包。
Python中的GIL(全局解释器锁)确保一次执行单个线程。一个线程保存GIL并在将其传递给下个线程之前执行一些操作,这会让我们产生并行运行的错觉。但实际上,只是线程在CPU上轮流运行。当然,所有的传递会增加程序执行的内存压力。
43、如何在python中复制对象
答:使用copy包的copy和deepcopy函数。其中,copy 仅拷贝对象本身,而不拷贝对象中引用的其它对象;deepcopy 除拷贝对象本身,而且拷贝对象中引用的其它对象。
44、python的面向对象?
答:类是对象的蓝图和模板,而对象是类的实例。类是抽象的概念,而对象是具体的东西。在面向对象编程的世界中,一切皆为对象,对象都有属性和行为,每个对象都是独一无二的,而且对象一定属于某个类(型)。当我们把一大堆拥有共同特征的对象的静态特征(属性)和动态特征(行为)都抽取出来后,就可以定义出一个叫做“类”的东西。面向对象有三大支柱:封装、继承和多态。
45、什么是元类?
答:同上,我们讲到在python中皆为对象,而元类即是用来创建类的”东西”。类也是元类的实例。而在python中,它们要么是类的实例,要么是元类的实例,除了type。type实际上是它自己的元类。元类主要的用途是用来创建API,比如django的ORM。
46、python的search和match知识点?
答:search和match都在re模块中,match只匹配字符串的开始,如果字符串开始不符合正则表达式,则匹配失败,函数返回None。search匹配整个字符串,直到找到一个匹配。
47、类的初始化:new() 和 init()?
答:new()方法用来实例化最终的类对象,在类创建之前被调用,它在类的主体被执行完后开始执行。
init()方法是在类被创建之后被调用,用来执行其他的一些输出化工作
当我们构造元类的时候,通常只需要定一个init()或new()方法,但不是两个都定义。但是,如果需要接受其他的关键词参数的话,这两个方法就要同时提供,并且都要提供对应的参数签名。
48、类的初始化过程?
答:B类继承A类,在B类自己的基础上可以调用A类所有方法,如果A,B同时拥有init, B会改写A中的init方法,A类的方法失效。
Super函数可以调用A类中的属性,B类中有同名属性时,覆盖A类中的同名属性。但调用函数时,总是先查找它自身的定义,如果没有定义,则顺着继承链向上插座,知道在某个父类中找到为止。
B类 init参数需大于或等于A 父类的init方法,因为super初始化了,参数量为父类参数量。
49、简述Python多线程?
多线程可以共享进程的内存空间,因此要实现多个线程之间的通信相对简单,比如设置一个全局变量,多个线程共享这个全局变量。但是当多个线程共享一个资源的时候,可能导致程序失效甚至崩溃,如果一个资源被多个线程竞争使用,那么对临界资源的访问需要加上保护,否则会处于“混乱”状态,比如银行存100块钱,最终很可能存不到一百块多个线程得到的余额状态都是0,所有操作都是在0上面加1,从而导致错误结果。这种情况下,锁就可以得到用处了。多线程并不能发挥cpu多核特性,因为python解释器有一个gil锁,任何线程执行前必须获得GIL锁,然后每执行100条字节码,解释器就会自动释放GIL锁让别的线程有机会执行。
50、python内存管理?
答:python内部使用引用计数,来保持追踪内存中的对象,Python内部记录了对象有多少个引用,即引用计数,当对象被创建时就创建了一个引用计数,当对象不再需要时,这个对象的引用计数为0时,它被垃圾回收。所有这些都是自动完成,不需要像C一样,人工干预,从而提高了程序员的效率和程序的健壮性。
51、python的filter方法?
答:filter就像map,reduce,apply,zip等都是内置函数,用C语言实现,具有速度快,功能强大等 优点。
用于过滤与函数func()不匹配的值, 类似于SQL中select value != ‘a’
相当于一个迭代器,调用一个布尔函数func来迭代seq中的每个元素,返回一个是bool_seq返 回为True的序列
第一个参数: function or None, 函数或None
第二个参数: sequence,序列
52、.给定一串排好序的列表,打乱这个函数?
答:这个题考了python里的shuffle函数的用法。
import random
list = [1, 2, 3, 4]
random.shuffle(list)
print(list)
53、给定一串字典(或列表),找出指定的(前N个)最大值?最小值?
答:这道题的考点是python内的heapq模块的nlargest() 和 nsmallest(), 而不是min()和max()。这两个函数都能接收关键字参数,用于复杂的结构数据中:
portfolio = [
{‘name’: ‘IBM’, ‘shares’: 100, ‘price’: 91.1},
{‘name’: ‘AAPL’, ‘shares’: 50, ‘price’: 543.22},
{‘name’: ‘FB’, ‘shares’: 200, ‘price’: 21.09},
{‘name’: ‘HPQ’, ‘shares’: 35, ‘price’: 31.75},
{‘name’: ‘YHOO’, ‘shares’: 45, ‘price’: 16.35},
{‘name’: ‘ACME’, ‘shares’: 75, ‘price’: 115.65}
]
cheap = heapq.nsmallest(3, portfolio, key=lambda s: s[‘price’])
expensive = heapq.nlargest(3, portfolio, key=lambda s: s[‘price’])
54、python实现单例模式?(掌握一个)
答:这个题考的是python中对单例模式的理解和运用,有4个方法实现单例模式:
#方法1,实现__new__方法
#并在将一个类的实例绑定到类变量_instance上,
#如果cls._instance为None说明该类还没有实例化过,实例化该类,并返回
#如果cls._instance不为None,直接返回cls._instance
class Singleton(object):
def new(cls, *args, **kw):
if not hasattr(cls, ‘_instance’):
orig = super(Singleton, cls)
cls._instance = orig.new(cls, *args, **kw)
return cls._instance
class MyClass(Singleton):
a = 1
one = MyClass()
two = MyClass()
two.a = 3
print(one.a)
#3
#one和two完全相同,可以用id(), ==, is检测
print(id(one))
#29097904
print(id(two))
#29097904
print(one == two)
#True
print(one is two)
#True
print(’----------------------方法2--------------------------’)
#方法2,共享属性;所谓单例就是所有引用(实例、对象)拥有相同的状态(属性)和行为(方法)
#同一个类的所有实例天然拥有相同的行为(方法),
#只需要保证同一个类的所有实例具有相同的状态(属性)即可
#所有实例共享属性的最简单最直接的方法就是__dict__属性指向(引用)同一个字典(dict)
#可参看:http://code.activestate.com/recipes/66531/
class Borg(object):
_state = {}
def new(cls, *args, **kw):
ob = super(Borg, cls).new(cls, *args, **kw)
ob.dict = cls._state
return ob
class MyClass2(Borg):
a = 1
one = MyClass2()
two = MyClass2()
#one和two是两个不同的对象,id, ==, is对比结果可看出
two.a = 3
print(one.a)
#3
print(id(one))
#28873680
print(id(two))
#28873712
print(one == two)
#False
print(one is two)
#False
#但是one和two具有相同的(同一个__dict__属性),见:
print(id(one.dict))
#30104000
print(id(two.dict))
#30104000
print ‘----------------------方法3--------------------------’
#方法3:本质上是方法1的升级(或者说高级)版
#使用__metaclass__(元类)的高级python用法
class Singleton2(type):
def init(cls, name, bases, dict):
super(Singleton2, cls).init(name, bases, dict)
cls._instance = None
def call(cls, *args, **kw):
if cls._instance is None:
cls._instance = super(Singleton2, cls).call(*args, **kw)
return cls._instance
class MyClass3(object):
metaclass = Singleton2
one = MyClass3()
two = MyClass3()
two.a = 3
print(one.a)
#3
print(id(one))
#31495472
print(id(two))
#31495472
print(one == two)
#True
print(one is two)
#True
print ‘----------------------方法4--------------------------’
#方法4:也是方法1的升级(高级)版本,
#使用装饰器(decorator),
#这是一种更pythonic,更elegant的方法,
#单例类本身根本不知道自己是单例的,因为他本身(自己的代码)并不是单例的
def singleton(cls, *args, **kw):
instances = {}
def _singleton():
if cls not in instances:
instances[cls] = cls(*args, **kw)
return instances[cls]
return _singleton
@singleton
class MyClass4(object):
a = 1
def init(self, x=0):
self.x = x
one = MyClass4()
two = MyClass4()
two.a = 3
print(one.a)
#3
print(id(one))
#29660784
print(id(two))
#29660784
print(one == two)
#True
print(one is two)
#True
one.x = 1
print(one.x)
#1
print(two.x)
#1
55、实现一个斐波那契数列的生成器?
答:这道题的考点关键是生成器的yield关键字将一个普通函数改造成生成器函数:
def fib(n):
a, b = 0, 1
for _ in range(n):
a, b = b, a + b
yield a
def main():
for val in fib(20):
print(val)
if name == ‘main’:
main()
56、使用字符串拼接达到字幕滚动效果?
答:import os
import time
def main():
content = ‘欢迎来到蓝鸥科技有限公司’
while True:
# 清理屏幕上的输出
os.system(‘cls’) # os.system(‘clear’)
print(content)
# 休眠200毫秒
time.sleep(0.2)
content = content[1:] + content[0]
if name == ‘main’:
main()
57、设计一个函数返回给定文件名的后缀?
答:这道题考了正则表达式的简单知识点。代码如下:
def get_suffix(filename, has_dot=False):
“”"
获取文件名的后缀名
:param filename: 文件名
:param has_dot: 返回的后缀名是否需要带点
:return: 文件的后缀名
"""
pos = filename.rfind('.')
if 0 < pos < len(filename) - 1:
index = pos if has_dot else pos + 1
return filename[index:]
else:
return ''
二:Django面试题
1、谈谈你对Django的认识?
答:1.Django是走大而全的方向,它最出名的是其全自动化的管理后台:只需要使用起ORM,做简单的对象定义,它就能自动生成数据库结构、以及全功能的管理后台。
2.Django内置的ORM跟框架内的其他模块耦合程度高。
应用程序必须使用Django内置的ORM,否则就不能享受到框架内提供的种种基于其ORM的便利;
理论上可以切换掉其ORM模块,但这就相当于要把装修完毕的房子拆除重新装修,倒不如一开始就去毛胚房做全新的装修。
3.Django的卖点是超高的开发效率,其性能扩展有限;采用Django的项目,在流量达到一定规模后,都需要对其进行重构,才能满足性能的要求。
4.Django适用的是中小型的网站,或者是作为大型网站快速实现产品雏形的工具。
5.Django模板的设计哲学是彻底的将代码、样式分离; Django从根本上杜绝在模板中进行编码、处理数据的可能。
2、Django 、Flask、Tornado的对比?
答:1.Django走的是大而全的方向,开发效率高。它的MTV框架,自带的ORM,admin后台管理,自带的sqlite数据库和开发测试用的服务器,给开发者提高了超高的开发效率
2.Flask是轻量级的框架,自由,灵活,可扩展性很强,核心基于Werkzeug WSGI工具和jinja2模板引擎
3.Tornado走的是少而精的方向,性能优越。它最出名的是异步非阻塞的设计方式
Tornado的两大核心模块:
1.iostraem:对非阻塞式的socket进行简单的封装
2.ioloop:对I/O多路复用的封装,它实现了一个单例
3、什么是wsgi,uwsgi,uWSGI?
答:WSGI:
web服务器网关接口,是一套协议。用于接收用户请求并将请求进行初次封装,然后将请求交给web框架
实现wsgi协议的模块:
1.wsgiref,本质上就是编写一个socket服务端,用于接收用户请求(django)
2.werkzeug,本质上就是编写一个socket服务端,用于接收用户请求(flask)
uwsgi:
与WSGI一样是一种通信协议,它是uWSGI服务器的独占协议,用于定义传输信息的类型
uWSGI:
是一个web服务器,实现了WSGI协议,uWSGI协议,http协议,
4、django请求的生命周期?
答:1.wsgi,请求封装后交给web框架 (Flask、Django)
2.中间件,对请求进行校验或在请求对象中添加其他相关数据,例如:csrf、request.session -
3.路由匹配 根据浏览器发送的不同url去匹配不同的视图函数
4.视图函数,在视图函数中进行业务逻辑的处理,可能涉及到:orm、templates => 渲染 -
5.中间件,对响应的数据进行处理。
6.wsgi,将响应的内容发送给浏览器。
5、简述什么是FBV和CBV?
答:FBV和CBV本质是一样的
基于函数的视图叫做FBV,基于类的视图叫做CBV
在python中使用CBV的优点:
1.提高了代码的复用性,可以使用面向对象的技术,比如Mixin(多继承)
2.可以用不同的函数针对不同的HTTP方法处理,而不是通过很多if判断,提高代码可读性
6、如何给CBV的程序添加装饰器?
答:引入method_decorator模块
1.直接在类上加装饰器
@method_decorator(test,name=‘dispatch’)
class Loginview(View):
pass
2.直接在处理的函数前加装饰器
@method_decorator(test)
def post(self,request,*args,**kwargs):pass
7、简述MVC和MTV?
答:MVC软件系统分为三个基本部分:模型(Model)、视图(View)和控制器(Controller)
Model:负责业务对象与数据库的映射(ORM)
View:负责与用户的交互
Control:接受用户的输入调用模型和视图完成用户的请求
Django框架的MTV设计模式借鉴了MVC框架的思想,三部分为:Model、Template和View
Model(模型):负责业务对象与数据库的对象(ORM)
Template(模版):负责如何把页面展示给用户
View(视图):负责业务逻辑,并在适当的时候调用Model和Template
此外,Django还有一个urls分发器,
它将一个个URL的页面请求分发给不同的view处理,view再调用相应的Model和Template
8、django路由系统中name的作用?
答:用于反向解析路由,相当于给url取个别名,只要这个名字不变,即使对应的url改变,通过该名字也能找到该条url
9、列举django的内置组件?
答:1.Admin是对model中对应的数据表进行增删改查提供的组件
2.model组件:负责操作数据库
3.form组件:1.生成HTML代码2.数据有效性校验3校验信息返回并展示
4.ModelForm组件即用于数据库操作,也可用于用户请求的验证
10、说一下Django,MIDDLEWARES中间件的作用和应用场景?
答:中间件是介于request与response处理之间的一道处理过程,用于在全局范围内改变Django的输入和输出。
简单的来说中间件是帮助我们在视图函数执行之前和执行之后都可以做一些额外的操作
例如:
1.Django项目中默认启用了csrf保护,每次请求时通过CSRF中间件检查请求中是否有正确#token值
2.当用户在页面上发送请求时,通过自定义的认证中间件,判断用户是否已经登陆,未登陆就去登陆。
3.当有用户请求过来时,判断用户是否在白名单或者在黑名单里
11、列举django中间件的5个方法?
答:1.process_request : 请求进来时,权限认证
2.process_view : 路由匹配之后,能够得到视图函数
3.process_exception : 异常时执行
4.process_template_responseprocess : 模板渲染时执行
5.process_response : 请求有响应时执行
12、django的request对象是在什么时候创建的?
答:class WSGIHandler(base.BaseHandler):
request = self.request_class(environ)
请求走到WSGIHandler类的时候,执行__cell__方法,将environ封装成了request
13、Django重定向是如何实现的?用的什么状态码?
答:1.使用HttpResponseRedirect
from django.http import HttpResponseRedirect
2.使用redirect和reverse
状态码:301和302
301和302的区别:
相同点:都表示重定向,浏览器在拿到服务器返回的这个状态码后会自动跳转到一个新的URL地址
不同点:
301比较常用的场景是使用域名跳转。比如,我们访问 http://www.baidu.com 会跳转到 https://www.baidu.com
表示旧地址A的资源已经被永久地移除了
302用来做临时跳转,比如未登陆的用户访问用户中心重定向到登录页面。表示旧地址A的资源还在(仍然可以访问),这个重定向只是临时地从旧地址A跳转到地址B
14、xxss攻击?
答:-- XSS攻击是向网页中注入恶意脚本,用在用户浏览网页时,在用户浏览器中执行恶意脚本的攻击。
– XSS分类,反射型xss ,存储型xss
– 反射型xss又称为非持久型xss,攻击者通过电子邮件等方式将包含注入脚本的链接发送给受害者,
受害者通过点击链接,执行注入脚本,达到攻击目的。
– 持久型xss跟反射型的最大不同是攻击脚本将被永久的存放在目标服务器的数据库和文件中,多见于论坛
攻击脚本连同正常信息一同注入到帖子内容当中,当浏览这个被注入恶意脚本的帖子的时候,恶意脚本会被执行
– 防范措施 1 输入过滤 2 输出编码 3 cookie防盗
1,输入过滤 用户输入进行检测 不允许带有js代码
2,输出编码 就是把我们的脚本代码变成字符串形式输出出来
3,cookie加密
向页面注入恶意的代码,这些代码被浏览器执行
XSS攻击能做些什么:
1.窃取cookies
2.读取用户未公开的资料,如果:邮件列表或者内容、系统的客户资料,联系人列表
解决方法:
1.客户度端:表单提交之前或者url传递之前,对需要的参数进行过滤
2.服务器端:检查用户输入的内容是否有非法内容
15、django中csrf的实现机制?
答:第一步:django第一次响应来自某个客户端的请求时,后端随机产生一个token值,把这个token保存在SESSION状态中;同时,后端把这个token放到cookie中交给前端页面;
第二步:下次前端需要发起请求(比如发帖)的时候把这个token值加入到请求数据或者头信息中,一起传给后端;Cookies:{csrftoken:xxxxx}
第三步:后端校验前端请求带过来的token和SESSION里的token是否一致;
16、基于django使用ajax发送post请求时,都可以使用哪种方法携带csrf token?
答:1.后端将csrftoken传到前端,发送post请求时携带这个值发送
data: {
csrfmiddlewaretoken: ‘{{ csrf_token }}’
},
2.获取form中隐藏标签的csrftoken值,加入到请求数据中传给后端
data: {
csrfmiddlewaretoken:KaTeX parse error: Expected 'EOF', got '}' at position 49: …val() }̲, 3.cookie中存在cs….cookie(“csrftoken”)},
17、Django本身提供了runserver,为什么不能用来部署?(runserver与uWSGI的区别)?
答:1.runserver方法是调试 Django 时经常用到的运行方式,它使用Django自带的
WSGI Server 运行,主要在测试和开发中使用,并且 runserver 开启的方式也是单进程 。
2.uWSGI是一个Web服务器,它实现了WSGI协议、uwsgi、http 等协议。注意uwsgi是一种通信协议,而uWSGI是实现uwsgi协议和WSGI协议的 Web 服务器。
uWSGI具有超快的性能、低内存占用和多app管理等优点,并且搭配着Nginx就是一个生产环境了,能够将用户访问请求与应用 app 隔离开,实现真正的部署 。
相比来讲,支持的并发量更高,方便管理多进程,发挥多核的优势,提升性能。
18、cookie和session的区别?
答:cookie:
cookie是保存在浏览器端的键值对,可以用来做用户认证
2.session:
将用户的会话信息保存在服务端,key值是随机产生的自符串,value值时session的内容
依赖于cookie将每个用户的随机字符串保存到用户浏览器上
Django中session默认保存在数据库中:django_session表
flask,session默认将加密的数据写在用户的cookie中
19、列举django orm 中所有的方法(QuerySet对象的所有方法)
答: all(): 查询所有结果
filter(**kwargs): 它包含了与所给筛选条件相匹配的对象。获取不到返回None
get(**kwargs): 返回与所给筛选条件相匹配的对象,返回结果有且只有一个。获取不到会抱胸
如果符合筛选条件的对象超过一个或者没有都会抛出错误。
exclude(**kwargs): 它包含了与所给筛选条件不匹配的对象
order_by(*field): 对查询结果排序
reverse(): 对查询结果反向排序
count(): 返回数据库中匹配查询(QuerySet)的对象数量。
first(): 返回第一条记录
last(): 返回最后一条记录
exists(): 如果QuerySet包含数据,就返回True,否则返回False
values(*field): 返回一个ValueQuerySet——一个特殊的QuerySet,运行后得到的并不是一系 model的实例化对象,而是一个可迭代的字典序列
values_list(*field): 它与values()非常相似,它返回的是一个元组序列,values返回的是一个字典序列
distinct(): 从返回结果中剔除重复纪录
20、only和defer的区别?
答:only:从数据库中只取指定字段的内容,defer:指定字段的内容不被检索
21、select_related和prefetch_related的区别?
答:有外键存在时,可以很好的减少数据库请求的次数,提高性能
select_related通过多表join关联查询,一次性获得所有数据,只执行一次SQL查询
prefetch_related分别查询每个表,然后根据它们之间的关系进行处理,执行两次查询
22、filter和exclude的区别?
答:#取到的值都是QuerySet对象,filter选择满足条件的,exclude:排除满足条件的
23、F和Q的作用?
答:F:对数据本身的不同字段进行操作 如:比较和更新
Q:用于构造复杂的查询条件 如:& |操作
24、values和values_list的区别?
答:values : 取字典的queryset
values_list : 取元组的queryset
25、如何使用django orm批量创建数据?
答:bulk_create()
objs=[models.Book(title=“图书{}”.format(i+15)) for i in range(100)]
models.Book.objects.bulk_create(objs)
26、django的Form和ModeForm的作用?
答:Form作用:
1.在前端生成HTML代码
2.对数据作有效性校验
3.返回校验信息并展示
ModeForm:根据模型类生成From组件,并且可以操作数据库
27、django的Form组件中,如果字段中包含choices参数,请使用两种方式实现数据源实时更新?
答:1.重写构造函数def def init(self, *args, **kwargs):
super().init(*args, **kwargs)
self.fields[“city”].widget.choices = models.City.objects.all().values_list(“id”, “name”)#2.利用ModelChoiceField字段,参数为queryset对象
28、 django的Model中的ForeignKey字段中的on_delete参数有什么作用?
答:删除关联表中的数据时,当前表与其关联的field的操作
django2.0之后,表与表之间关联的时候,必须要写on_delete参数,否则会报异常
29、django如何实现websocket?
答:1.使用execute执行自定义的SQL
2.使用extra方法
3.使用raw方法
1.执行原始sql并返回模型
2.依赖model多用于查询
30、django orm 中如何设置读写分离?
答:1.手动读写分离:通过.using(db_name)来指定要使用的数据库
2.自动读写分离:
1.定义类:如Router
2.配置Router
settings.py中指定DATABASE_ROUTERS
DATABASE_ROUTERS = [‘myrouter.Router’,]
提高读的性能:多配置几个数据库,并在读取时,随机选取。写的时候写到主库
实现app之间的数据库分离:分库分表
31、django内置的缓存机制?
答:# 全站缓存
MIDDLEWARE_CLASSES = (
‘django.middleware.cache.UpdateCacheMiddleware’, #第一
‘django.middleware.common.CommonMiddleware’,
‘django.middleware.cache.FetchFromCacheMiddleware’, #最后)
@cache_page(15) #超时时间为15秒def index(request):
t=time.time() #获取当前时间
return render(request,“index.html”,locals())
{% load cache %}
{% cache 2 ‘name’ %} # 存的key
32、django的缓存能使用redis吗?如果可以的话,如何配置?
答:#1.安装 pip install django-redis
#2.在stting中配置CACHES,可以设置多个缓存,根据名字使用
CACHES = {
“default”: {
“BACKEND”: “django_redis.cache.RedisCache”,
“LOCATION”: “redis://127.0.0.1:6379”,
“OPTIONS”: {
“CLIENT_CLASS”: “django_redis.client.DefaultClient”,
“CONNECTION_POOL_KWARGS”: {“max_connections”: 100}
# “PASSWORD”: “密码”,
}
}
},
#另添加缓存
“JERD”: { }
#3.根据名字去连接池中获取连接
from django_redis import get_redis_connection
conn = get_redis_connection(“default”)
33、django的模板中filter和simple_tag的区别?
答:# 自定义filter:{{ 参数1|filter函数名:参数2 }}
34、django-debug-toolbar的作用?
答:#1.是django的第三方工具包,给django扩展了调试功能
#包括查看sql语句,db查询次数,request,headers等
35、解释orm中 db first 和 code first的含义?
答:#数据持久化的方式:
db first基于已存在的数据库,生成模型
code first基于已存在的模型,生成数据库库
36、django中如何根据数据库表生成model中的类?
答:1.在settings中设置要连接的数据库
2.生成model模型文件#python manage.py inspectdb
3.模型文件导入到models中
python manage.py inspectdb > app/models.py
37、使用orm和原生sql的优缺点?
答:#1.orm的开发速度快,操作简单。使开发更加对象化
#执行速度慢。处理多表联查等复杂操作时,ORM的语法会变得复杂
#2.sql开发速度慢,执行速度快。性能强
38、django的contenttype组件的作用?
答:#这个组件保存了项目中所有app和model的对应关系,每当我们创建了新的model并执行数据库迁移后,ContentType表中就会自动新增一条记录
#当一张表和多个表FK关联,并且多个FK中只能选择其中一个或其中n个时,可以利用contenttypes
39、谈谈你对restful规范的认识?
答:首先restful是一种软件架构风格或者说是一种设计风格,并不是标准,它只是提供了一组设计原则和约束条件,主要用于客户端和服务器交互类的软件。
就像设计模式一样,并不是一定要遵循这些原则,而是基于这个风格设计的软件可以更简洁,更#有层次,我们可以根据开发的实际情况,做相应的改变。它里面提到了一些规范,例如:
1.restful 提倡面向资源编程,在url接口中尽量要使用名词,不要使用动词
2、在url接口中推荐使用Https协议,让网络接口更加安全
3、在url中可以体现版本号
4、url中可以体现是否是API接口
5、url中可以添加条件去筛选匹配
6、可以根据Http不同的method,进行不同的资源操作
7、响应式应该设置状态码
8、有返回值,而且格式为统一的json格式
9、返回错误信息
10、返回结果中要提供帮助链接,即API最好做到Hypermedia
#如果遇到需要跳转的情况 携带调转接口的URL
ret = {
code: 1000,
data:{
id:1,
name:‘小强’,
depart_id:http://www.luffycity.com/api/v1/depart/8/
}
}
40、接口的幂等性是什么意思?
答:1.是系统的接口对外一种承诺(而不是实现)
2.承诺只要调用接口成功,外部多次调用对系统的影响都是一致的,不会对资源重复操作
41、什么是RPC?
答:#远程过程调用 (RPC) 是一种协议,程序可使用这种协议向网络中的另一台计算机上的程序请求服务
#1.RPC采用客户机/服务器模式。请求程序就是一个客户机,而服务提供程序就是一个服务器。
#2.首先,客户机调用进程发送一个有进程参数的调用信息到服务进程,然后等待应答信息。
#2.在服务器端,进程保持睡眠状态直到调用信息到达为止。当一个调用信息到达,服务器获得进程参数,计算结果,发送答复信息,然后等待下一个调用信息,
#3.最后,客户端调用进程接收答复信息,获得进程结果,然后调用执行继续进行。
42、为什么要使用API?
答:#系统之间为了调用数据。
#数据传输格式:
43、为什么要使用django rest framework框架?
答:#能自动生成符合 RESTful 规范的 API
#1.在开发REST API的视图中,虽然每个视图具体操作的数据不同,
#但增、删、改、查的实现流程基本一样,这部分的代码可以简写
#2.在序列化与反序列化时,虽然操作的数据不同,但是执行的过程却相似,这部分的代码也可以简写
#REST framework可以帮助简化上述两部分的代码编写,大大提高REST API的开发速度
44、django rest framework框架中都有那些组件?
答:#1.序列化组件:serializers 对queryset序列化以及对请求数据格式校验
#2.路由组件routers 进行路由分发
#3.视图组件ModelViewSet 帮助开发者提供了一些类,并在类中提供了多个方法
#4.认证组件 写一个类并注册到认证类(authentication_classes),在类的的authticate方法中编写认证逻
#5.权限组件 写一个类并注册到权限类(permission_classes),在类的的has_permission方法中编写认证逻辑。
#6.频率限制 写一个类并注册到频率类(throttle_classes),在类的的allow_request/wait 方法中编写认证逻辑
#7.解析器 选择对数据解析的类,在解析器类中注册(parser_classes)
#8.渲染器 定义数据如何渲染到到页面上,在渲染器类中注册(renderer_classes)
#9.分页 对获取到的数据进行分页处理, pagination_class
#10.版本 版本控制用来在不同的客户端使用不同的行为
#在url中设置version参数,用户请求时候传入参数。在request.version中获取版本,根据版本不同 做不同处理
45、django rest framework框架中的视图都可以继承哪些类?
答:#class View(object):
#class APIView(View): 封装了view,并且重新封装了request,初始化了各种组件
#class GenericAPIView(views.APIView):
#1.增加了一些属性和方法,如get_queryset,get_serializer
#class GenericViewSet(ViewSetMixin, generics.GenericAPIView)
#父类ViewSetMixin 重写了as_view,返回return csrf_exempt(view)
#并重新设置请求方式与执行函数的关系
#class ModelViewSet(mixins.CreateModelMixin,
#继承了mixins下的一些类,封装了list,create,update等方法
#和GenericViewSet
46、简述 django rest framework框架的认证流程?
答:#1.用户请求走进来后,走APIView,初始化了默认的认证方法
#2.走到APIView的dispatch方法,initial方法调用了request.user
#3.如果我们配置了认证类,走我们自己认证类中的authentication方法
47、django rest framework如何实现的用户访问频率控制?
答:#使用IP/用户账号作为键,每次的访问时间戳作为值,构造一个字典形式的数据,存起来,每次访问时对时间戳列表的元素进行判断,#把超时的删掉,再计算列表剩余的元素数就能做到频率限制了 #匿名用户:使用IP控制,但是无法完全控制,因为用户可以换代理IP登录用户:使用账号控制,但是如果有很多账号,也无法限制
48、rest_framework序列化组件的作用,以及一些外键关系的钩子方法?
答:#作用:帮助我们序列化数据
#1.choices get_字段名_display
#2.ForeignKey source=orm 操作
#3.ManyToManyFiled SerializerMethodField()
49、给用户提供一个接口之前需要提前做什么?
答:#1.跟前端进行和交互,确定前端要什么
#2.把需求写个文档保存
50、PV和UV?
答:#1.pv:页面访问量,没打开一次页面PV计算+1,页面刷新也是
#2.UV:独立访问数,一台电脑终端为一个访客
51、什么是跨域以及解决方法?
答:#跨域:
#同源策略:
#处理方法:
#简单请求:
#非简单请求:
#只要同时满足以下两大条件,就属于简单请求。
#JSONP和CORS:
52、如何实现用户的登陆认证?
答:#1.cookie session
#2.token 登陆成功后生成加密字符串
#3.JWT:json wed token缩写 它将用户信息加密到token中,服务器不保存任何用户信息
#服务器通过使用保存的密钥来验证token的正确性
53、如何将dict转换成url的格式?
答:#使用urlencode
#from urllib.parse import urlencode
#post_data={“k1”:“v1”,“k2”:“v2”}
#ret=urlencode(post_data)
#print(ret,type(ret)) #k1=v1&k2=v2
三:Flask面试题
1、什么是Flask,有什么优点?
答:概念解释
Flask是一个Web框架,就是提供一个工具,库和技术来允许你构建一个Web应用程序。这个Web应用程序可以是一些Web页面,博客,wiki,基于Web的日里应用或商业网站。
优点
Flask属于微框架(micro-framework)这一类别,微架构通常是很小的不依赖外部库的框架。
4、Flask-WTF是什么,有什么特点?
答:Flask-wtf是一个用于表单处理,校验并提供csrf验证的功能的扩展库
Flask-wtf能把正表单免受CSRF<跨站请求伪造>的攻击
5、Flask脚本的常用方式是什么?
答:在shell中运行脚本文件
在python编译器中run
6、如何在Flask中访问会话?
答:会话(seesion)会话数据存储在服务器上。 会话是客户端登录到服务器并注销的时间间隔。 需要在此会话中进行的数据存储在服务器上的临时目录中。
from flask import session导入会话对象
session[‘name’] = 'admin’给会话添加变量
session.pop(‘username’, None)删除会话的变量
7、解释Python Flask中的数据库连接?
答:python中的数据库连接有两种方式
在脚本中以用第三方库正常连接,用sql语句正常操作数据库,如mysql关系型数据库的pymsql库
用ORM来进行数据库连接,flask中典型的flask_sqlalchemy,已面向对象的方式进行数据库的连接与操作
8、 列举Http请求中常见的请求方式?
答:GET / POST/DELETE
9、 列举Http请求中的状态码?
10、答:404 请求的url地址不存在
503 访问限制有权限
200 访问成功
302 重定向
10、列举Http请求中常见的请求头?
答:User-Agent:浏览器类型,如果Servlet返回的内容与浏览器类型有关则该值非常有用。
Cookie:这是最重要的请求头信息之一
Content-Type:请求类型
11、Flask框架依赖组件?
答:Route(路由)
templates(模板)
Models(orm模型)
blueprint(蓝图)
Jinja2模板引擎
12、Flask蓝图的作用?
答:蓝图Blueprint实现模块化的应用步骤:
13、列举使用过的Flask第三方组件?
答:flask_bootstrap
flask-WTF
flask_sqlalchemy
14、简述Flask上下文管理流程?
答:每次有请求过来的时候,flask 会先创建当前线程或者进程需要处理的两个重要上下文对象,把它们保存到隔离的栈里面,这样视图函数进行处理的时候就能直接从栈上获取这些信息。
15、Flask中多app应用是怎么完成?
答:请求进来时,可以根据URL的不同,交给不同的APP处理
16、wtforms组件的作用?
答:WTForms是一个支持多个web框架的form组件,主要用于对用户请求数据进行验证。
17、Flask框架默认session处理机制?
答:Flask的默认session利用了Werkzeug的SecureCookie,把信息做序列化(pickle)后编码(base64),放到cookie里了。过期时间是通过cookie的过期时间实现的。为了防止cookie内容被篡改,session会自动打上一个叫session的hash串,这个串是经过session内容、SECRET_KEY计算出来的,看得出,这种设计虽然不能保证session里的内容不泄露,但至少防止了不被篡改。
18、ORM的实现原理?
答:概念: 对象关系映射(Object Relational Mapping,简称ORM,或O/RM,或O/R mapping),是一种程序技术,用于实现面向对象编程语言里不同类型系统的数据之间的转换。ORM解决的主要问题是对象关系的映射。
ORM技术特点:
1.提高了开发效率。由于ORM可以自动对Entity对象与数据库中的Table进行字段与属性的映射,所以我们实际可能已经不需要一个专用的、庞大的数据访问层。
2.ORM提供了对数据库的映射,不用sql直接编码,能够像操作对象一样从数据库获取数据。
四、爬虫问题:
1、scrapy的基本结构(五个部分都是什么,请求发出去的整个流程)
答:Scrapy主要包括了以下组件:
引擎(Scrapy Engine)
用来处理整个系统的数据流处理, 触发事务(框架核心)
调度器(Scheduler)
用来接受引擎发过来的请求, 压入队列中, 并在引擎再次请求的时候返回. 可以想像成一个URL(抓取网页的网址或者说是链接)的优先队列, 由它来决定下一个要抓取的网址是什么, 同时去除重复的网址
下载器(Downloader)
用于下载网页内容, 并将网页内容返回给蜘蛛(Scrapy下载器是建立在twisted这个高效的异步模型上的)
爬虫(Spiders)
爬虫是主要干活的, 用于从特定的网页中提取自己需要的信息, 即所谓的实体(Item)。用户也可以从中提取出链接,让Scrapy继续抓取下一个页面
项目管道(Pipeline)
负责处理爬虫从网页中抽取的实体,主要的功能是持久化实体、验证实体的有效性、清除不需要的信息。当页面被爬虫解析后,将被发送到项目管道,并经过几个特定的次序处理数据。
下载器中间件(Downloader Middlewares)
位于Scrapy引擎和下载器之间的框架,主要是处理Scrapy引擎与下载器之间的请求及响应。
爬虫中间件(Spider Middlewares)
介于Scrapy引擎和爬虫之间的框架,主要工作是处理蜘蛛的响应输入和请求输出。
调度中间件(Scheduler Middewares)
介于Scrapy引擎和调度之间的中间件,从Scrapy引擎发送到调度的请求和响应。
运行原理:
2、scrapy的去重原理 (指纹去重到底是什么原理)
答:对于每一个url的请求,调度器都会根据请求得相关信息加密得到一个指纹信息,并且将指纹信息和set()集合中的指纹信息进行比对,如果set()集合中已经存在这个数据,就不在将这个Request放入队列中。如果set()集合中没有存在这个加密后的数据,就将这个Request对象放入队列中,等待被调度。
具体操作方式是:scrapy.Request(url, meta={‘item’: news_item}, callback=self.parse2, dont_filter=True)中参数dont_filter默认为False,即开启去重,如果设置为True则关闭去重
3、scrapy中间件有几种类?
答:
CookiesMiddleware:是否向web server发送cookie
DefaultHeadersMiddleware:将所有request的头设置为默认模式
DownloadTimeoutMiddleware:设置request的timeout
HttpAuthMiddleware:对来自特定spider的request授权
HttpCacheMiddleware:给request&response设置缓存策略
HttpCompressionMiddleware:
ChunkedTransferMiddleware:
HttpProxyMiddleware:给所有request设置http代理
RedirectMiddleware:处理request的重定向
MetaRefreshMiddleware:根据meta-refresh html tag处理重定向
RetryMiddleware:失败重试策略
RobotsTxtMiddleware:robots封禁处理
UserAgentMiddleware:支持user agent重写
DepthMiddleware:对抓取深度和深度优先级进行设置;
HttpErrorMiddleware:设置成功码的范围
OffsiteMiddleware:主域过滤
RefererMiddleware:
UrlLengthMiddleware:限定有效url的长度
4、scrapy中间件如何使用?
答:参考https://www.jianshu.com/p/f4fed2ea2717
5、为什么会用到代理?如何使用代理?
答:在平时使用爬虫程序采集数据时,往往会遇到,因采集速度过快导致的自己网络ip被目标网站封禁,这种封禁有时候是封几分钟,有时候是封一天,封的时间不等,但是这样会导致我们局域网内其他人也无法访问目标网站,最大的问题是我们无法进行数据采集。为了保证正常采集数据且本地ip不被封禁,引入代理ip。
代理的具体使用:参考https://www.cnblogs.com/hhh5460/p/5824786.html
6、登陆验证码处理?
答:分析网页验证码图片,之后将图片下载下来,通过图像处理进行机器识别,识别出验证码。
7、模拟登陆流程?
答:使用scrapy.FormRequest()登录,通过scrapy.FormRequest能够发送post请求,同时需要添加fromdata参数作为请求体
yield scrapy.FormRequest(
“https://github.com/session”,
formdata={
“authenticity_token”:authenticity_token,
“utf8”:utf8,
“commit”:commit,
“login”:“",
“password”:"”
},
callback=self.parse_login
)
8、Scrapy中cookie如何处理?
答:略(参考链接:https://blog.csdn.net/u013210620/article/details/80283637)
9、.如何处理网站传参加密的情况?
答:第一种破解方式是 简单的破解方式使用 selenium,或者其他可以执行JS 并且可以存储cookie,手动设置cookie的值,selenium 有个通病 比较慢。
第二种 有点投机取巧了, 找他们的相关的APP,看下APP是不是没有加密或者加密比较薄弱(一般网页加密,app也是加密的但是不试一下怎么知道不成功)
第三种方式,手动去设置破解方式,需要打开浏览器的 开发者模式,查看每次的网络请求,根据请求对应的链接或js查找加密算法。
10、分布式原理?
答:分布式爬虫的关键是共享一个requests队列,维护该队列的主机称为master,而从机则负责数据的抓取,数据处理和数据存储,那么队列用什么维护呢,这里我们选用Redis队列进行存储,Redis是一种高效的非关系型数据库,以key-value的形式存储,结构灵活,它是内存中的数据结构存储系统,处理速度快,性能好,同时,提供了队列,集合等多种存储结构,方便队列维护。
分布式爬虫架构如下图所示:
11、分布式去重原理?
答:Redis提供集合数据结构,在Redis集合中存储每个Request的指纹,在向Request队列中加入Request时首先验证指纹是否存在。如果存在,则不加入,如果不存在,则加入。
12、关系型数据库和非关系型数据库的区别?
答:关系型数据库(Mysql和Oracle)
1.表和表、表和字段、数据和数据存在着关系
优点:
1.数据之间有关系,进行数据的增删改查的时候是非常方便的
2.关系型数据库是有事务操作的,保证数据的完整性和一致性。
缺点:
1.因为数据和数据是有关系的,底层是运行了大量的算法
大量算法会降低系统的效率,会降低性能
2.面对海量数据的增删改查的时候会显的无能为力
3.海量数据对数据进行维护变得非常的无力
因此关系型数据库适合处理一般量级的数据(银行转账和钱)
非关系数据库的(redis和MangDB)
为了处理海量数据,非关系数据库设计之初就是为了替代关系型数据库的关系
优点:
1.海量数据的增删改查是可以的
2.海量数据的维护和处理非常轻松
缺点:
1.数据和数据没有关系,他们之间就是单独存在的
2.非关系数据库没有关系,没有强大的事务关系,没有保证数据的完整性和安全性
因此非关系型数据库适合处理海量数据,保证效率,不一定安全(统计数据,例如微博数据)
13、http协议,请求由什么组成,每个字段分别有什么用?
答: HTTP请求包(GET?POST等请求方法)由三个部分构成,分别是:
(1)方法-URI-协议/版本,用来设置请求的方式,及请求遵循的协议等
(2)请求头,用来设置可接受的内容类型,链接状态,请求域名,浏览器型号和版本等
(3)请求正文,用来设置向服务器传输的数据等
14、https和http有什么差距?
答:HTTPS和HTTP的区别主要如下:
1、https协议需要到ca申请证书,一般免费证书较少,因而需要一定费用。
2、http是超文本传输协议,信息是明文传输,https则是具有安全性的ssl加密传输协议。
3、http和https使用的是完全不同的连接方式,用的端口也不一样,前者是80,后者是443。
4、http的连接很简单,是无状态的;HTTPS协议是由SSL+HTTP协议构建的可进行加密传输、身份认证的网络协议,比http协议安全。
五、人工智能部分
1、机器学习中特征的理解
答:特征选择和降维
特征选择:原有特征选择出子集,不改变原来的特征空间
降维:将原有的特征重组成为包含信息更多的特征,改变了原有的特征空间
降维的主要方法
Principal Component Analysis(主成分分析)
Singular Value Decomposition(奇异值分解)
Sammon’s Mapping(Sammon映射)
特征选择的方法
Filter方法
Chi-squared test(卡方检验)
information gain(信息增益),详细可见“简单易学的机器学习算法——决策树之ID3算法”
correlation coefficient scores(相关系数)
2、机器学习中,有哪些特征选择的工程方法?
答:数据和特征决定了机器学习的上限,而模型和算法只是逼近这个上限而已
典型的线性分类器有感知机,LDA,逻辑斯特回归,SVM(线性核);
典型的非线性分类器有朴素贝叶斯,kNN,决策树,SVM(非线性核)
优缺点:1.线性分类器判别简单、易实现、且需要的计算量和存储量小。
为解决比较复杂的线性不可分样本分类问题,提出非线性判别函数。:超曲面,非线性判别函数计算复杂,实际应用上受到较大的限制。在线性分类器的基础上,用分段线性分类器可以实现复杂的分类面。解决问题比较简便的方法是采用多个线性分界面将它们分段连接,用分段线性判别划分去逼近分界的超曲面。 2.如果一个问题是非线性问题并且它的类边界不能够用线性超平面估计得很好,那么非线性分类器通常会比线性分类器表现得更精准。如果一个问题是线性的,那么最好使用简单的线性分类器来处理。
4、如何解决过拟合问题?
答:解释过拟合:模型在训练集表现好,在真实数据表现不好,即模型的泛化能力不够。从另外一个方面来讲,模型在达到经验损失最小的时候,模型复杂度较高,结构风险没有达到最优。
解决:
学习方法上:限制机器的学习,使机器学习特征时学得不那么彻底,因此这样就可以降低机器学到局部特征和错误特征的几率,使得识别正确率得到优化.
数据上:要防止过拟合,做好特征的选取。训练数据的选取也是很关键的,良好的训练数据本身的局部特征应尽可能少,噪声也尽可能小.
5、L1和L2正则的区别,如何选择L1和L2正则?
答:L1Norm 和L2 Norm的区别(核心:L2对大数,对outlier更敏感!):
L1优点是能够获得sparse模型,对于large-scale的问题来说这一点很重要,因为可以减少存储空间。缺点是加入L1后目标函数在原点不可导,需要做特殊处理。
L2优点是实现简单,能够起到正则化的作用。缺点就是L1的优点:无法获得sparse模型。实际上L1也是一种妥协的做法,要获得真正sparse的模型,要用L0正则化。
参考:机器学习中的范数规则化之(一)L0、L1与L2范数
6、有监督学习和无监督学习的区别
答:有监督学习:对具有概念标记(分类)的训练样本进行学习,以尽可能对训练样本集外的数据进行标记(分类)预测。这里,所有的标记(分类)是已知的。因此,训练样本的岐义性低。监督学习中只要输入样本集,机器就可以从中推演出制定目标变量的可能结果.如协同过滤推荐算法,通过对训练集进行监督学习,并对测试集进行预测,从而达到预测的目的.
无监督学习:对没有概念标记(分类)的训练样本进行学习,以发现训练样本集中的结构性知识。这里,所有的标记(分类)是未知的。因此,训练样本的岐义性高。聚类就是典型的无监督学习
监督学习的典型例子就是决策树、神经网络以及疾病监测,而无监督学习就是很早之前的西洋双陆棋和聚类。
7、如何利用SciKit包训练一个简单的线性回归模型?
答:利用linear_model.LinearRegression()函数
regr = linear_model.LinearRegression()
regr.fit(data_X_train, data_y_train)
8、例举几个常用的python分析数据包及其作用?
答:数据处理和分析:NumPy, SciPy, Pandas
机器学习:SciKit
可视化: Matplotlib, Seaborn
9、如何利用Numpy对数列的前n项进行排序?
答:使用argsort()函数:x[x [: n-1].argsort ()]
10、在python中如何创建包含不同类型数据的dataframe?
答:利用pandas包的DataFrame函数的serias创建列然后用dtype定义类型:
df = pd.DataFrame({‘x’: pd.Series([‘1.0’, ‘2.0’, ‘3.0’], dtype=float), ‘y’: pd.Series([‘1’, ‘2’, ‘3’], dtype=int)})
11、Pandas中使用的标准数据缺失标志是什么?
答:NaN
12、描述numpy array比python list的优势?
答:1. numpy array比python list更紧凑,存储数据占的空间小,读写速度快。(这是由于python list储存的是指向对象(至少需要16个字节)的指针(至少4个字节);而array中储存的是单一变量(比如单精度浮点数为4个字节,双精度为8))
2. array可以直接使用vector和matrix类型的处理函数,非常方便。
13、如何检验numpy的array为空?
答:使用size函数, 比如
a = np.array([])
print(a.size) # 0
14、如何检验pandas dataframe为空?
答:使用empty函数
15、什么是逻辑斯蒂回归(logistic regression)?
答:逻辑斯蒂回归常指逻辑回归模型,用于预测参数之间组合可能输出的二分结果。
16、特征值和特征向量?
答:在数据分析是通过计算相关和协方差矩阵的特征向量可以用于确定之后的线性转换的方向。特征值表示特征向量方向转化或者压缩的强度。
17、如何评价一个逻辑斯蒂模型?
答:用分类矩阵查看真阴性和假阳性
一致性分析: 查看逻辑斯蒂模型区分事件是否发生的能力
与随机选择模型进行对比
18、如何处理缺失数据?如果缺失的数据不可得,将采用何种手段收集?
答:首先判断缺失数据是否有意义,如果没有意义或者缺失数据的比例超过80%直接去掉。如果缺失数据有规律,则需根据其变化规律来推测次缺失值;如果数据没有规律,则用其他值代替:
如果数据符合正态分布,缺失值用期望值代替
如果数据是类型变量,则用默认类型值代替缺失值
19、逻辑斯蒂回归和线性回归的区别?
答:逻辑斯蒂回归的预测值是两元的,0或1;而线性回归的预测值是连续的。
六:HTML&JS
一、HTML&CSS整理答案
1、标签上title与alt属性的区别是什么?
答:title是设置鼠标移动到图片上时显示的内容,而alt是用于当图片没有正常显示时出现的提示文字,另外alt还用于在seo中针对图片的优化说明.
2、
标签内的文字是什么颜色的?
3、css单位px,em,rem的区别?
答:px像素(Pixel)。相对长度单位。像素px是相对于显示器屏幕分辨率而言的
px的特点:
1. IE无法调整那些使用px作为单位的字体大小;
2. 国外的大部分网站能够调整的原因在于其使用了em或rem作为字体单位;
3. Firefox能够调整px和em,rem,但是96%以上的中国网民使用IE浏览器(或内核)。
em是相对长度单位。相对于当前对象内文本的字体尺寸。如当前对行内文本的字体尺寸未被人为设置,则相对于浏览器的默认字体尺寸
EM特点
1. em的值并不是固定的;
2. em会继承父级元素的字体大小。
rem是CSS3新增的一个相对单位(root em,根em),这个单位引起了广泛关注。这个单位与em有什么区别呢?区别在于使用rem为元素设定字体大小时,仍然是相对大小,但相对的只是HTML根元素。这个单位可谓集相对大小和绝对大小的优点于一身,通过它既可以做到只修改根元素就成比例地调整所有字体大小,又可以避免字体大小逐层复合的连锁反应。目前,除了IE8及更早版本外,所有浏览器均已支持rem。对于不支持它的浏览器,应对方法也很简单,就是多写一个绝对单位的声明。这些浏览器会忽略用rem设定的字体大小。
4、以下哪些是css伪类?(c,d)after和before是伪元素
A.after B.before C.hover D.nth-child
5、以下不是html5元素的有哪些?(b,c)
A.footer B.center C.font D.frame
6、下述有关css属性position的属性值的描述。 语法错误的是?b
A.static:没有定位,元素出现在正常的流中。
B.fixed:生成绝对定位的元素,相对于父元素进行定位。
C.relative:生成相对定位的元素,相对于元素本身正常位置进行定位。
D.absolute:生成绝对定位的元素,相对于static定位意外的第一个祖先元素。
7、CSS实现隐藏页面元素的方法有哪些?
display:none; visibility: hidden;opacity:0; position:absolute;left:-10000px;
8、xhtml和html有什么区别?
答:xhtml比HTML严谨性会高点,然后基本语言都还是沿用的HTML的标签,只不过废除了部分表现层的标签,同事在标准上要求高了点比如标签的严格嵌套,标签结束等等
9、每个html文件里开头都有个Doctype。这是代表了什么意思?
答:版本声明
10、strong与em的异同?
答:语义都是语气加重,strong在显示上是变粗,而em是斜体显示
11、行内元素有哪些?块级元素有哪些?
答:块状:*
内联(行内):
根据这四个级别出现的次数计算得到CSS的优先级。
CSS优先级的计算规则如下:
2、“”和“=”的不同。
答:==用于一般比较,===用于严格比较,==在比较的时候可以转换数据类型,===严格比较,只要类型不匹配就返回flase
3、JavaScript的数据类型都有哪些?
答:JavaScript中有5种简单数据类型(也称为基本数据类型):Undefined、Null、Boolean、Number和String。还有1种复杂数据类型——Object,Object本质上是由一组无序的名值对组成的
4、let foo = “11” + 2 - “1”;foo 输出的是?typeof foo输出的是?
答:foo输出的是111,首先字符串11+数字2,执行字符串连接为112,而后减1,是将112执行隐式类型转换为数字112后再减1,所以最后结果是111
typeof foo,为number
5、split() join()的区别在哪?
答:split是将字符串分割为数组,而join是将数组中的值连接为字符串
6、数组方法pop() push() unshift() shift()的区别在哪?
答:pop是删除数组最后一位
push是在数组最后一位插入一个新元素
unshift是在数组开头添加一个或更多元素
shift是将数组开头的元素删除
7、JavaScript的事件流模型都有哪些?
答:在各种浏览器中存在三种事件模型:原始事件模型( original event model),DOM2事件模型,IE事件模型.(回答重点)
原始事件模型简单来说就是用on+事件名的方式绑定的事件,比如onclick,onsubmit等
dom2事件模型就是通过addEventListener绑定的事件,可以通过event.stopPropagation()来停止事件的传播,调用preventDefault()来阻止浏览器的默认行为
IE模型也提供了一个event对象封装了事件的详细信息,但是IE不把该对象传入事件处理函数,由于在任意时刻只会存在一个事件,所以IE把它作为全局对象window的一个属性,IE中的事件传播模式对应于DOM2的第二和第三阶段,首先执目标元素的处理函数,然后向上传播到达document,ie中只能能捕捉鼠标事件,而DOM2中可以捕捉所有的事件,IE中注册和删除事件处理函数的方法也不同于DOM2.
事件处理函数的注册和删除是通过元素的attachEvent( “eventType”,“handler”) and detachEvent(“eventType”,“handler” ),与dom2不同的是eventType有on前缀
8、请按执行顺序写出几次alert()语句a的值:
function fn1() {
var a = 1;
function fn2() {
alert(a++);
}
return fn2;
}
var f = fn1();
f();
f();
答:两次:第1次1,第二次2,var f=fn1()的时候只是调用了fn1这个函数并将fn2作为返回值返回,并未执行fn2里面的内容.
在第一个f()的时候就是执行fn2里面的内容,同时因为fn2是一个闭包函数,调用了fn1中的a,所以a为1,至于a++,因为a++为后自加,先引用a,再进行自加操作,所以第一次弹出为1,而第二个f(),因为a的值已经++过了,所以弹出2.
9、请按要求操作数组a:
i. 如何删除数组a中第2个元素(即:“B”)?
var a = [“A”, “B”, “C”, “D”];
答:a.splice(1,1);
ii. 如何删除数组a中最后一个元素?
var a = [“A”, “B”, “C”, “D”];
答:a.pop()
iii. 如何将“NEW”插入数组a的“B”和“C”之间?
var a = [“A”, “B”, “C”, “D”];
答:a.splice(2,0,”new”);
10、var stringArray = [“Hello”, “World”],给出您能想到的最好的方法输出“Hello World”。
答:stringArray.join(“ ”);
11、typeof输出的类型有哪些
答:A.number B.string C.null D.undefined
12、以下关于Array数组对象的说法不正确的是(c)
答:A.对数组里数据的排序可以用sort函数,如果排序效果非预期,可以给sort函数加一个排序函数的参数。
B.reverse用于对数组数据的倒序排列。
C.向数组的最后位置加一个新元素,可以用pop方法。
D.unshift方法用于向数组删除第一个元素。
13、javascrip的基本数据类型有哪些?(a,b,e,f,g)
答:A.number B.string C.object D.array E.null F.undefined G.boolean
14、下面有关浏览器中使用js跨域获取数据的描述。说法错误的是?(A)
A.域名,端口相同,协议不同,属于相同的域。
B.js可以使用jsonp进行跨域。
C.通过修改document.domain来跨子域。
D.使用window.name来进行跨域。
15、请写出打印出来的值。
var flag = true;
if (flag) {
var a = 10;
}
function fn() {
var b = 20;
c = 30;
}
fn();
console.log(a);
console.log©;
console.log(b);
答:10,30,报错(b是在fn内部定义,全局并没有b这个变量)
16、请分别使用原生js,jquery获取标签信息。(
答:
alert(typeof(null))//object
alert(typeof(NaN))//number
alert(typeof(undefined))//undefined
alert(typeof(“undefined”))//string
alert(NaN == undefined)//false
alert(NaN == NaN)//false
20、获取event目标对象的方法(要求兼容性)。
答:document.onclick = function (ev){
var e = ev||window.event;
}
21、请写出代码执行结果
var a;
alert(a); undefined______
alert(typeof a); undefined______________
alert(b); 报错_________________
22、请写一段json字符串,包含所有的数据类型.
答:{“a”:“string”,“b”:5,“c”:[1,2,3,4],“d”:{“e”:“obj”}}
23、请按执行顺序写出几次alert()语句a的值:
var a = 10;
function fn() {
alert(a);
var a = 100;
alert(a);
}
fn();
alert(a);
答:undefined,100,10
24、请按执行顺序写出几次alert()语句a的值:
function fn1(){
var a = 1;
function fn2(){
alert(a++);
}
fn2();
}
fn1();
fn1();
答:1,1
25、怎样添加,移除,移动,复制,创建和查找节点?
答:appendChild,removeChild,replaceChild,cloneNode,createElement,getElementById(ByTagName)
26、用js写一个正则匹配标签中是否包含一个class?
答:var className = “active”;
var reg = new RegExp(“\b"+className+"\b");
27、完善以下代码:
铝神公司
28、写一个函数,将一串字符串中空格替换”.”,如replace(“铝 神 欢 迎 你”)=“铝.神.欢.迎.你”
答:第一种:
function re(s){
return s.replace(/\s/g,".");
}
第二种:
function re(s){
return s.split(" “).join(”.");
}
29、对作用域上下文和this的理解,看下列代码:
var User = {
count:1,
getCount:function(){
return this.count;
}
};
console.log(User.getCount());//??
var func = User.getCount;
console.log(func());//??
答:1,undefined
30、HTTP状态码有哪些,分别代表什么意思?
答:如果是1开头的代表请求已被接受,需要继续处理
如果是2开头这一类型的状态码,代表请求已成功被服务器接收、理解、并接受
如果是3开头这类状态码代表需要客户端采取进一步的操作才能完成请求
如果是4开头这类的状态码代表了客户端看起来可能发生了错误,妨碍了服务器的处理
如果是5开头这类状态码代表了服务器在处理请求的过程中有错误或者异常状态发生,也有可能是服务器意识到以当前的软硬件资源无法完成对请求的处理
31、split() 和join()的区别
答:split是将字符串切割为数组,而join是将数组连接为字符串
32、事件绑定和普通事件有什么区别
答:区别就是普通事件只支持单个事件,而事件绑定可以添加多个事件
33、事件委托是什么,使用事件委托有什么好处?
答:就是让别人来做,这个事件本来是加在某些元素上的,然而你却加到别人身上来做,完成这个事件。
也就是:利用冒泡的原理,把事件加到父级上,触发执行效果。 好处呢:1,提高性能。
34、如何阻止事件冒泡和默认事件
答:阻止事件冒泡:ie:window.event.cancelBubble=true;而非ie:e.stopPropagation();
阻止默认事件:ie:window.event.returnValue = false;return false;而非ie:e.preventDefault();
35、编写一个数组去重的方法
答:Array.prototype.unique3 = function(){
var res = [];
var json = {};
for(var i = 0; i < this.length; i++){
if(!json[this[i]]){
res.push(this[i]);
json[this[i]] = 1;
}
}
return res;
}
36、如何实现多标签页之间的通讯。
答:调用 localstorge、cookies 等本地存储方式
37、简述什么是按需加载,然后实现一个图片按需加载的js。
答:图片的按需加载又称为延时加载,随着用户的滚动条滑动来按需获取图片。代码略,课件中有
38、什么是模块开发,怎么实现一个模块开发。
答:一个模块就是实现特定功能的文件,有了模块,我们就可以更方便地使用别人的代码,想要什么功能,就加载什么模块。
可以使用模块加载器比如sea.js或者require.js
39、怎么优化一个首屏的加载速度,可以从js和css等多方便考虑 吗?
答:可以
1.可以使用延迟加载,通过js将第二屏出现的图片设置问延迟加载,优先加载第一屏的图片,如果不想自己写js推荐一个lazyload这个插件
2.尽可能压缩图片大小,可以利用在线图片压缩工具tinypng
3.将JS放到HTML最后的地方,能最后加载,优先保证基础信息阅读。可以参考雅虎优化原则
40、在JavaScript中,以下哪个变量名是非法的(b)
A、Name B、9name C、Name_a D、Name9
41、请选择结果为真的表达式(c)
A、null instance Object B、null === undefined C、null == undefined D、NaN == NaN
42、var a = new Object();
a.value = 1;
b = a;
b.value = 2;
console.log(a.value);
输出正确的是:(b)
A、1 B、2 C、undefined D、以上都不正确
43、var a = 3;
(function() {
window.a = 2
var a = 1;
})()
console.log(a)
输出为:(b)
A、1 B、2 C、3 D、undefined
44、以下localStroage的使用方式,哪些是正确的?abe
A.localStorage. setItem(“lastname”, “smith”);
B.document.getElementById(“result”).innerHTML=loaclStorage.getItem(“lastname”);
C.localStorage.lastname=“Smith”;
D.document.getElementByid(“result”).innerHTML=localStorage.lastname;
E.localStorage.removeItem(“lastname”);
45、以下关于Array数组对象的说法不正确的是?c
A.对数组里数据的排序可以用sort函数,如果排序效果非预期,可以给sort函数加一个排序函数的参数.
B.reverser用于对数组数据的排序排列.
C.向数组的最后位置加一个新元素,可以用pop方法.
D.unshift方法用于向数组删除第一个元素.
46、var stringArray=[“Hello”,”World”],给出您能想到的最好的方法输出”Hello, World”
答:stringArray.join(“,”);
47、HTML5存储类型有哪些?
答:cookies:存储大小为4k
localstorage:以键值对(Key-Value)的方式存储,永久存储,永不失效,除非手动删除,大小为5m
sessionstorage:HTML5 的本地存储 API 中的 localStorage 与 sessionStorage 在使用方法上是相同的,区别在于 sessionStorage 在关闭页面后即被清空,而 localStorage 则会一直保存
离线缓存(application cache):本地缓存应用所需的文件
Web SQL:关系数据库,通过SQL语句访问
Web SQL 数据库 API 并不是 HTML5 规范的一部分,但是它是一个独立的规范,引入了一组使用 SQL 操作客户端数据库的 APIs。
48、谈谈对JOSN的了解
答:JSON的全称是”JavaScript Object Notation”,意思是JavaScript对象表示法,它是一种基于文本,独立于语言的轻量级数据交换格式
49、请描述一下cookies sessionStorage和localStorage的区别?
1.与cookie不同的是:Web Storage数据完全存储在客户端,不需要通过浏览器的请求将数据传给服务器,因此x相比cookie来说能够存储更多的数据,大概5M左右。
2.LocalStorage和sessionStorage功能上是一样的,但是存储持久时间不一样。
LocalStorage:浏览器关闭了数据仍然可以保存下来,并可用于所有同源(相同的域名、协议和端口)窗口(或标签页),
sessionStorage:数据存储在窗口对象中,窗口关闭后对应的窗口对象消失,存储的数据也会丢失。
注意:sessionStorage 都可以用localStorage 来代替,但需要记住的是,在窗口或者标签页关闭时,使用sessionStorage 存储的数据会丢失。
50、Flash,Ajax各自的优缺点,在使用中如何取舍?
答:参考http://blog.csdn.net/duandianyiwai/article/details/52127839
51、JavaScript中如何检测一个变量是一个String类型?请写出函数实现。
答:function isString (s) {
return typeof s === "string";
}
52、作PC端项目时,需要考虑哪些兼容性的问题?
答:浏览器兼容问题一:不同浏览器的标签默认的外补丁和内补丁不同
问题症状:随便写几个标签,不加样式控制的情况下,各自的margin 和padding差异较大。
碰到频率:100%
解决方案:CSS里 *{margin:0;padding:0;}
备注:这个是最常见的也是最易解决的一个浏览器兼容性问题,几乎所有的CSS文件开头都会用通配符*来设置各个标签的内外补丁是0。
浏览器兼容问题二:块属性标签float后,又有横行的margin情况下,在IE6显示margin比设置的大
问题症状:常见症状是IE6中后面的一块被顶到下一行
碰到频率:90%(稍微复杂点的页面都会碰到,float布局最常见的浏览器兼容问题)
解决方案:在float的标签样式控制中加入 display:inline;将其转化为行内属性
备注:我们最常用的就是div+CSS布局了,而div就是一个典型的块属性标签,横向布局的时候我们通常都是用div float实现的,横向的间距设置如果用margin实现,这就是一个必然会碰到的兼容性问题。
浏览器兼容问题三:设置较小高度标签(一般小于10px),在IE6,IE7,遨游中高度超出自己设置高度
问题症状:IE6、7和遨游里这个标签的高度不受控制,超出自己设置的高度
碰到频率:60%
解决方案:给超出高度的标签设置overflow:hidden;或者设置行高line-height 小于你设置的高度。
备注:这种情况一般出现在我们设置小圆角背景的标签里。出现这个问题的原因是IE8之前的浏览器都会给标签一个最小默认的行高的高度。即使你的标签是空的,这个标签的高度还是会达到默认的行高。
浏览器兼容问题四:行内属性标签,设置display:block后采用float布局,又有横行的margin的情况,IE6间距bug
问题症状:IE6里的间距比超过设置的间距
碰到几率:20%
解决方案:在display:block;后面加入display:inline;display:table;
备注:行内属性标签,为了设置宽高,我们需要设置display:block;(除了input标签比较特殊)。在用float布局并有横向的margin后,在IE6下,他就具有了块属性float后的横向margin的bug。不过因为它本身就是行内属性标签,所以我们再加上display:inline的话,它的高宽就不可设了。这时候我们还需要在display:inline后面加入display:talbe。
浏览器兼容问题五:图片默认有间距
问题症状:几个img标签放在一起的时候,有些浏览器会有默认的间距,加了问题一中提到的通配符也不起作用。
碰到几率:20%
解决方案:使用float属性为img布局
备注:因为img标签是行内属性标签,所以只要不超出容器宽度,img标签都会排在一行里,但是部分浏览器的img标签之间会有个间距。去掉这个间距使用float是正道。(我的一个学生使用负margin,虽然能解决,但负margin本身就是容易引起浏览器兼容问题的用法,所以我禁止他们使用)
浏览器兼容问题六:标签最低高度设置min-height不兼容
问题症状:因为min-height本身就是一个不兼容的CSS属性,所以设置min-height时不能很好的被各个浏览器兼容
碰到几率:5%
解决方案:如果我们要设置一个标签的最小高度200px,需要进行的设置为:{min-height:200px; height:auto !important; height:200px; overflow:visible;}
备注:在B/S系统前端开时,有很多情况下我们又这种需求。当内容小于一个值(如300px)时。容器的高度为300px;当内容高度大于这个值时,容器高度被撑高,而不是出现滚动条。这时候我们就会面临这个兼容性问题。
浏览器兼容问题七:透明度的兼容CSS设置
做兼容页面的方法是:每写一小段代码(布局中的一行或者一块)我们都要在不同的浏览器中看是否兼容,当然熟练到一定的程度就没这么麻烦了。建议经常会碰到兼容性问题的新手使用。很多兼容性问题都是因为浏览器对标签的默认属性解析不同造成的,只要我们稍加设置都能轻松地解决这些兼容问题。如果我们熟悉标签的默认属性的话,就能很好的理解为什么会出现兼容问题以及怎么去解决这些兼容问题。
/* CSS hack*/
我很少使用hacker的,可能是个人习惯吧,我不喜欢写的代码IE不兼容,然后用hack来解决。不过hacker还是非常好用的。使用hacker我可以把浏览器分为3类:IE6 ;IE7和遨游;其他(IE8 chrome ff safari opera等)
◆IE6认识的hacker 是下划线_ 和星号 *
◆IE7 遨游认识的hacker是星号 *
比如这样一个CSS设置:
height:300px;height:200px;_height:100px;
IE6浏览器在读到height:300px的时候会认为高时300px;继续往下读,他也认识heihgt, 所以当IE6读到*height:200px的时候会覆盖掉前一条的相冲突设置,认为高度是200px。继续往下读,IE6还认识_height,所以他又会覆盖掉200px高的设置,把高度设置为100px;
IE7和遨游也是一样的从高度300px的设置往下读。当它们读到*height200px的时候就停下了,因为它们不认识_height。所以它们会把高度解析为200px,剩下的浏览器只认识第一个height:300px;所以他们会把高度解析为300px。因为优先级相同且想冲突的属性设置后一个会覆盖掉前一个,所以书写的次序是很重要的。
Pc端的项目兼容问题主要集中ie6和ie7,而他们的市场份额已经非常低了,而且选择兼容他们会让我们代码变多,维护成本升高,不能使用css2.1或者3的高级命令等等。所以最好不要兼容ie6,7.
而如果要兼容ie8,那么在使用css3的时候一定要小心,因为ie8也是不兼容css3和html5的,所以建议在使用css3的时候要避免使用影响布局的css3属性.
在js中的兼容问题:
1)通过class获取标签:
function byClass(parents,className){
if (parents.getElementsByClassName){
return parents.getElementsByClassName(className);
}
var el=parents.getElementsByTagName("*");
var arr=[];
var reg=new RegExp("\\b"+className+"\\b");
// console.log(reg);
var arr=[];
for (var i=0; i
}
2)ready函数
function ready(fn){
if(document.addEventListener)
{
document.addEventListener(‘DOMContentLoaded’, fn, false);
}
else
{
var oS=document.createElement(‘script’);
oS.defer=true;
oS.onreadystatechange=function ()
{
if(oS.readyState=='complete')
{
fn();
}
};
var oHead=document.getElementsByTagName('head')[0];
oHead.appendChild(oS);
}
}
3) 事件绑定
function addEvent(obj,event,fn){
//现代:addEventLister 不用加on
//ie:touchEvent 需要加on
if (window.addEventListener){
obj.addEventListener(event,fn);
}else{
obj.attachEvent(“on”+event, fn);
}
}
4)获取样式
function getStyle(el,styleName){
if (el.currentStyle){
return el.currentStyle[styleName];
}else{
return getComputedStyle(el, null)[styleName];
}
}
5)ajax
function ajax(url,succFn,faultFn){
if (window.XMLHttpRequest){
var ajax=new XMLHttpRequest();
}else{
var ajax=new ActiveXObject("Msxml2.XMLHTTP");
}
ajax.open("get",url,true);
ajax.send();
ajax.onreadystatechange=function (){
if (ajax.readyState=="4"){
if (ajax.status>=200&&ajax.status<300||ajax.status==304){
if (succFn){
succFn(ajax.responseText);
}
}else{
if (faultFn){
faultFn(ajax.status);
}
}
}
}
}
53、PC端项目涉及到跨域,那么什么叫跨域?为什么需要跨域?跨域的方法有几种,都是什么原理?
答:
跨域简单的理解即为当前服务器目录下的前端需求要请求非本服务器(本域名)下的后台服务就称为跨域请求。跨域请求我们使用普通的ajax请求是无法进行的
由于同源策略,一般来说位于 server1.example.com 的网页无法与不是 server2.example.com的服务器沟通,或者说如果在server1.example.com下想获取server2.example.com的话就得用跨域请求
跨域的解决方法及解决:http://blog.csdn.net/joyhen/article/details/21631833
三、AJAX
1、ajax请求的时候get和post方式的区别
答:第一:ajax.open方法的第二个参数如果是get请求路径中是带有参数的,而post就只是路径
第二:如果是post方式在open方法和send方法之间还要设置请求的头:ajax.setRequestHeader(“Content-Type”, “application/x-www-form-urlencoded");
第三:ajax.send方法如果是get的话参数留空就行,而post需要将参数以序列化的格式传入
2、Ajax请求Json数据后如何解析
答:第一种:使用eval
第二种:使用JSON.parse()
第三种:new Function(“return” + strJSON)();
3、ajax出问题时怎么判断是前端的问题还是后台的
答:首先测试api是否能正常调用,比如可以模拟一些数据发送一下,如果是get请求就直接浏览器地址栏中拼接上然后看返回结果。在确认api调用正常的情况下,基本就可以确定是属于前端的问题。
4、向后台请求数据,有几种方式
答:用的最多的就是get和post.
除了这两个还有:
HEAD
类似于get请求,只不过返回的响应中没有具体的内容,用于获取报头
PUT
传说当前请求文档的一个版本
DELETE
发送一个用来删除指定文档的请求
TRACE
发送请求的一个副本,以跟踪其处理进程
OPTIONS
返回所有可用的方法;可检查服务器支持哪些方法
CONNECT
用于ssl隧道的基于代理的请求
5、什么是AJAX?同步异步的区别?
答:通过在后台与服务器进行少量数据交换,AJAX 可以使网页实现异步更新。这意味着可以在不重新加载整个网页的情况下,对网页的某部分进行更新
同步需要等待返回结果才能继续,异步不必等待,一般需要监听异步的结果
同步是在一条直线上的队列,异步不在一个队列上 各走各的