当前位置: 首页 > news >正文

杭州网站建设q479185700棒养殖业网站模板

杭州网站建设q479185700棒,养殖业网站模板,延安网站建设推广,论坛程序做导航网站一、Python基础部分 1. 数据类型 数字类型(Numbers)#xff1a; 整数(int), 浮点数(float), 复数(complex) 布尔(Booleans)#xff1a; True和False 字符串(Str)#xff1a;Uniconde字符序列, 在引号内包含 列表(list)#xff1a; 有序的值的序列 元组(Tuples)#x…一、Python基础部分 1. 数据类型 数字类型(Numbers) 整数(int), 浮点数(float), 复数(complex) 布尔(Booleans) True和False 字符串(Str)Uniconde字符序列, 在引号内包含 列表(list) 有序的值的序列 元组(Tuples) 有序的值的序列且不可改变 字典(Dictionaries) 无序的键值对的组合 集合(Sets) 无序的不含重复值的序列 2.字符串操作 - join() 字符串拼接 - index()/rindex() - find()/rfind() - title() - upper()/lower() - split() 默认一个或多个空格分隔 - capitalize() 首字母大小 - rjust(width, pad_str)/ljust() - encode() - startswith()/endswith() - replace()/strip() - isdigit()/isalpha()/isalnum()/isupper()/islower()/istitle() - format() - count(c)3. 列表操作 1、列表添加元素“增”append,extend,insert 2、修改元素通过修改已存在元素下标对应的值来进行修改元素 3、查找元素in,not in,index,count,查看指定的元素是否存在 4、删除元素del,pop,remove 5、排序sort,reverse 3.1 一次遍历获取列表中第二大的值 list1 [2, 3, 45, 6, 7, 83, 4, 56, 7] max_value list1[0] second_value list1[0] for i in list1:if i max_value:max_value ielif second_value i max_value:second_value i print(second_value) # 564. 列表添加元素append和extend之间的区别 a. append可以追加任意类型的元素而extend只能追加可迭代对象 b. 当添加可迭代对象的时候append会将整个可迭代对象添加进去但是extend只会添加可迭代对象中元素(打碎加入到列表末尾) c. 二者都是将元素追加到列表的末尾 d. 二者都是在原列表的基础上进行添加的 5. 深拷贝和浅拷贝 这个可以从赋值开始说 赋值(即)数据完全共享不同的变量指向同一块内存地址 可变数据类型 ---- 修改其中一个另一个也随之改变不可变数据类型 ---- 修改了其中一个另一个并不会改变 浅拷贝数据半共享(拷贝其数据另外开辟内存存放但是只拷贝成功第一层) 可变数据类型 ---- 修改其中一个另一个也随之改变不可变数据类型 ---- 修改了其中一个另一个并不会改变 a [2,3,4,[5,6,7]] b a.copy() print(a,id(a)) # [2, 3, 4, [5, 6, 7]] 2496163828808 print(b,id(b)) # [2, 3, 4, [5, 6, 7]] 2496168588808a[2] 9 print(a,id(a)) # [2, 3, 9, [5, 6, 7]] 2496163828808 print(b,id(b)) # [2, 3, 4, [5, 6, 7]] 2496168588808a[3][0]x print(a,id(a)) # [2, 3, 9, [x, 6, 7]] 2496163828808 print(b,id(b)) # [2, 3, 4, [x, 6, 7]] 2496168588808深拷贝数据不共享拷贝其数据完全独立存放另一内存空间两份数据之间互不影响 import copy a [2,3,4,[5,6,7]] b copy.deepcopy(a) print(a,id(a)) # [2, 3, 4, [5, 6, 7]] 2235721617032 print(b,id(b)) # [2, 3, 4, [5, 6, 7]] 2235721617096a[2] 9 print(a,id(a)) # [2, 3, 9, [5, 6, 7]] 2235721617032 print(b,id(b)) # [2, 3, 4, [5, 6, 7]] 2235721617096a[3][0]x print(a,id(a)) # [2, 3, 9, [x, 6, 7]] 2235721617032 print(b,id(b)) # [2, 3, 4, [5, 6, 7]] 22357216170966. 创建字典方法 # 方式一 dict1 {name:张三,age:10,score:100}# 方式二 dict2 {} dict2[name] 张三 dict2[age] 10 dict2[score] 88# 方式三 # dict(keyvalue....) dict3 dict(namelisi,age9,score66)# 方式四 # dict([(key1,value1),(key2,value2)....]) dict4 dict([(one,10),(two,20),(three,30)])# 方式五 # dict(zip(seq1所有的key,seq2所有的value))seq1和seq2可以是列表也可以是元组 dict5 dict(zip([111,222,333],[1,2,3]))dict5 dict(zip([111,222,333,444],[1,2,3])) print(dict5) # {111: 1, 222: 2, 333: 3}7. dict()和fromkeys的区别 d2 dict(zip([22,33],[a,b])) print(d2) #{22: a, 33: b}d2 dict.fromkeys([22,33],[a,b]) print(d2) #{22: [a, b], 33: [a, b]}8. 字典合并方式 (1)update 内置方法 user {name:xiao, age:22} gen {gender:male} user.update(gen) print(user) # {name: xiao, age: 22, gender: male} print(gen) # {gender: male}(2)dict.items()合并。 items方法将dict转成 dict_items再对这两个dict_items取并集利用 dict函数转成字典。 aaa {name:xiao, age:22} title {title:hello world} data dict(aaa.items()|title.items()) print(aaa.items()) # dict_items([(name, xiao), (age, 22)]) print(data) # {age: 22, name: xiao, title: hello world}(3)字典解析式 aaa {name:xiao, age:22} title {title:hello world} data {k:v for d in [aaa,title] for k,v in d.items()} print(data) # {name: xiao, age: 22, title: hello world}(4)itertools字典是可迭代对象可以使用 itertools.chain() 函数先将多个字典串联起来然后组成一个更大的可迭代对象在用dict 转成字典。 import itertools aaa {name:xiao, age:22} title {title:hello world} print(dict(itertools.chain(aaa.items(),title.items()))) # {name: xiao, age: 22, title: hello world} print(aaa.items()) # dict_items([(name, xiao), (age, 22)]) print(itertools.chain(aaa.items(),title.items())) # itertools.chain object at 0x000001F9E196DB889. 字典交换Key和Value——字典推导式 dict21 {value:key for key,value in dict1.items()} print(dict21)10. 可迭代对象和迭代器之间的区别和联系 可迭代对象Iterable可以直接作用于for循环的数据类型如list,tuple,dict,set,str,生成器等 迭代器Iterator可以直接作用于for循环或者可以通过next获取下一个元素的数据类型如生成器 联系 迭代器一定是可迭代对象可迭代对象不一定是迭代器 但是可以通过iter()将不是迭代器的可迭代对象在转换为迭代器 11. 迭代器和生成器的区别 迭代是访问集合元素的一种方式。迭代器是一个可以记住遍历位置的对象. 一个实现了__iter__方法和__next__方法的对象就是迭代器。 class MyIterator(object):def __init__(self, n):self.n nself.current 0# 自定义迭代器需要重写__iter__和__next__方法def __iter__(self):return selfdef __next__(self):if self.current self.n:value self.currentself.current 1return valueelse:raise StopIterationmy_it MyIterator(10) for i in my_it: # 迭代器重写了__iter__方法它本身也是一个可迭代对象print(i)迭代器核心功能 ​ 可以通过next()函数的调用来返回下一个数据值。如果每次返回的数据值不是在一个已有的数据集合中读取的而是通过程序按照一定的规律计算生成的那么也就意味着可以不用再依赖一个已有的数据集合也就是说不用再将所有要迭代的数据都一次性缓存下来供后续依次读取这样可以节省大量的存储内存空间。 例— 斐波那契数列 class FibIterator(object):斐波那契数列迭代器def __init__(self, n)::param n: int, 指明生成数列的前n个数self.n n# current用来保存当前生成到数列中的第几个数了self.current 0# num1用来保存前前一个数初始值为数列中的第一个数0self.num1 0# num2用来保存前一个数初始值为数列中的第二个数1self.num2 1def __next__(self):调用next()函数来获取下一个数if self.current self.n:num self.num1self.num1, self.num2 self.num2, self.num1self.num2self.current 1return numelse:raise StopIterationdef __iter__(self):迭代器的__iter__返回自身即可return selfif __name__ __main__:fib FibIterator(10)for num in fib:print(num, end ) 2生成器 生成器是一类特殊的迭代器 生成器实现方式 列表推导式[] — ()函数结合yield 在使用生成器实现的方式中我们将原本在迭代器__next__方法中实现的基本逻辑放到一个函数中来实现但是将每次迭代返回数值的return换成了yield此时新定义的函数便不再是函数而是一个生成器了。 简单来说只要在def中有yield关键字的 就称为 生成器 yield关键字有两点作用 保存当前运行状态断点然后暂停执行即将生成器函数挂起将yield关键字后面表达式的值作为返回值返回此时可以理解为起到了return的作用 可以使用next()函数让生成器从断点处继续执行即唤醒生成器函数 3区别 ①生成器是一类特殊的迭代器 ②迭代器是一个对象生成器是一个函数 11.列表生成式和列表推导式 列表生成式即推导式 列表生成式即List Comprehensions,是Python内置的非常简单却强大的可以用来创建list的生成式。 列表生成式的结构是在一个中括号里包含一个表达式,然后是一个for语句,然后是0个或多个for或者if语句。列表表达式可以是任意的,意思是你可以在列表中放入任意类型的对象。返回结果将是一个新的列表,在这个以if和for语句为上下文的表达式运行完成之后产生。 python # 普通生成列表 list1 [] for i in range(1, 11):list1.append(i * i) print(list1)# 列表生成式 list2 [i * i for i in range(1, 11)] print(list2)12. 高阶函数 概念函数的一个参数是函数或者返回值是一个函数,都可以称为高阶函数。 1map()函数接收两个参数一个是函数一个是序列。map将传入的函数依次作用到序列的每个元素并把结果作为新的序列返回。 2reduce():接收两个参数把函数作用在一个序列上reduce把 结果继续和序列下一个元素做累积计算。 def fun():return x*10yprint(reduce(fun,[1,2,3,4,5]))# 输出结果 123453filter()过滤函数:接收一个函数和一个序列filter函数把传入的函数依次作用于每个元素然后根据返回值 是True或False来决定保留或者丢弃该元素。 4sorted()接收一个序列和一个函数进行进行排序。 13. 装饰器 概念 在Python中不改变已有函数代码的前提下给函数增加新功能的一种函数。它的实质也是一种高阶函数。 装饰器的使用场景: 插入日志、性能测试、事务处理、缓存、权限校验等场景 收集函数的操作或错误日志记录验证函数的使用权限计算函数的运行时间在ORM/DB模型操作时通过属性方法动态地获取关联的数据函数数据的缓存定制函数的输入和输出序列化和反序列化 # 需求书写一个装饰器可以统计任意一个函数的执行时间 import timedef get_time(func):def inner(*args,**kwargs):# 开始时间start time.time() #获取时间差#调用原函数func(*args,**kwargs)# 结束时间end time.time()result round(end - start,3)return resultreturn innerget_time def check():for i in range(1000000):pass print(check()) 简单装饰器 import loggingdef use_logging(func):def wrapper():logging.warning(%s is running % func.__name__)return func()return wrapperuse_logging def func():print(i am func)func()# 输出 i am foo WARNING:root:func is running被装饰函数有参数 import loggingdef use_logging(func):def wrapper(*args, **kwargs):logging.warning(%s is running % func.__name__)return func(*args, **kwargs)return wrapperuse_logging def func(x):print(i am func,i have %s % x)func(参数)# 输出 WARNING:root:func is running i am func,i have 参数带参数的装饰器 def deco_para(parameter): # 接收装饰器参数def deco_func(func): # 接收被装饰函数def wrapper(*args, **kwargs): # 接收被装饰函数参数print(parameter)func(*args, **kwargs)print(看看打印顺序)return wrapperreturn deco_funcdeco_para(i am decorator arguments) def foo(x):print(i am foo, i have %s % x)if __name__ __main__:foo(参数)Python内置的装饰器 property/name.setter 属性方法classmethodstaticmethodasyncio.coroutineabc.abstractmethodabc.abstractclassmethodabc.abstractstaticmethodclassonlymethod 14. Python的垃圾回收机制 Python中存在三种内存回收机制 引用计数 标记清除 分代回收 在python中维护了一个refchain的双向环状链表这个链表存储程序中创建的所有对象每种类型的对象都有一个 ob_refcnt 的引用计数器对象被引用则计数器的值 1引用被删除则计数器的值 -1最后引用计数的值为 0 时会进行垃圾回收对象销毁、从refchain中移除 但是在python中对于那些可以有多个元素组成的对象可能会存在循环引用问题为了解决这个问题python引入了 标记清除 在其内部再维护了一个链表专门放那些可能存在循环引用的对象 (list/tuple/dict/set) 某种情况下 触发会去扫描 可能存在循环引用的链表中的每一个元素检查是否有循环引用如果有则双方的引用计数器 -1如果是 0 则垃圾回收 然而又有一个新的问题产生就是什么时候扫描可能存在循环引用的链表扫描代价较大每次扫描耗时久所以又引入了 分代回收 将可能存在循环引用对象维护成 3 个链表分别是 0代1代2代所有可能存在循环引用的对象都存储在 0代链表当对象个数达到700个的时候扫描一次是垃圾则回收不是则移入 1代依次类推0代扫描10次1代扫描一次1代扫描10次2代扫描1次。 15. 匿名函数优缺点 匿名函数 一个lambda表达式本质上还是一个函数可以设置参数也可以调用表达式本身就是函数的 运算结果 优点 简化代码 减少内存空间的使用 缺点 只能实现简单的逻辑逻辑一旦复杂代码的可读性会降低则不建议使用 16. 类属性(字段)和对象属性(字段)的区别和联系 a. 定义位置不同类属性直接定义在类中对象属性对象动态绑定或者定义在构造函数中 b. 访问方式不同类属性可以通过对象或者类访问对象属性只能通过对象访问 c. 在内存中出现的时机不同类属性随着类的加载出现在内存中对象属性随着对象的创建出现在内存中 类属性优先于对象属性出现在内存中 d. 优先级不同当类属性和对象属性重名的情况下对象属性的优先级高于类属性 e. 使用场景不同是多个对象共享的数据则定义为类属性如果是各个对象不同的数据则定义为对象属性 17. 普通函数和__init__的区别和联系 不同点 a. 函数名不同普通函数的函数名可以自定义但是__init__是固定的不能随意更改。 b. 调用不同普通函数必须手动调用__init__是在创建对象的过程中自动调用的。 c. 调用的次数对于同一个对象而言__init__只会被调用一次但是普通函数可以被无数次调用。 相同点 a. 定义在类中形参列表的第一个参数为self。都被称为实例函数。 b. 形参列表仍然可以设置默认参数不定长参数实参列表也可以设置关键字参数。 c. 也可以设置返回值。 18. 实例函数类函数和静态函数区别和联系 相同点 本质都是函数所以默认参数关键字参数不定长参数都可以正常使用也可以设置返回值 不同点 a. 是否有装饰器类函数需要被classmethod修饰静态函数需要被staticmethod修饰实例函数不需要任何装饰器 b. 参数列表类函数的第一个参数必须为cls实例函数的第一个参数必须为self静态函数的参数没有要求 c. 调用方式类函数和静态函数可以通过类名或者对象调用实例函数只能通过对象调用 d. 使用场景不同 静态函数(staticmethod): 即静态方法,主要处理与这个类的逻辑关联, 如验证数据; 类函数(classmethod):即类方法, 更关注于从类中调用方法, 而不是在实例中调用方法, 如构造重载; 成员函数: 实例的方法, 只能通过实例进行调用; 19. 线程和进程的区别 一个运行程序就是一个进程一个进程至少包含一个线程进程是由操作系统分配资源进程之间的内存是相互独立的如果需要在多个进程间通信的话可以使用管道/队列/共享内存/信号/linux socket 线程是属于某一个进程的线程是应用程序中工作的最小单元而属于同一个进程多个线程之间的内存是共享的那么就会出现内存资源的安全问题python为了线程安全就设置了全局解释器锁(GIL)机制既一个进程中同时只能有一个线程访问cpu 全局解释器锁GIL 同一进程中假如有多个线程运行一个线程在运行python程序时会霸占python解释器加一把锁即GIL使该进程内的其他线程无法运行等该线程运行完后其他线程才能运次行。如果线程运行过程中出现耗时操作则解释器锁打开使其他线程运行所以在多进程中线程的运行仍是有先后顺序的并不是同时运行。 Lock和Rlock区别 由于线程之间是进行随机调度并且每个线程可能只执行n条执行之后当多个线程同时修改同一条数据时可能会出现脏数据所以出现了线程锁 - 同一时刻允许一个线程执行操作。 acquire  给线程上锁release  给线程解锁 无论是lock还是rlock提供的方法都非常简单acquire和release。但是rlock和lock的区别是什么呢**RLock允许在同一线程中被多次acquire。而Lock却不允许这种情况。**注意如果使用RLock那么acquire和release必须成对出现即调用了n次acquire必须调用n次的release才能真正释放所占用的锁。 20. 协程 asyncio 正是由于python多线程的缺陷需要引入协程的概念。 协程是一种用户态的轻量级线程线程和进程由CPU调度 协程由用户开发者或程序本身来调度的。 协程存在的意义对于多线程应用CPU通过切片的方式来切换线程间的执行线程切换时需要耗时保存状态下次继续。协程则只使用一个线程在一个线程中规定某个代码块执行顺序。 协程的适用场景当程序中存在大量不需要CPU的操作时IO适用于协程 协程的发展阶段 - 第一阶段 yield和send的生成器的关键字来实现用户自我调度 - 第二阶段(python3.4) asyncio.coroutine 和 yield from - 第三阶段(python3.5) async 和 await 两个关键【注】第二和第三阶段使用asynio模块 协程的对象必须事件循环对象中运行。- 使用asyncio模块 - 函数上方使用asyncio.coroutine或async关键字使得变成协程对象 - 在协程函数中使用yield from 或 await关键字告知事件模型当前协程等待其它协程完成任务 - 协程对象需要在事件模型中运行- loop asyncio.get_event_loop() 获取事件模型对象- loop.run_until_complete(协程对象)- 协程对象默认是单任务- 多个协程对象可以通过列表方式和asynio.wait()函数封装多任务协程对象21.创建线程的方法 Python3.x通过Threading模块创建新的线程有两种方法 通过threading.Thread(targetexecutable Method)即通过传递给Thread对象一个可执行方法或对象 通过继承 threading.Thread 定义子类创建多线程 使用 threading 模块创建多线程直接从 threading.Thread 继承然后重写__init__() 方法和 run() 方法 import threading import timeclass MyThread(threading.Thread): #继承父类threading.Threaddef __init__(self, threadID, name, counter):threading.Thread.__init__(self)self.threadID threadIDself.name nameself.counter counterdef run(self): #把要执行的代码写到run函数里面线程在创建后会直接运行runprint(开始运行 self.name)print(self.name, self.counter, 5)print(结束运行 self.name)def print_time(threadName, delay, counter):while counter:time.sleep(delay)print(%s 进程 在 % (threadName, time.ctime(time.time())))counter - 1#创建新线程 thread_1 MyThread(1, Thread-1, 1) thread_2 MyThread(2, Thread-2, 2)#开启线程 thread_1.start() thread_2.start()#等待线程结束 thread_1.join() thread_2.join()应用场景 做登录业务时使用到sms短信网关业务,创建子线程,让子线程去调用sms服务,主线程则返回,这样做可以提高用户的体验度多线程爬虫有些时候比如下载图片因为下载图片是一个耗时的操作。如果采用之前那种同步的方式下载。那效率肯会特别慢。这时候我们就可以考虑使用多线程的方式来下载图片。Redis 默认rdb持久化时为了性能最大化让子进程来完成写操作让主进程继续处理命令所以是 IO 最大化。使用单独子进程来进行持久化主进程不会进行任何 IO 操作保证了 redis 的高性能 22. 线程本地变量和条件变量 线程本地变量 因为多线程是共享同一个进程的内存如果数据仅用于当前线程时可以基于threading.local类实现线程私有数据。线程条件变量 多线程共同修改某一个数据对象时为了使得数据更安全一致性可以使用 threading.Condition条件变量类。它具有对共享数据的加锁、解锁功能也可以在数据不满足条件时让当前线程挂载反之满足条件时可以唤醒其它挂起的线程。23. 多任务的4种实现方式 a.多进程模式启动多个进程每个进程虽然只有一个线程但多个进程可以一块执行多个任务 b.多线程模式启动一个进程在一个进程内启动多个线程这样多个线程也可以一块执行多个任务 c.协程模式启动一个进程启动一个线程但是借助于函数生成器【yield】可以执行多个子任务 d.多进程多线程模式启动多个进程每个进程再启动多个线程这样同时执行的任务就更多了 24. 创建进程的方法 1. os.fork创建 只支持Linux/Unix系统 2. os.system(cmd) 创建子进程来执行cmd描述的操作系统命令但无法获取命令执行的结果 3. os.popen(cmd) 创建子进程来执行cmd命令可以获取命令执行的结果。引用subprocessing.Popen类。 4. multiprocssing.Process类创建子进程需要重写run方法来实现自己的业务。25. fork的优缺点 fork的缺点 a. 兼容性差只能在Linux下使用Windows系统无法使用 b. 扩展性差当创建多个进程对象的时候管理较为复杂 c. 会产生“孤儿”进程或者“僵尸”进程需要手动回收系统资源 fork的优点 是系统自带的更加接近底层的创建进程的方式运行效率高 26. 文件操作Open 默认打开模式 r 只读-权限 t 文本-文件类型 常用模式的组合 r 读写文本如果文件不存在则会报错异常rb 读写字节数据媒体文件 图片、音频、视频、office文件 如果文件不存在则报错w 读写文本 如果文件不存在则会自动创建a/ab 追加文本或字节数据如果文件不存在则会创建。encoding参数 只针对读取文本数据模式 即指定文本数据的编码名词 如果是b模式时则不需要指定这个参数如果指定则会抛出异常。27. with上下文 with 是Python中管理上下文环境时的关键字 当某一个对象在使用with时则会存在两个节点即当对象进入上下文时则调用对象的__enter__()方法此方法返回一个对象在with表达式中通过as关键字来接收这个对象。当代码执行完则会退出上下文此时会调用对象的__exit__()方法。 28. 单例 Singleton 解决问题 无论类实例化多少次只有一个实例对象。 class Singleton:def __init__(self, name, phone):self.name nameself.phone phonedef save(self):print(self.name, self.phone)def __new__(cls, *args, **kwargs):if not hasattr(cls, instance):cls.instance super().__new__(cls)return cls.instance s1 Singleton(disen, 17791692095) s2 Singleton(jack, 17791692094) s3 Singleton(lucy, 17791692093)s1.save() s2.save() s3.save()29. __init__,__new__和__call__三者的区别 __init__ 是初始化实例对象的是__new__返回对象之后调用的。 __new__ 是创建实例对象的它是一个静态方法。调用父类时只传入一个cls对象即可。用来分配内存空间它的返回值传递给__init__的第一个参数self __call__ 当实例对象被作为函数调用时对象会调用__call__()用法这种机制一般会用于装饰器类中。30. logging日志模块的常用Handler处理器类 日志是用于记录Logger程序中的一些重要信息的记录的信息按等级(Level)交给特定的处理器Handler按一定的格式Formatter进行处理打印、文件保存、上传网络和发送邮件等。 - logging.StreamHandler 输出流 - logging.FileHandler 输出到文件 - logging.handlers.SMTPHandler 通过SMTP邮件协议向指定的邮箱发送日志信息 - logging.handlers.HTTPHandler 通过HTTP Web协议向指定WEB服务器上传日志信息 - logging.handlers.TimedRotatingFileHandler 时间分隔的日志文件处理器。31. re模块中常用的函数 compile(pattern, flags) 生成正则对象一次生成对象可以被多次调用。match(pattern, string, flags0) 如果pattern正则表达式匹配了string内容则返回match对象反之返回None。一般用于验证string的完整性手机号、身份证、邮箱。search(pattern, string, pos0, flags0) 默认从pos的索引下标开始, 匹配第一次的内容findall(pattern, string, flags0) 查找所有与正则匹配的数据返回list。sub(pattern, replace_str, string, flags0) 在string文本中使用replace_str替换正则匹配的内容 32. 正则的转义字符 \d 任意一个数字 表示[0-9] \D 非任意一个数字 \w 任意一个数字、字母、下划线或中文【Python中】 ,表示 [a-zA-Z0-9_] \W 非任意一个数字、字母、下划线或中文 \s 任意一个空白Space空格、Tab制表符、Enter换行符等 \S 非任意一个空白33. 常用魔术方法 魔术方法就是一个类/对象中的方法和普通方法唯一的不同时普通方法需要调用而魔术方法是在特定时刻自动触发。 1.__init__ 初始化魔术方法 触发时机初始化对象时触发不是实例化触发但是和实例化在一个操作中 参数至少有一个self接收对象 返回值无 作用初始化对象的成员 注意使用该方式初始化的成员都是直接写入对象当中类中无法具有2.__new__ 实例化魔术方法 触发时机 在实例化对时触发 参数至少一个cls 接收当前类 返回值必须返回一个对象实例 作用实例化对象 注意实例化对象是Object类底层实现其他类继承了Object的__new__才能够实现实例化对象。 没事别碰这个魔术方法先触发__new__才会触发__init__ 3.__del__ 析构魔术方法 触发时机当对象没有用没有任何变量引用的时候被触发 参数一个self 结婚搜对象 返回值无 作用使用完对象是回收资源 注意del不一定会触发当前方法只有当前对象没有任何变量接收时才会触发4.__call__ 调用对象的魔术方法 触发时机:将对象当作函数调用时触发 对象() 参数:至少一个self接收对象其余根据调用时参数决定 返回值根据情况而定 作用可以将复杂的步骤进行合并操作减少调用的步骤方便使用 注意无5.__len__ 触发时机使用len(对象) 的时候触发 参数一个参数self 返回值必须是一个整型 作用可以设置为检测对象成员个数但是也可以进行其他任意操作 注意返回值必须必须是整数否则语法报错另外该要求是格式要求。6.__str__ 触发时机:使用print(对象)或者str(对象)的时候触发 参数一个self接收对象 返回值必须是字符串类型 作用print对象时进行操作得到字符串通常用于快捷操作 注意无7.__repr__ 触发时机:在使用repr(对象)的时候触发 参数一个self接收对象 返回值必须是字符串 作用将对象转使用repr化为字符串时使用也可以用于快捷操作repr函数和str函数处理字符串只有一个区别 str的结果 字符串本身 结果可以被eval执行 如x ‘无图言Diao’ str() -无图言Diao rerpr的结果 字符串定义结构 eavl不会执行repr结果 如x ‘无图言Diao’ repr() -‘无图言Diao’ 备注: 在类中通常情况下__str__和__repr__ 设置相同即可 eval() 函数 将字符串当作python代码执行 格式eval(字符串) 返回值可以有返回值 8.__bool__ 触发时机: 使用bool(对象)的时候触发 参数一个self接收对象 返回值必须是布尔值 作用根据实际情况决定可以作为快捷方式使用 注意:仅适合于返回布尔值的操作9.__format__ 触发时机使用字符串.format(对象)时候触发 参数一个self接收对象一个参数接收format的{}中的格式例如:5 返回值:必须是字符串 作用设置对象可以作为format的参数并且自定义对象格式化的规则 注意无二、网络协议 1. TCP和UDP之间的区别 TCP: Transmission Control Protocol 传输控制协议,基于字节流的传输层通信协议 a. 可靠的【确保接收方完全正确地获取发送方所发送的全部数据】 b. 面向连接的【面向连接的协议数据传输必须建立连接所以TCP需要连接时间】要任何装饰器 c. 数据传输的效率较低 d. 传输数据大小限制一旦连接建立双方可以按统一的格式传输大的数据 UDP: Transmission Control User Datagram Protocol的简称用户数据包协议提供面向事务的简单不可靠信息传送服务 a. 不可靠的【所发送的数据报并不一定以相同的次序到达接收方UDP将数据包发送给对方,对方不一定能接受到】,比如飞秋 b. 无连接的【每个数据报中都给出了完整的地址信息因此无需要建立发送方和接收方的连接】 c. 效率高速度快 d. UDP传输数据时是有大小限制的每个被传输的数据报必须限定在64KB之内 2. TCP/IP协议三次握手和四次挥手 三次握手 概念指在发送数据的准备阶段服务器和客户端之间需要三次 第一次握手建立连接时客户端向服务器发送一个SYN包并进入SYN_SENT状态等待服务器确认 第二次握手当服务器收到客户端的请求后此时要给客户端给一个确认信息ACK,同时发送SYN包此时服务器进入 SYN_RECV状态 第三次握手客户端收到服务器发的ACKSYN包后向服务器发送ACK,发送完毕之后客户端和服务器进入 ESTABLISHED(TCP连接成功)状态完成三次握手socket里面的客户端的connect 服务端的accept 就实现了三次握手四次挥手 概念四次挥手就是说关闭TCP连接的过程当断开一个TCP连接时需要客户端和服务器共发送四个包确认 第一次挥手客户端发送一个FIN,用来关闭客户端到服务器的数据传输客户端进入FIN_WAIT_1状态 第二次挥手服务器收到FIN后发送一个ACK给客户端确认序号为收到序号1与SYN相同一个FIN占用一个序 号服务器进入CLOSE_WAIT状态 第三次挥手服务器发送一个FIN,用来关闭服务器到客户端的数据传输服务器进入LAST_ACK状态 第四次挥手客户端收到FIN后客户端进入TIME_WAIT状态接着发送一个AKC给服务器确认序号为收到序号1服务器进入CLOSED状态完成四次挥手socket里面的客户端的colse和服务端conn的colse实现四次挥手3. socket 所有的Web应用本质上就是一个socket服务端而用户的浏览器就是一个socket客户端基于请求做出响应客户都先请求服务端做出对应的响应按照http协议的请求协议发送请求服务端按照http协议的响应协议来响应请求这样的网络通信我们就可以自己实现Web框架了。 通过对socket的学习我们知道网络通信我们完全可以自己写了因为socket就是做网络通信用的下面我们就基于socket来自己实现一个web框架写一个web服务端让浏览器来请求并通过自己的服务端把页面返回给浏览器浏览器渲染出我们想要的效果 socket参数的详解 socket.socket(familyAF_INET,typeSOCK_STREAM,proto0,filenoNone)# 创建socket对象的参数说明family地址系列应为AF_INET(默认值),AF_INET6,AF_UNIX,AF_CAN或AF_RDS。 AF_UNIX 域实际上是使用本地 socket 文件来通信type套接字类型应为SOCK_STREAM(默认值),SOCK_DGRAM,SOCK_RAW或其他SOCK_常量之一。 SOCK_STREAM 是基于TCP的有保障的即能保证数据正确传送到对方面向连接的SOCKET多用于资料传送。 SOCK_DGRAM 是基于UDP的无保障的面向消息的socket多用于在网络上发广播信息。proto协议号通常为零,可以省略,或者在地址族为AF_CAN的情况下,协议应为CAN_RAW或CAN_BCM之一。fileno如果指定了fileno,则其他参数将被忽略,导致带有指定文件描述符的套接字返回。 与socket.fromfd()不同,fileno将返回相同的套接字,而不是重复的。 这可能有助于使用socket.close()关闭一个独立的插座。 server.py import socketsk socket.socket() # 创建一个server端的对象 sk.bind((127.0.0.1,9001)) # 给server端绑定一个地址 sk.listen() # 开始监听(可以接收)客户端给我的连接了conn,addr sk.accept() # 建立连接 conn是连接 conn.send(bhello) # 发送消息 msg conn.recv(1024) # 接收消息 print(msg) conn.close() # 关闭连接sk.close()client.py import socketsk socket.socket() sk.connect((127.0.0.1,9001))msg sk.recv(1024) print(msg) sk.send(bbyebye)sk.close()4. 简述HTTP协议的Content-Type、Content-Length、Content-Disposition 三者都是HTTP协议的报文头的属性分别代表 - Content-Type: 报文中body的数据类型,常见有text/html、text/css、image/png、application/json、application/javascript、application/x-www-form-urlencoded和multi/form-data等。 - Content-Length: 报文body的数据字节长度。 - Content-Disposition: 响应报文的弹出窗口的附加信息如下载文件时显示文件的名称等。一般同Content-Type为application/octet-stream组合使用它的value为attachment;filenamexxx.png5. C10K问题及解决方案 C10K: 高并发问题 即在某一个时间段内同时存在至少1万个任务需要处理。在HTTP协议中由于受到响应时间的限制用户体验因此存在高并发问题。解决方案 Celery 消息队列Redis/RabbitMQ/Kafka)2. 自定义后台进程消息队列 6. Session与Cookie的区别 由于HTTP协议是无状态的Cookie是前端如浏览器存储数据的技术 浏览器访问服务端带着一个空的cookie然后由服务器产生内容浏览器收到相应后保存在本地 当浏览器再次访问时浏览器会自动带上Cookie这样服务器就能通过Cookie的内容来判断这个是“谁”了。 Session的技术基于CookieSession一般将当前会话-连接业务的数据当客户端与服务器第一次连接时服务端则会为当前的连接创建一个唯一标识session_id/sessionid/jsessionid,并将唯一标识以Cookie的方式响应给客户端客户端则默认存储。客户端在下一次发起请求时默认将当前站点保存的Cookie附加到请求头上向服务端发起请求。在服务端可以验证当前的SessionID,确认当前的连接是哪一个并从中读取相关的数据之前保存或操作的数据。如果前端将Cookie清空则SessionID标识的会话连接则无效当连接服务端会重新创建sessionId。如果前端禁用的Cookie功能则无法创建持久连接即Session功能无效。7. 写出HTTP协议的请求与响应的报文第一行 请求报文 GET path HTTP/1.1 GET请求方法 path是请求路径默认是/; HTTP协议HTTPs, 1.1版本号响应报文 HTTP/1.1 200 OK ,如 HTTP/1.1 400 Bad Request8. 跨域问题及解决的办法 跨域 当前的请求目标url和当前的服务不属于同源协议相同、host主机相同、端口相同。 解决办法1. 服务器端解决 配置Options请求的响应头. 【建议解决】Access-Control-Allow: *或白名单的IP地址Access-Control-Headers: 可以发起的跨域请求头Access-Control-Credentials: 是否支持安全请求Access-Control-Methods: 允许请求的方法 如Options/GET/POST/PUT/Delete在Django中使用django-cors-headers第三方库插件配置在Flask 使用flask-cors第三方库修饰Flask的实例2. 客户端解决办法 代理Nodejs可以配置 Proxy3. 客户端jsonp9. HTTP协议 HTTP协议是Hyper Text Transfer Protocol超文本传输协议的缩写,是用于从万维网WWW:World Wide Web 服务器传输超文本到本地浏览器的传送协议。 HTTP是一个基于TCP/IP通信协议来传递数据HTML 文件, 图片文件, 查询结果等。 HTTP协议工作于客户端-服务端架构为上。浏览器作为HTTP客户端通过URL向HTTP服务端即WEB服务器发送所有请求。Web服务器根据接收到的请求后向客户端发送响应信息。 无连接无连接的含义是限制每次连接只处理一个请求。服务器处理完客户的请求并收到客户的应答后即断开连接。采用这种方式可以节省传输时间 无状态HTTP协议是无状态协议。无状态是指协议对于事务处理没有记忆能力。缺少状态意味着如果后续处理需要前面的信息则它必须重传这样可能导致每次连接传送的数据量增大。另一方面在服务器不需要先前信息时它的应答就较快。 9.1 请求方法 常用 GETSELECT从服务器取出资源一项或多项。(它本身不会对资源本身产生影响因此满足 幂等性) POSTCREATE在服务器新建一个资源。 (它会对资源本身产生影响每次调用都会有新的资源产生因此 非幂等性) PUTUPDATE在服务器更新资源客户端提供改变后的完整资源。(它直接把实体部分的数据替换到服务器的资源多次调用它只会产生一次影响所以满足 幂等性) PATCHUPDATE在服务器更新资源客户端提供改变的属性。(非幂等) DELETEDELETE从服务器删除资源。 (调用一次和多次对资源产生影响是相同的所以也满足 幂等性)不常用 HEAD获取资源的元数据。 OPTIONS获取信息关于资源的哪些属性是客户端可以改变的(跨域时易见到)。幂等性 HTTP 幂等方法是指无论调用多少次都不会有不同结果的 HTTP 方法。不管你调用一次还是调用一百次一千次结果都是相同的9.2 HTTP工作原理 HTTP协议定义Web客户端如何从Web服务器请求Web页面以及服务器如何把Web页面传送给客户端。HTTP协议采用了请求/响应模型。 客户端向服务器发送一个请求报文请求报文包含: 请求的方法、URL、协议版本、请求头部和请求数据。 服务器以一个状态行作为响应响应的内容包括: 协议的版本、成功或者错误代码、服务器信息、响应头部和响应数据。 以下是 HTTP 请求/响应的步骤 1、客户端连接到Web服务器 一个HTTP客户端通常是浏览器与Web服务器的HTTP端口默认为80建立一个TCP套接字连接。 2、发送HTTP请求 通过TCP套接字客户端向Web服务器发送一个文本的请求报文一个请求报文由请求行、请求头部、空行和请求数据4部分组成。 3、服务器接受请求并返回HTTP响应 Web服务器解析请求定位请求资源。服务器将资源复本写到TCP套接字由客户端读取。一个响应由状态行、响应头部、空行和响应数据4部分组成。 4、释放连接TCP连接 若connection 模式为close则服务器主动关闭TCP连接客户端被动关闭连接释放TCP连接;若connection 模式为keepalive则该连接会保持一段时间在该时间内可以继续接收请求; 5、客户端浏览器解析HTML内容 客户端浏览器首先解析状态行查看表明请求是否成功的状态代码。然后解析每一个响应头响应头告知以下为若干字节的HTML文档和文档的字符集。客户端浏览器读取响应数据HTML根据HTML的语法对其进行格式化并在浏览器窗口中显示。 例如在浏览器地址栏键入URL按下回车之后会经历以下流程 1、浏览器向 DNS 服务器请求解析该 URL 中的域名所对应的 IP 地址; 2、解析出 IP 地址后根据该 IP 地址和默认端口 80和服务器建立TCP连接; 3、浏览器发出读取文件(URL 中域名后面部分对应的文件)的HTTP 请求; 4、服务器对浏览器请求作出响应并把对应的 html 文本发送给浏览器; 5、释放 TCP连接; 6、浏览器将该 html 文本渲染并显示内容; 10. HTTP请求状态码表 状态码状态码英文名称中文描述100Continue继续客户端应继续其请求101Switching Protocols切换协议。服务器根据客户端的请求切换协议。只能切换到更高级的协议例如切换到HTTP的新版本协议200OK请求成功。一般用于GET与POST请求201Created已创建。成功请求并创建了新的资源202Accepted已接受。已经接受请求但未处理完成203Non-Authoritative Information非授权信息。请求成功。但返回的meta信息不在原始的服务器而是一个副本204No Content无内容。服务器成功处理但未返回内容。在未更新网页的情况下可确保浏览器继续显示当前文档205Reset Content重置内容。服务器处理成功用户终端例如浏览器应重置文档视图。可通过此返回码清除浏览器的表单域206Partial Content部分内容。服务器成功处理了部分GET请求300Multiple Choices多种选择。请求的资源可包括多个位置相应可返回一个资源特征与地址的列表用于用户终端例如浏览器选择301Moved Permanently永久移动。请求的资源已被永久的移动到新URI返回信息会包括新的URI浏览器会自动定向到新URI。今后任何新的请求都应使用新的URI代替302Found临时移动。与301类似。但资源只是临时被移动。客户端应继续使用原有URI303See Other查看其它地址。与301类似。使用GET和POST请求查看304Not Modified未修改。所请求的资源未修改服务器返回此状态码时不会返回任何资源。客户端通常会缓存访问过的资源通过提供一个头信息指出客户端希望只返回在指定日期之后修改的资源305Use Proxy使用代理。所请求的资源必须通过代理访问306Unused已经被废弃的HTTP状态码307Temporary Redirect临时重定向。与302类似。使用GET请求重定向400Bad Request客户端请求的语法错误服务器无法理解401Unauthorized请求要求用户的身份认证402Payment Required保留将来使用403Forbidden服务器理解请求客户端的请求但是拒绝执行此请求404Not Found服务器无法根据客户端的请求找到资源网页。通过此代码网站设计人员可设置您所请求的资源无法找到的个性页面405Method Not Allowed客户端请求中的方法被禁止406Not Acceptable服务器无法根据客户端请求的内容特性完成请求407Proxy Authentication Required请求要求代理的身份认证与401类似但请求者应当使用代理进行授权408Request Time-out服务器等待客户端发送的请求时间过长超时409Conflict服务器完成客户端的 PUT 请求时可能返回此代码服务器处理请求时发生了冲突410Gone客户端请求的资源已经不存在。410不同于404如果资源以前有现在被永久删除了可使用410代码网站设计人员可通过301代码指定资源的新位置411Length Required服务器无法处理客户端发送的不带Content-Length的请求信息412Precondition Failed客户端请求信息的先决条件错误413Request Entity Too Large由于请求的实体过大服务器无法处理因此拒绝请求。为防止客户端的连续请求服务器可能会关闭连接。如果只是服务器暂时无法处理则会包含一个Retry-After的响应信息414Request-URI Too Large请求的URI过长URI通常为网址服务器无法处理415Unsupported Media Type服务器无法处理请求附带的媒体格式416Requested range not satisfiable客户端请求的范围无效417Expectation Failed服务器无法满足Expect的请求头信息500Internal Server Error服务器内部错误无法完成请求501Not Implemented服务器不支持请求的功能无法完成请求502Bad Gateway作为网关或者代理工作的服务器尝试执行请求时从远程服务器接收到了一个无效的响应503Service Unavailable由于超载或系统维护服务器暂时的无法处理客户端的请求。延时的长度可包含在服务器的Retry-After头信息中504Gateway Time-out充当网关或代理的服务器未及时从远端服务器获取请求505HTTP Version not supported服务器不支持请求的HTTP协议的版本无法完成处理 三、MySQL相关知识 1. 数据库的认知 关系型数据库 SQLServer(字符集 GBK/GB2312)、MySQL版本 5.5 5.6、5.7 8.0、Oracle9i/10g/11g, 12c、DB2、 MariDB同MySQL是一个开发者等。 非关系型数据库 redis、mongodbjs、elasticsearch 全文检索引擎Lucene 大数据库 hive、hbase、sparkHadoop2.MySQL数据库支持的引擎 可以通过show engines语句查看MySQL支持的引擎 InnoDB 支持事务、外键、行锁 MyISAM 普通引擎不支持事务和外键 Memory 内存存储无持久化 CSV csv格式存储数据 体积小文本数据3. 事务特性-ACID Atomicity(原子性 事务中的所有操作要么都成功要么都失败。 Consistency(一致性) 事务开始和结束的数据保持一致的保持数据的完整性。 Isolation(隔离性): 事务之间互不影响 Durability(持久性 数据存储之后即使系统出现故障数据也会持久保存。4. 事务隔离级别 事务的四个隔离级别 isolation level: read uncommitted 读未提交 A事务可以读B事务未提交的修改数据。问题【脏读】【不可重复读】【幻读】 read committed 读已提交 A事务可以读取B事务已提交的数据。 【不可重复读】【幻读】 repeatable read 可重复读【默认】 A事务修改数据时会读取其它事务提交后数据再进一步修改保持数据的一致性。 【幻读】 serializable 序列化或串行化 多个事务在修改同一条数据时必须等待其他事务完成才能执行。客户端设置事务隔离级别的语句 set session transaction isolation level 隔离级别5. 高级子查询 -- join on 方式-- 内连接 join on -- 左外连接 left join on -- 右外连接 right join on select s.*, sc.*, c.*from student s left join score sc on (sc.sns.sn)right join cource c on (c.cn sc.cn)-- 等值连接条件(属于内连接)select s.*, sc.*, c.*from student s, score sc , cource cwhere s.sn sc.snand sc.cn c.cn;-- 联合查询select * from s1union all -- all 表示不去重select * from s1;6. MySQL中字符、日期、数值的常用函数 字符函数 lower(), upper(), replace(), instr(), length, char_length(), concat(), lpad(), rpad(), trim() char(), ord(), format(str, n) 日期函数 year()/month()/day()/hour()/minute()/week()dayofweek() dayofyear() weekofyear()date_add(,interval n 日期时间关键字) date_sub()str_to_date() date_format()now()/current_timestampcurrent_date/curdate()current_time/curtime() 数值函数 abs()/round()/ceil()/floor()/pow()/mod()sin()/cos()/tan()/con()rand()7. Mysql数据库的增、删、查、改 1select语句 select [*|表名.*] [,][ [表名.]字段名 [as 字段别名], [表名.]字段名2 [as 字段名2别名], ...] from 表名 [as] [表别名] [join 表名2 on (表名.列名 表名2.列名 ) ] [where 条件表达式] [group by 分组的字段] [having 聚合字段的条件表达式] [order by 排列字段] [limit 起始行号, 每页显示的记录行数]经典SQL语句 查询课程编号为01且课程成绩在80分以上的学生的学号和姓名 SELECT st.s_id, st.s_name FROM student st JOIN score sc ON sc.s_idst.s_id WHERE sc.c_id01 AND sc.s_score802 insert语句 -- 新增数据时可以指定哪些字段及它的数据 -- 默认情况下为所有的字段指定数据, 字段顺序按创建表时的字段顺序。 insert into 表名 [ ( 字段1 字段2 ) ] values (字段1值 字段2值);3 update语句 update 表名 set 字段1字段1值 [, 字段2字段2值, ...] [where 条件表达式]【注意】如果不增加where条件语句则表示针对所有的记录行的特定的字段修改它的数据。 4 delete语句 delete from 表名 [where 条件表达式]【提示】不加where条件的delete语句表示清空表。 8. 外键约束的级联删除 添加外键约束时 可以指定级联选项 on delete cascade 当主表中的主键所在行的数据被删除时外键字段所在行则被级联删除on delete set null 当主表中的主键所在行的数据被删除时外键字段则被设置为nullon update cascade 级联更新, 当主键的值发生变化后外键的值也同步修改。 9. Oder by子句和Limit子句 order by用于对查询数据进行排序的支持升序默认 ASC和降序( DESC )两种方式。 -- 查询所有员工的姓名、入职时间和薪资并按薪资的降序从大到小方式排列 -- desc - descend -- asc - ascend select name,hire_date,salary from person order by salary desc;limit子句可以对查询结构的数据进行分页显示格式 -- offset 表示起始行的索引编号 从0开始 -- rows 表示本次显示的行数可以理解一页显示的记录数 -- 假如 每一页显示 10记录第5页的offet是多少是40 -- 每一页显示 5条记录第6页的offset是多少 -- offset (page-1)*rows limit offset, rows10. mysql查询最新插入的10条数据 select * from table order by id desc limit 1011. MySQL和Redis的区别 1类型上从类型上来说mysql是关系型数据库redis是非关系型数据库 2作用上mysql用于持久化的存储数据到硬盘功能强大但是速度较慢redis用于存储使用较为频繁的数据到内存中读取速度快 3需求上mysql和redis因为需求的不同一般都是配合使用12.Redis的优缺点 优点 读写性能优异 Redis能读的速度是110000次/s写的速度是81000次/s。支持数据持久化支持AOF和RDB两种持久化方式。支持事务Redis的所有操作都是原子性的同时Redis还支持对几个操作合并后的原子性执行。数据结构丰富除了支持string类型的value外还支持hash、set、zset、list等数据结构。支持主从复制主机会自动将数据同步到从机可以进行读写分离。 缺点 数据库容量受到物理内存的限制不能用作海量数据的高性能读写因此Redis适合的场景主要局限在较小数据量的高性能操作和运算上。Redis 不具备自动容错和恢复功能主机从机的宕机都会导致前端部分读写请求失败需要等待机器重启或者手动切换前端的IP才能恢复。主机宕机宕机前有部分数据未能及时同步到从机切换IP后还会引入数据不一致的问题降低了系统的可用性。Redis 较难支持在线扩容在集群容量达到上限时在线扩容会变得很复杂。为避免这一问题运维人员在系统上线时必须确保有足够的空间这对资源造成了很大的浪费。 12. Redis常用的数据类型和数据持久化方式 redis是基于k-v的键值对的完全的内存缓存服务,所谓的数据类型是指v的数据类型. 常用的数据类型:- str - hash- list- set 集合- zset 有序集合数据持久化:- rdb(Redis DataBase默认)方式,将内存的数据保存到硬盘中, 默认在配置文件使用save项, 根据keys的数量和时间的设置存储条件.- aof方式, 将操作的日志进行持久化(追加日志文件).四、Linux常用命令 1.Linux基本命令 pwd 显示工作路径 tree 显示文件和目录由根目录开始的树形结构 lstree 显示文件和目录由根目录开始的树形结构 mkdir dir1 创建一个叫做 dir1 的目录 mkdir dir1 dir2 同时创建两个目录 mkdir -p /tmp/dir1/dir2 创建一个目录树 rm -f file1 删除一个叫做 file1 的文件 rmdir dir1 删除一个叫做 dir1 的目录 rm -rf dir1 删除一个叫做 dir1 的目录并同时删除其内容 rm -rf dir1 dir2 同时删除两个目录及它们的内容 mv dir1 new_dir 重命名/移动 一个目录 cp file1 file2 复制一个文件 cp dir/* . 复制一个目录下的所有文件到当前工作目录 cp -a /tmp/dir1 . 复制一个目录到当前工作目录 cp -a dir1 dir2 复制一个目录 ln -s file1 lnk1 创建一个指向文件或目录的软链接 ln file1 lnk1 创建一个指向文件或目录的物理链接 2. find文件查找 命令格式 find [path] [表达式语句] find . -name *.txt txt_files.txt # 将查找到的所有文本文件结果写入到 txt_files.txt文件中 find code -name *.py |xargs cat|grep -E ^$| wc -l # 统计python的代码行数3. Cat内容查看 命令格式 cat [OPTION] 文件 -A, --show-all 显示所有内容 -n 显示行号 cat -nb 1.sql # 显示文件内容并显示行号 但空行不显示行号4. grep命令 当想知道某个关键字xxx在哪些文件里面的哪些行出现的时候用这个命令。这个命令可以配合正则表达式实现强大的功能 可以和cat或find组合使用为显示的数据增加显示或查找条件。 cat test2.sql |grep -E ^.$ | wc -l grep -E ^.*$ -n test2.sql # 显示每一行的内容并显示行号。 -E表示正则5. xargs命令 ​ 是给其他命令传递参数的一个过滤器常作为组合多个命令的一个工具。它主要用于将标准输入数据转换成命令行参数xargs能够处理管道或者标准输入并将其转换成特定命令的命令参数。也就是说find的结果经过xargs后其实将find找出来的文件名逐个作为了grep的参数。grep再在这些文件内容中查找关键字test。 格式 命令 | xargs [参数] [command ] , 不带command 默认的使用echo 输出 作用 - 数据以空格进行分隔 - 可以根据参数进行一次或多次处理,默认的处理命令是/bin/echo - 空行不进行处理,会被忽略 - 遇到命令状态为255时,xargs会立刻停止,譬如发生错误时.find code -name *.py|xargs python #查到 code目录下所有python脚本并执行此脚本# find、grep、xargs结合使用: find . -name aa* | xargs grep hello -ls # 则输出的是文件内容 包含“hello”的aa文件6. ps进程查看 参数说明 -A 所有的进程均显示出来与 -e 具有同样的效用 -a 显示现行终端机下的所有进程包括其他用户的进程 -u 以用户为主的进程状态 x 通常与 a 这个参数一起使用可列出较完整信息。 l 较长、较详细的将该PID 的的信息列出 j 工作的格式 (jobs format) -f 做一个更为完整的输出。ps -l ps -ef # 显示进程完整的信息查看所有的sshd远程的进程 ps -ef|grep sshd | grep -v grep7. netstat端口占用查看命令 netstat -nltp | grep 22 #查看 22端口的占用情况8. free查看内存命令 #查看内存使用情况 free -mh 可以使用 top命令查看CPU和内存使用情况。9. df查看磁盘空间命令 参数 -a, --all 所有文件信息 pseudo 虚假的, duplicate 重复的, inaccessible 不可达 -h, --human-readable 显示人性化的文件大小 (如 1K 234M 2G) -i, --inodes 显示inode 信息而非块使用量 -k 即--block-size1K -l, --local 只显示本机的文件系统 -T, --print-type 显示文件类型df -h #显示存储空间大小10. du查看目录命令 du -sh-s 统计求和将所有目录及文件的大小的总和计算出来。结果只有一行。 11. firewall-cmd命令 查看状态 firewall-cmd --state开启与关闭 service firewalld start|stop|restart # systemctl start|stop|restart firewalld启用与禁用 systemctl disable|enable firewalld开放端口 firewall-cmd --add-port80/tcp --permanent开放端口后需要重载配置命令如下 firewall-cmd --reload12. Chmod、Chown命令 r:4 w:2 x:1 chmod [ugoa][-][rwx] filename # 修改权限 chmod x aa.sh # 给aa.sh文件添加可执行权限chown # 修改文件所属组及用户 格式 chown [-fhnv] [-R [-H | -L | -P]] owner[:group] file 13. vim 通过vim编辑一些文本或脚本文件。 三种模式 ​ 普通模式、插入模式、命令行模式 1、普通模式命令 ​ [n]yy: 复制, 当前光标位置向下复制n行n默认为1行 ​ [n]dd: 剪贴当前光标位置向下剪贴n行n默认为1行 ​ d 按左右方向键 删除光标左或右边的一个字符 按上下方向键删除当前行和上行或下行的两行内容。 ​ nd 向上或下删除 n1 行 向左或右删除 n个字符 ​ p: 粘贴 ​ **x**光标所在位置删除一个字符 ​ nx: 光标所在位置开始向右删除n个字符。如果删除最一个位置光标自动向左移动。 ​ **dw**光标位置开始到行尾全部删除 遇到空格或特殊字符结束。 ​ gg: 第一行 ​ **G**光标移动到最后一行首位置 ​ dGShiftg: 从当前行删除到最后一行 ​ ggdG: 清空文件 ​ v: 进入可视模式移动光标选择字符 ​ shiftv: 选择整行 ​ . : 重复操作 ​ u: 撤销操作 ​ ctrlr: 取消撤消 ​ / : 查找字符 2、插入模式 i光标当前位置 insert Shift i 光标所在行首 insert a光标所在的后一个位置 insert Shift a 光标所在行尾 insert o 光标所在行下插入空行 Shift o 光标所在行上插入空行 cc: 剪切当前行进入当前。 和dd命令相似但dd不会进入编辑模式 r只替换一个之后变成 普通模式 Shift r ®替换模式,可连续替换直到模式切换为止。 3、命令行模式 set number 显示行号set nonumber 取消显示行号n 移动第n行/内容 搜索内容%s/原内容/新内容/ig 全文或当前行替换内容set ftUNIX 设置文件格式为UNIX格式 解决Window上开发的sh脚本不能在Linux中执行的问题。w 写入q 退出 q! 强制退出x 写入并退出 14. sed sed是一种流编辑器它是文本处理中非常好的工具能够完美的配合正则表达式使用功能不同凡响。处理时把当前处理的行存储在临时缓冲区中称为“模式空间”pattern space接着用sed命令处理缓冲区中的内容处理完成后把缓冲区的内容送往屏幕。接着处理下一行这样不断重复直到文件末尾。文件内容并没有改变除非你使用重定向存储输出。Sed主要用来自动编辑一个或多个文件可以将数据行进行替换、删除、新增、选取等特定工作简化对文件的反复操作编写转换程序等。 # sed [-nefr] [动作]选项与参数 -n 使用安静(silent)模式。在一般 sed 的用法中所有来自 STDIN 的数据一般都会被列出到终端上。但如果加上 -n 参数后则只有经过sed 特殊处理的那一行(或者动作)才会被列出来。 -e 直接在命令列模式上进行 sed 的动作编辑 -f 直接将 sed 的动作写在一个文件内 -f filename 则可以运行 filename 内的 sed 动作 -r sed 的动作支持的是延伸型正规表示法的语法。(默认是基础正规表示法语法) -i 直接修改读取的文件内容而不是输出到终端。动作说明 [n1[,n2]]function n1, n2 不见得会存在一般代表『选择进行动作的行数』举例来说如果我的动作是需要在 10 到 20 行之间进行的则『 10,20[动作行为] 』function a 新增 a 的后面可以接字串而这些字串会在新的一行出现(目前的下一行) c 取代 c 的后面可以接字串这些字串可以取代 n1,n2 之间的行 d 删除因为是删除啊所以 d 后面通常不接任何咚咚 i 插入 i 的后面可以接字串而这些字串会在新的一行出现(目前的上一行) p 列印亦即将某个选择的数据印出。通常 p 会与参数 sed -n 一起运行 s 取代可以直接进行取代的工作哩通常这个 s 的动作可以搭配正规表示法例如 1,20s/old/new/g 就是啦替换字符串 sed -i s/要被取代的字串/新的字串/g grep 查找字段 -rl 路径15. Shell shell 中while循环 while (( condition )) docommand done# 例 i1 s0 while (( $i100 )) dos$[is]echo $i, $slet i # 执行 字符串的shell表达式等价于 i$[i1] done shell 中读取文件第一行 head -n 1 file.txtshell 中读取文件最后一行 tail -n -1 file.txt五、Docker工具 Docker是镜像容器的管理工具 实现虚拟化技术 替代类传于VMware或VirtualBox虑拟环境。Docker基于硬件虚拟化 实现多个独立的容器微型操作系统在同等的硬件资源下和基础的操作系统Ubuntu上构建的虚拟环境。 1. Docker常用命令 docker version 检查docker环境 systemctl start docker 启动docker后台服务 systemctl enable docker 开机启动docker服务 systemctl disable docker 取消开机启动docker服务 docker pull 镜像名:版本号 下拉镜像 docker images 查看本地镜像 docker ps [-a|l] 查看容器的运行状态 docker rmi [-f] 镜像全名[:tag]或ID 删除镜像 docker exec -it 容器名或ID bash 进入容器运行镜像 docker run [-i -t -d] [--name name] [-v local_path:path] [-p local_port:port] [--network network_name] [-e envirment_namevalue] 镜像全名[:tag]或ID-i 表示input可以进入容器中 -t 表示打开新的terminal 终端 一般和-i组合使用 -d 让容器处于后台运行 同步返回容器的ID –name 指定容器的名称 -v (Volumn) 将本地的文件路径和容器的文件绑定同步文件数据。 -p 将本地的端口与容器中服务端口绑定。 -e 指定容器的环境变量容器的程序在运行时需要的变量。 2. Docker复制文件 通过docker cp命令将本地文件复制到容器中或者容器中文件复制到本地来。 docker cp 容器名:源文件路径 本地目标路径 docker cp 本地源路径 容器名:目标文件路径3. 容器日志 当容器启动后可以查看容器中服务的运行日志 docker logs 容器名或ID4. Docker镜像和容器的关系 容器由镜像运行产生的运行镜像产生容器一个镜像可以运行多次但每一次产生的容器名称和ID是唯一的。容器可以保存为镜像docker save 六、框架相关知识 1. Django中的MVC、MTV和MVVM MVC把Web应用分为模型(Model)控制器(Controller)和视图(View)三层他们之间以一种插件式的、松耦合的方式连接在一起模型负责业务对象与数据库的映射(ORM)视图负责与用户的交互(页面)控制器接受用户的输入调用模型和视图完成用户的请求MTV模式本质上和MVC是一样的。M 代表模型Model负责业务对象和数据库的关系映射(ORM)。T 代表模板 (Template)负责如何把页面展示给用户(html)。V 代表视图View负责业务逻辑并在适当时候调用Model和Template。 MVVM也是MVC的 M和VM分别表示模型和视图模型控制器/监视器 V单纯的视图用户交互的UI页面。其中VM是MVC中的控制器主要监听V视图的事件和M(数据模型)的变化并即时渲染到V中。MVVM主要应用于Vue框架。2. FBV和CBV FBV Function based View 基于函数的视图。Djang和Flask都是默认支持的。 CBV Class based View 基于类的视图。如Django的View或DRF的APIView类。FBV和CBV的区别- FBV 处理业务都集中一个函数中无论是哪一个请求方法GET/POST。一般与MVT组合使用。因为HTML页面的Form表单标签只支持GET和POST请求。- CBV 处理的业务分散不同的实例方法中如get(), post()。开发RESTful接口时显得更规范一些。主要面向的资源的业务开发API接口。2.1 CBV加装饰器 需要先导入模块 from django.utils.decorators import method_decorator装饰类时语法为method_decorator(装饰器函数名, name‘类内需要装饰的方法名’) 直接装饰类内的方法时直接**method_decorator(装饰器函数名)**即可。我们这里不用原生的装饰器是因为扩展性差因为类方法有一个self参数如果用原生的装饰器就需要加一个参数可是加了之后装饰器又没法装饰普通的函数了。 # method_decorator(login_auth,nameget) # 第二种 name参数必须指定 class MyHome(View):method_decorator(login_auth) # 第三种 get和post都会被装饰def dispatch(self, request, *args, **kwargs):super().dispatch(request,*args,**kwargs)# method_decorator(login_auth) # 第一种def get(self,request):return HttpResponse(get)def post(self,request):return HttpResponse(post)FBVcsrf_token认证情况 情况一所有函数都要认证某一个不需要认证 (csrf_exempt) MIDDLEWARE [django.middleware.security.SecurityMiddleware,django.contrib.sessions.middleware.SessionMiddleware,django.middleware.common.CommonMiddleware,django.middleware.csrf.CsrfViewMiddleware, # 全站使用csrf认证django.contrib.auth.middleware.AuthenticationMiddleware,django.contrib.messages.middleware.MessageMiddleware,django.middleware.clickjacking.XFrameOptionsMiddleware, ] from django.views.decorators.csrf import csrf_exemptcsrf_exempt # 该函数无需认证 def users(request):user_list [tom,jeck]return HttpResponse(json.dumps((user_list)))情况二所有都不认证某个函数需要认证(csrf_protect) MIDDLEWARE [django.middleware.security.SecurityMiddleware,django.contrib.sessions.middleware.SessionMiddleware,django.middleware.common.CommonMiddleware,#django.middleware.csrf.CsrfViewMiddleware, # 全站不使用csrf认证django.contrib.auth.middleware.AuthenticationMiddleware,django.contrib.messages.middleware.MessageMiddleware,django.middleware.clickjacking.XFrameOptionsMiddleware, ]from django.views.decorators.csrf import csrf_exemptcsrf_protect # 该函数需认证 def users(request):user_list [tom,jeck]return HttpResponse(json.dumps((user_list)))CBV,csrf_token认证时需要使用 method_decorator(csrf_exempt)在dispatch方法中单独方法无效 # 方式一 from django.views.decorators.csrf import csrf_exempt,csrf_protect from django.utils.decorators import method_decoratorclass StudentsView(View):method_decorator(csrf_exempt)def dispatch(self, request, *args, **kwargs):return super(StudentsView,self).dispatch(request, *args, **kwargs)def get(self,request,*args,**kwargs):print(get方法)return HttpResponse(GET)def post(self, request, *args, **kwargs):return HttpResponse(POST)def put(self, request, *args, **kwargs):return HttpResponse(PUT)def delete(self, request, *args, **kwargs):return HttpResponse(DELETE)# 方式二 from django.views.decorators.csrf import csrf_exempt,csrf_protect from django.utils.decorators import method_decoratormethod_decorator(csrf_exempt,namedispatch) class StudentsView(View):def get(self,request,*args,**kwargs):print(get方法)return HttpResponse(GET)def post(self, request, *args, **kwargs):return HttpResponse(POST)def put(self, request, *args, **kwargs):return HttpResponse(PUT)def delete(self, request, *args, **kwargs):return HttpResponse(DELETE)3. RESTful设计的规范 RESTful主要是面向资源设计它的接口的, 它有四个规范:- 每个资源都存在唯一的标识URI- 每个资源都具有四个动作谓词, 分别是GET/POST/PUT/DELETE- 每次的动作都是无状态的, 即是HTTP的短连接(Connection: close|keep-alive)- 交互的资源数据类型一般是json或xml.4. Django、Flask、Tornado三个框架的区别 从体积方面: - Django重力级的,组件或功能更全面,不需要过多地引用第三方插件(组件).内部包含MVC/MTV/ORM/Cache/Logger/Admin站点/权限/Session等.- Flask 微框架, 只实现Web服务的核心引擎,基于Werkzeug实现WSGI服务.如果操作数据库则需要自定义或引用第三方的SQLAlchemy.- Tornado 除了现实现WSGI服务之外,包含异步请求模块. 整体被设计为高并发/高性能的异步服务框架. 从性能方面:- Django 的json序列化最优的, ORM操作比较慢的. 在Tornado和Flash中使用SQLAlchemy性能较高.- Tornado的响应的速度最快的,大概在1秒; Django和Flask大概在3.4秒左右.- Flask的单独使用其它组件时,处理速度是最快的. 在实现少量接口的业务中,开发速度是最快的.- NoSQL(Redis/MongoDB/Memchache/ElatichSearch/Hive/Hbase)5. Django中间件的钩子函数 常用四个钩子函数 - process_request(self, request, *args, **kwargs)处理请求前在每个请求上request对象产生之后url匹配之前调用返回None或HttpResponse- process_view(self, request, view, *args, **kwargs)处理视图前在每个请求上url匹配之后视图函数调用之前调用返回None或HttpResponse- process_exception(self, request, exception)异常处理当视图抛出异常时调用- process_response(self, request, response)处理响应后视图函数调用之后所有响应返回浏览器之前被调用在每个请求被调用返回HttpResponse对象 - process_template_response(self, request, response):6. ORM及实现原理 ORM: ORM是对象关系映射(Object Relational Mapping)的缩写Django的ORM操作本质上会根据对接的数据库引擎翻译成对应的sql语句用面向对象的方式去操作数据库的创建表、增加、修改、删除、查询等操作。实现原理 在Python中可以通过元类、类和对象的自省函数来实现表结构的定义、实例对象的CURD等功能。 现有的ORM Django ORM 和 SQLAlchemy6.1 orm中的方法 1 all(): 查询所有结果 2 filter(**kwargs): 它包含了与所给筛选条件相匹配的对象 3 get(**kwargs): 返回与所给筛选条件相匹配的对象返回结果有且只有一个如果符合筛选条件的对象超过一个或者没有都会抛出错误。 4 exclude(**kwargs): 它包含了与所给筛选条件不匹配的对象 5 order_by(*field): 对查询结果排序 6 reverse(): 对查询结果反向排序 8 count(): 返回数据库中匹配查询(QuerySet)的对象数量。 9 first(): 返回第一条记录 10 last(): 返回最后一条记录 11 exists(): 如果QuerySet包含数据就返回True否则返回False 12 values(*field): 返回一个ValueQuerySet——一个特殊的QuerySet运行后得到的并不是一系列model的实例化对象而是一个可迭 代的字典序列 13 values_list(*field): 它与values()非常相似它返回的是一个元组序列values返回的是一个字典序列 14 distinct(): 从返回结果中剔除重复纪录 15 delete(): 立即删除对象而不返回任何值delete() 方法是 QuerySet 上的方法但并不适用于 Manager 本身。 16 update(): 对于任何结果集QuerySet均有效这意味着可以同时更新多条记录。update()方法会返回一个整型数值表示受影响的记录条数。6.2 django orm中三种能写sql语句的方法 1 extra 结果集修改器一种提供额外查询参数的机制 # 查找小玖出版社中所有大于100元的书籍 Book.objects.filter(publisher__name 小玖出版社).extra(where [price 100]) # 或 Book.objects.filter(publisher__name 小玖出版社, price__gt 100)2 raw 执行原始sql并返回模型实例 # 查看数据表python_book 中的所有的对象。 b Book.objects.raw(select * from python_book) # raw方法返回的是RawQuerySet的对象可迭代 for i in b:print(i.title)3直接执行自定义SQL(这种方法完全不依赖与model前面两种方式还是要依赖于model),其实就是用python操作数据库的方法 # 获取数据库的连接对象 from django.db import connection # 获得一个游标cursor对象 cursor connection.cursor() # 插入操作 cursor.execute(insert into python_author(name) values(小玖)) # 更新操作 cursor.execute(update python_author set name 小柒 where name 小玖 ) # 删除操作 cursor.execute(delete from python_author where name 小柒) # 查询操作 cursor.execute(select * from python_author) # 一条一条的取数据 raw cursor.fetchone() # 取出所有数据以元组的形式返 cursor.fetchall()7. DRF可用的权限验证类 rest_framework.permissions.AllowAny rest_framework.permissions.IsAuthenticated rest_framework.permissions.IsAuthenticatedOrAnonReadOnly rest_framework.permissions.IsAdminUser rest_framework.permissions.DjangoModelPermissions rest_framework.permissions.DjangoModelPermissionsOrAnonReadOnly8. Django请求生命周期 1用户输入网址浏览器发起请求 2WSGI服务器网关接口创建socket服务端接受请求 3中间件处理请求 4url路由根据当前请求的url找到相应的视图函数 5进入view进行业务处理执行类或者函数返回字符串 6再次通过中间件处理响应 7WSGI返回响应 8浏览器渲染9. Nginx负载均衡策略 (1)RR 轮询策略 按照轮询默认方式进行负载每个请求按时间顺序逐一分配到不同的后端服务器如果后端服务器down掉能自动剔除。虽然这种方式简便、成本低廉。但缺点是可靠性低和负载分配不均衡。(2)权重weight 指定轮询几率weight和访问比率成正比用于后端服务器性能不均的情况。 upstream test{server localhost:8080 weight9;server localhost:8081 weight1; }(3)ip_hash 上面的2种方式都有一个问题那就是下一个请求来的时候请求可能分发到另外一个服务器当我们的程序不是无状态的时候采用了session保存数据这时候就有一个很大的很问题了比如把登录信息保存到了session中那么跳转到另外一台服务器的时候就需要重新登录了所以很多时候我们需要一个客户只访问一个服务器那么就需要用iphash了iphash的每个请求按访问ip的hash结果分配这样每个访客固定访问一个后端服务器可以解决session的问题。upstream test {ip_hash;server localhost:8080;server localhost:8081; }(4)fair(第三方) 按后端服务器的响应时间来分配请求响应时间短的优先分配。 upstream backend { fair; server localhost:8080;server localhost:8081; }10. celery Celery是一个简单、灵活且可靠的处理大量消息的分布式系统专注于实时处理的异步任务队列同时也支持任务调度。 分布式系统 ​ 一个系统应用(网站系统应用)会涉及到很多的组件(web服务器、web应用、数据库、消息中间件等)将一个系统应用的相关组件架构在不同的服务器上不同服务器上不同组件之间进行消息通信的这种模式就叫做分布式系统。可以实现负载均衡。 10.1 celery的优点 简单** Celery 易于使用和维护并且它 不需要配置文件 。 下面是一个你可以实现的最简应用 from celery import Celeryapp Celery(hello, brokeramqp://guestlocalhost//)app.task def hello():return hello world高可用性 woker和client会在网络连接丢失或者失败时自动进行重试。并且有的brokers(消息中间件) 也支持“双主”或者“主从”的方式实现高可用快速 单个 Celery 进程每分钟可处理数以百万计的任务而保持往返延迟在亚毫秒级使用 RabbitMQ、py-librabbitmq 和优化过的设置。 灵活 Celery 几乎所有部分都可以扩展或单独使用。可以自制连接池、 序列化、压缩模式、日志、调度器、消费者、生产者、自动扩展、 中间人传输或更多。 10.2 使用场景 充值成功发送短信通知耗时操作 七、爬虫相关知识 1. 爬虫的常见反爬虫策略 - UAUser-Agent - Cookie - 频次(请求的次数)IP代理 - 验证码(短信、图片字母和数字、勾选、滑块) - 动态JSSelenium/Splash - Referer 引用来源 2. requests.request()方法中常用参数 requests.request(method, url, params,data,json, **kwargs)- method- url- params- data- json- files- headers- cookies- auth- proxies基于request()方法实现的快捷方法requests.get(url, params, **kwargs)requests.post(url, data, json, **kwargs)requests.put(url, data,json, **kwargs)requests.delete(url, params, **kwargs)3. scrapy框架的常用命令 scrapy startproject 项目名 scrapy genspider 爬虫名 域名 scrapy crawl 爬虫名 [-o 文件名] scrapy shell [url]4. scrapy的核心组件 engine 引擎, 负责其他四个组件的交互. spider 爬虫类, 启动爬虫的入口(发起起始的请求)/请求成功之后的数据解析/解析过程的产出item和request scheduler 调度器, 接收engine传入的请求,根据调度规则(考虑优先级), 产出一个request给engine. downloader 下载器, 接收engien从调度器获取的请求request, 并开始下载,下载成功之后,产出给engine itempipeline 数据管道, 处理engien从爬虫类中接收到解析数据item, 并进行处理. 两个中间件: 爬虫中间件 下载中间件
http://www.huolong8.cn/news/438144/

相关文章:

  • 网站description大连网站优化方案
  • 河南宝盈建设集团有限公司网站网页浏览器打开
  • 企业集团网站网站建设方案网站百度收录怎么做
  • 中国交通建设集团有限公司网站优化自己可以做吗
  • 做期货浏览哪些网站阿里云网站开发
  • 深圳网站制作公司兴田德润怎么样市住建设局网站
  • 保定网站制作价格无极招聘网无极在线
  • 网站建设实施计划包括哪些方面抖音小程序
  • 建设部招投标网站深圳做网站的公
  • 怎么做网站相册wordpress修改logo大小代码
  • 企业网站模板源码有哪些药品包装设计
  • 如何在百度上做网站推广有域名怎么建立网站
  • 学习做网站可以吗自动推广引流app
  • 多语言网站难做么网站哪个公司做的好
  • 昆明市建设厅网站加盟创业
  • 叶县网站建设网站建设 金手指 下拉22
  • 网站开发人员负责方面做一个商城网站需要多少钱
  • 鹰潭做网站的公司网站页面一般做多大
  • 专为网站做点击量文化建设素材
  • 网站空间 按流量计费马云不会代码怎么做的网站
  • 百度新网站提交入口青岛关键词快速排名
  • 游戏 网站 模板中国企业公示信息网官网
  • 岚县网站建设济南的企业网站
  • 网站做md5脚本微信网站入口
  • 网站名称填写什么wordpress下拉筛选
  • 做网站包含微信公众号吗网页源码在线查看
  • 做图片视频的网站有哪些问题吗免费制作网站平台
  • 国外著名的网站设计公司wordpress防止发表重复标题的文章
  • 北京怎么样做网站二级域名网站建设
  • 手机能建设网站开发网站年度工作总结及明年工作计划