课程相关复习
django
web框架的本质 – socket服务端
-
socket收发消息
-
根据不同的路径返回不同的内容
-
动态页面(jinja2)
浏览器上输入地址之后发生的事情
HTTP协议
请求的格式:
‘请求方式 URL路径 协议版本\r\n
k1:v1\r\n
k2:v2\r\n
\r\n
请求体’
响应格式:
‘HTTP/1.1 状态码 状态描述\r\n
k1:v1\r\n
k2:v2\r\n
\r\n
响应体(HTML文本)’
状态码 !
1xx
2xx 请求成功 返回正常的响应
3xx 重定向 301 302
4xx 请求错误 404 403
5xx 服务器的错误 500 502
请求头: !
content-type
cookie set-cookie
host
user-agent
location
MTV MVC
MVC M model V view C controller
MTV M model T template V view
路由
正则
^ $ \d \w ? + *
分组和命名分组
url的命名和反向解析
include
namespace
视图
FBV CBV
request !
response
三大件
CBV
as_view 原理
加装饰器
模板
{{ }} {% %}
变量
. KEY 属性 方法 索引
过滤器
{{ 变量|filter:参数 }}
safe mark_safe from django.utils.safestring import mark_safe
default add date : \’Y-m-d H:i:s\’ join first last length
标签 {% %}
{% csrf_token %} csrfmiddlewaretoken 64字符串
{ % with as %}
{% endwith %}
组件
一段HTML代码 nav.html
{% include nav.html %}
静态文件
{% load static %}
{% static ‘相对路径’ %}
母板和继承
{ % extends \’母版的文件名\’ %} # 写到顶部
三个自定义方法: !!!
filter simple_tag inclusion_tag
步骤:
-
在APP下创建名为tempaltetags的Python包
-
在包内写py文件 my_tags.py
-
在py文件中写
from django import template register = template.Library()
-
写函数+装饰器
@register.filter def addxx(value,arg=None): # 对变量使用 {} return \'xxxxx\' @register.simple_tag def simple(*args,**kwargs): # 对标签使用 {% %} return \'cccccc\' @register.inclusion_tag(\'li.html\') # def show_li(*args,**kwargs): return {\'k1\':v1}
-
使用
{% load my_tags %} {{ \'alex\'|addxx:\'sb\' }} {% simple \'v1\' \'v2\' k1=\'v3\' %} {% show_li %}
ORM
对象关系映射
对应关系
-
必知必会13条
对象列表
all
filter # 过滤
exclude # 过滤反转
values() # 字典列表
values_list() # 元组列表
order_by() # 排序
reverse() # 反转
distinct() # 去重,按照整个结果去重,不能按照每个字典去重
对象
get
first()
last()
数字
count()
布尔值
exists()
-
单表的双下划线
__gt gte lt lte
__isnull
__in =[ ]
__range=[1,10]
__contains
__icontains
-
外键
描述多对一的关系
publisher book
class Book:
pub = Fk(\’Publisher\’,on_delete,related_name=\’books\’) # on_delete 当删时做的操作 SET(value) SET_DEFAULT SET_NULL
基于对象
正向查询
book_obj.pub ——》 出版社对象
book_obj.pub_id ——》 出版社对象ID
反向查询
pub_obj.book_set ——》 管理对象 related_name=\’books pub_obj.books
pub_obj.book_set.all() ——》 出版社所管理所有的书籍
基于字段
Book.objects.filter(publisher__name=\’xxxxx\’)
-
多对多
创建的三种方式 方式一,让Django自动创建第三张表 class Author(): name = books = models.ManyToManyField(\'Book\') 方式二,手动创建第三张表, 查询不方便,需要手动跨表 class Author(models.Model): name = models.CharField(max_length=32) class Author_Book(models.Model): author = models.ForeignKey(\'Author\') book = models.ForeignKey(\'Book\') date = models.DateTimeField() 方式三,手动创建,查询优化,如同自动创建的 class Author(models.Model): name = models.CharField(max_length=32) books = models.ManyToManyField(\'Book\', through=\'Author_Book\') class Author_Book(models.Model): author = models.ForeignKey(\'Author\') book = models.ForeignKey(\'Book\') date = models.DateTimeField()
方法:
author_obj.books ——》 管理对象
author_obj.books.all()
author_obj.books.set() 设置多对多 【对象,对象】 【id,id】
add remove clear create
author_obj.books.create book
book_obj.author_set
F 和 Q
Q 条件
```pyton
Q(name__contains =\'xxxx\') | Q(qq__contains=\'111\')
& 与 ~ 非
Q((\'name__contains\' ,\'xxxx\'))
q = Q()
q.connector = \'OR\'
q.children.append(Q((\'name__contains\' ,\'xxxx\')))
q.children.append(Q( Q(qq__contains=\'111\')))
聚合和分组 TODO 真心不懂
from crm import models
from django.db.models import Count, Max, Sum, Min, Avg
ret = models.UserProfile.objects.aggregate(Count(\'id\'))
print(ret)
ret = models.Campuses.objects.annotate(Count(\'classlist\')).values()
ret = models.ClassList.objects.values(\'campuses\').annotate(Count(\'campuses\'))
print(ret)
事务
from django.db import transaction
with transaction.atomic():
# 事务
pass
行级锁 !
from django.db import transaction
with transaction.atomic():
# 事务
queryset = models.ClassList.objects.filter(pk__gt=3).select_for_update()
queryset.update()
cookie和session !!
解决HTTP协议无状态的问题
cookie 保存在浏览器上一组组键值对
django中的操作
设置
response.set_cookie(key, values,max_age=10,) set-cookie
获取
request.COOKIES cookie
session
保存在服务器上一组组键值对 必须依赖于cookie
django中操作
request.session[]
ajax
data csrfmiddlewaretoken
heard x-csrftoken
中间件 !!!!!
本质上是一个类,在全局范围内改变django的输入和输出,一个钩子。
5种 4个点
process_request()
process_response()
process_view()
process_exception() # 视图级别 有错误才执行
process_template_response() # 返回的response 对象是
执行时间 、 执行顺序、 参数 、不同返回的流程
form modelform modelformset
django-debug-toolbar
缓存
信号
ORM性能相关
数据库相关
crm
重点
- 业务
- 代码 自己能写出来
- 权限控制
- 表结构
- 数据结构 session 中
- 开发过程中遇到了什么问题?
-
干什么用的?
维护客户关系一套系统。 客户、销售增多 。
-
实现的功能
- 销售
- 客户管理
- 公户 私户
- 跟进记录管理
- 报名表
- 缴费表
- 班主任
- 班级管理
- 课程记录管理
- 学习记录
- 销售
-
公户和私户
-
避免销售抢单
3天跟进 15天成单 –> 客户的上限 150 200
-
-
CRM有现成的系统?为什么要开发?
自己开发 可定制化程度高 学邦 http://www.xuebangsoft.com/about.html?
-
crm有多少张表?
- 业务 10 张
- 权限 6张表(4个model)
-
权限是如何实现的?
大概思路, 不是代码,不是结果
- url代表的一个权限
- 表结构
- 登录 + 中间件
-
权限中的技术点
-
视频 153.38
-
登录
- 获取权限
- 跨表
- 去重
- 获取权限
-
去空
-
数据结构
-
权限的结构
permission_list = [ { url title id pid } ]
路径导航
permission_dict = { 权限的id : { url title id pid }
}
权限控制到按钮级别
permission_dict = { 权限的name : { url title id pid pname }
}
-
菜单的结构
menu_dict = {
一级菜单的ID: { title: icon: children : [ { title url id } ] }
}
-
-
session
- json序列表
-
中间件
- process_request
- request.pah_info
- request.breadcrumb_list = [ { url:index , title:首页 } ]
- 白名单
- settings
- 正则
- 权限的校验
- 是有pid
- 有pid 子权限
- request.current_menu_id = pid
- breadcrumb_list.append({ url title }) permission_dict [pid] 父权限 pname
- breadcrumb_list.append({ url title }) 子权限
- 没有pid 二级菜单
- request.current_menu_id = id
- breadcrumb_list.append({ url title }) 二级菜单
- 有pid 子权限
- 是有pid
-
动态菜单
- inclusion_tag
- 权限的id == request.current_menu_id
- 二级菜单 class = active
- 一级菜单 class= ‘’
-
-
路径导航
- inclusion_tag
- 权限控制到按钮级别
- if name in permission_dict
- filter
简单权限的实现
class Permission(models.Model):
url = models.CharField(max_length=64)
title = models.CharField(max_length=32)
class Role(models.Model):
name = models.CharField(max_length=32)
permissions = models.ManyToManyField(\'Permission\')
class User(models.Model):
name = models.CharField(max_length=32)
pwd = models.CharField(max_length=32)
roles = models.ManyToManyField(\'Role\')
动态一级菜单
class Permission(models.Model):
url = models.CharField(max_length=64)
title = models.CharField(max_length=32)
is_menu = models.BooleanField(default=False)
icon = models.CharField(max_length=64)
class Role(models.Model):
name = models.CharField(max_length=32)
permissions = models.ManyToManyField(\'Permission\')
class User(models.Model):
name = models.CharField(max_length=32)
pwd = models.CharField(max_length=32)
roles = models.ManyToManyField(\'Role\')
动态二级菜单
class Menu(models.Model):
title = models.CharField(max_length=64)
icon = models.CharField(max_length=64)
class Permission(models.Model):
"""
有menu_id 二级菜单
有parent_id 子权限
"""
url = models.CharField(max_length=64)
title = models.CharField(max_length=32)
menu = models.ForeignKey(Menu, null=True, blank=True)
parent = models.ForeignKey(\'self\', null=True, blank=True)
class Role(models.Model):
name = models.CharField(max_length=32)
permissions = models.ManyToManyField(\'Permission\')
class User(models.Model):
name = models.CharField(max_length=32)
pwd = models.CharField(max_length=32)
roles = models.ManyToManyField(\'Role\')
权限控制到按钮级别
class Menu(models.Model):
title = models.CharField(max_length=64)
icon = models.CharField(max_length=64)
class Permission(models.Model):
"""
有menu_id 二级菜单
有parent_id 子权限
"""
url = models.CharField(max_length=64)
title = models.CharField(max_length=32)
name = models.CharField(\'URL别名\', max_length=32, unique=True)
menu = models.ForeignKey(Menu, null=True, blank=True)
parent = models.ForeignKey(\'self\', null=True, blank=True)
class Role(models.Model):
name = models.CharField(max_length=32)
permissions = models.ManyToManyField(\'Permission\')
class User(models.Model):
name = models.CharField(max_length=32)
pwd = models.CharField(max_length=32)
roles = models.ManyToManyField(\'Role\')
权限如何能不重新登录,就应用新的权限?
-
用户表加字段 存 session_key
-
通过session_key 拿到用户的session数据 更新权限
from django.contrib.sessions.models import Session from django.contrib.sessions.backends.db import SessionStore decode encode
权限如何控制到行级别?
加条件表
开发过程中遇到了什么问题?
- 数字变字符串
- 表结构的变化
- 需求的取舍
路飞学城
Vue
要求:了解Vue 能看懂Vue的代码,能够使用elementUI搭建简单的页面
Vue的基础语法
- 常用指令(小清单的应用 数据驱动视图) –> MVC和MVVM的区别
- Vue的生命周期钩子函数
- 组件
- 组件定义
- 全局组件
- 局部组件
- 组件间传值
- 插槽(slot)
- 前端模块化开发
- node.JS(基于chrome V8引擎的一个服务器版JS) –> 让我们像写后端代码一样写前端代码
- webpack –>打包工具,把后端开发的JS代码都打包成一个JS文件,放到HTML中
- VueCLI3 –>
vue create 项目名
(项目的目录结构)
- VueRouter
- 基本路由定义
router-link
路由入口router-view
路由出口-
$route
:当前的这条路由信息 -
$router
:当前路由对象
-
- 嵌套路由
- 命名路由
- 路由的动态匹配(参数:
route.params
route.query
) - 编程式导航 –>
router.push(...)
- 基本路由定义
- axios (Vue里面推荐使用的发送ajax请求的模块,支持promise)
- VueX: 一般大型项目才用的 https://vuex.vuejs.org/zh/
Django REST framework
十个组件
序列化(Serializer)
用法类似于form
组件
serializer使用
- 定义一个serializer类,继承
serializers.Serializer
/serializers.ModelSerializer
- 字段
-
read_only
和write_only
-
source
用来指定该字段的具体操作source=get_category_display
-
serializers.MethodField
serializer类中必须定义一个get_
开头的方法 - 外键关联
depth=1
所有外键关联的数据就变成只读的 serializers.ListField
require=True
-
- 校验 抛出
serializers.ValidationError
异常 (对比Django form校验记忆)- 全局
validate()
- 局部
validate_field()
- 使用内置的检验规则 正则等
- 全局
serializers.ModelSerializer
- 不用自己挨个定义字段
-
.save()
直接一键更新或创建
class ArticleWriteSerializer(serializers.ModelSerializer):
class Meta:
model = models.Article
fields = "__all__"
extra_kwargs = {
"tag": {
"error_messages": {
"does_not_exist": \'"{pk_value}"对应的tag对象不存在。\'
}
}
}
序列化过程:ORM对象–>JSON格式数据
反序列化:JSON格式数据–>ORM对象
视图
对面对对象理解更深刻的一节课。
重难点:类的多继承,mixin混合类
混合类: 不能单独实例化,必须和别的类搭配使用
认证、权限、限制(节流)
认证
重写authenticate()
方法,返回值是一个元素:第一个元素是用户对象 第二个元素是token
全局配置:所有视图都通用的认证方案
局部视图配置:给单独某个视图配置的认证方案
Token: JWT
–> JSON Web Token
替代session存储的方案
JWT原理 面试的经常问,要能够说明白!
权限
表示用户有没有权限访问某个接口(API)
重写has_permission()
方法
允许访问返回True
不允许访问返回False
全局配置:所有视图都通用的认证方案
局部视图配置:给单独某个视图配置的认证方案
class VipPermission(BasePermission):
def has_permission(self, request, view):
# 如果当前的用户是VIP用户就返回True
if not request.user:
return False
if request.user.vip: # 前提user表里必须要有一个vip字段
return True
else:
return False
限制(节流)
用来限制用户访问API的频率
重写allow_request()
方法
一般使用内置的就满足基本需求
from rest_framework.throttling import SimpleRateThrottle
class VisitThrottle(SimpleRateThrottle):
scope = "xxx"
def get_cache_key(self, request, view):
return self.get_ident(request)
在settings.py中要添加配置项
# 在settings.py中设置rest framework相关配置项
REST_FRAMEWORK = {
"DEFAULT_AUTHENTICATION_CLASSES": ["app01.utils.MyAuth", ],
# "DEFAULT_PERMISSION_CLASSES": ["app01.utils.MyPermission", ]
"DEFAULT_THROTTLE_CLASSES": ["app01.utils.VisitThrottle", ],
"DEFAULT_THROTTLE_RATES": {
"xxx": "5/m",
}
}
知识点:
一分钟最多访问3次,使用while
循环
边循环列表边对列表做删除元素的操作。
分页、版本控制、过滤器
分页
分页模式
- 基本的page number
- limitoffset
- 加密分页
使用的模式:
- 全局配置
- 局部视图配置
REST_FRAMEWORK = {
# 指定用什么分页模式
\'DEFAULT_PAGINATION_CLASS\': \'rest_framework.pagination.LimitOffsetPagination\',
# 每页显示多少条数据
\'PAGE_SIZE\': 100
}
版本控制
为了兼容引出来版本的概念,满足新旧版本同时运行的需求。
五种方式:
- 域名:
luffycity.com/api/v1
- URL参数
luffycity.com/version=v1
- 在请求头中添加 version信息
配置:
REST_FRAMEWORK = {
...
\'DEFAULT_VERSIONING_CLASS\': \'rest_framework.versioning.URLPathVersioning\',
\'DEFAULT_VERSION\': \'v1\', # 默认的版本
\'ALLOWED_VERSIONS\': [\'v1\', \'v2\'], # 有效的版本
\'VERSION_PARAM\': \'version\', # 版本的参数名与URL conf中一致
}
在视图中拿到版本信息:
request.version
拿到当前这次请求的版本号
if request.version == "v1":
....
elif request.version == "v2":
...
过滤器(filter)
对请求的数据按照某个字段做筛选。
视图中通过get_queryset()
方法拿到本次请求用到的所有数据
在get_queryset
中对数据进行过滤。
DRF有个插件:django-filter
安装pip install django-filter
class ProductList(generics.ListAPIView):
queryset = Product.objects.all()
serializer_class = ProductSerializer
filter_backends = (filters.DjangoFilterBackend,)
filter_fields = (\'category\', \'in_stock\') # 通过这个配置项指定支持过滤的字段
解析器、渲染器
解析器:把前端提交过来的数据反序列化成DRF框架中可以使用的数据
渲染器:根据前端请求头里面的信息返回不同格式的数据
POSTman
一个测试接口的工具
路飞业务
首页 elementUI搭建首页
课程列表页
后端用的是ListAPIView
前端Vue用的v-for
支持排序和检索
根据价格排序:order_by("price")
按照课程分类做筛选:filter(category=1)
添加购物车
Redis
-
五种数据类型:List String Hash Set Zset
-
基本操作
-
Django中使用redis
储购物车数据的数据格式:字符串 JSON格式的字符串 –> Python中的字典
结算
数据有效性的校验
- 课程信息校验
- 价格策略的校验
- 优惠券校验
- 课程优惠券
- 通用优惠券
- 支付金额的校验
结算属于中间状态,用redis存储。
支付校验
创建订单(未支付的) –> 返回一个订单号
创建支付宝支付链接需要用到订单号
支付宝支付
加密(为什么要加密?确保通信的安全)
沙箱环境的使用
调用支付宝支付接口的流程:
- 创建一个支付宝的支付链接(要有订单号)
- 浏览器拿到这个链接跳转到支付宝的二维码页面
- 用户扫码
- 用户支付成功 –> 支付宝收到钱
- 支付宝先会发送一个POST请求到我的网站指定的接口
- 对发来的请求用私钥解密信息,判断是否真的支付成功
- 给支付宝的POST请求返回一个true 应答
- 支付宝会在发送一个GET请求到一个指定的URL
简历
CRM:
客户管理系统
经销商管理
库存管理
内部OA
路飞(5个月):
拼购的网站:类似于电商
小程序:调用微信登录
K12: 在线的公开课网站,给小孩子看视频的
经销商培训系统:培训新产品的新特色之类
项目难点:
自己看源码 –> DRF视图 –> 面向对象有了更深刻的理解 多继承和混合类
支付宝支付接口 –> 学会看文档(SDK) –> 要能够把支付流程说清楚
优惠券策略 –> 不同的品类绑定不同的优惠券 –> contenttype
存redis操作 –> 购物车数据结构 –> 大字典
人工智能:
智能蓝牙音箱(小爱同学)
智能玩具
智能客服(爱因互动)
爬虫和数据分析:
git操作
数据结构和算法:
常见算法及时间复杂度空间复杂度必须背会。
手写快排、堆排序、选择排序
归并排序
关于准备面试
- 自己提前做好计划,确定好里程碑节点。(简历写(改)完, 刷面试题,投简历,出去面试(录音回来分析))
写简历千万不要像写笔记一样,把知识点与项目背景融合,写的尽量真实点。
简历可以准备多份,根据投的公司不一样使用不同的简历。
本科 3年
简历上如果是子计算机相关专业就写上,不是就不要写了。
简历要下功夫
准备面试永远没有准备好的那一天。
简历上写的项目要做到给你一张纸一根笔能说半个小时。
推荐大家把每个项目要说的东西都写下来。
面试的要不卑不亢,落落大方。
机会是自己努力争取的。
职业生涯代码量:1年6W左右
基础
第一部分
Cpython -> 解释器: 执行代码
解释性编程语言 -> 同声传译
执行效率低
跨平台性比较好
编译型编程语言 -> 笔译
执行效率高
跨平台性不好
IPython: 交互不一样
变量: 保存数据, 程序运行过程中产生的值。 供给后面的程序使用
int: 整数
float:浮点数
二级制
bool: 布尔
str: 字符串
ascii
unt8
list: 列表 -> 能装对象的对象
增删改查
set: 集合
去重复, 子集, 差集
dict: 字典
以key:value存储数据
key:必须可哈希。不能重复
value: 没有要求
tuple: 元组
不可变 -> 可哈希
long:长整数; py2
open() 打开一个文件 -> 获取到文件句柄
a w r
open 参数
深浅拷贝
第二部分
函数:
对功能或者动作的封装
def 函数名(形参):
函数体
return
函数名(实参)
返回值:
函数执行的结果
1. 不写return 没有返回值. None
2. 只写return 没有返回值. None
3. return 值, 只有一个返回值.
4. return 值1, 值2, 值3... 有多个返回值. 外面接收的是一个元组
return可以终止一个函数的执行
参数:
形参:
1. 位置
2. 默认值参数
3. 动态传参:
*args 位置参数
**kwargs 关键字
顺序: 位置 > *args > 默认值 > **kwargs
*, ** 在形参: 聚合成元组
*, ** 在实参: 打散. 可以把列表(可迭代对象)打散
实参:
1. 位置
2. 关键字
3. 混合 先位置, 后关键字
函数名: 函数名就是变量名
作用域和名称空间:
globals() 查看全局中的内容
locals() 查看当前作用域中的内容
global 获取到全局变量
nonlocal 在局部, 内层函数对外层变量的引入.
闭包:
内层函数对外层函数的变量的使用
def outer():
a = 10
def inner():
a
开闭原则:
对添加新功能开发
对修改源代码封闭
闭包作用:
1. 让一个变量常驻内存
2. 保护变量不被修改
装饰器:
from functools import wraps
def wrapper(fn):
@wraps(fn)
def inner(*args, **kwargs){
\'\'\'在xxx之前\'\'\'
ret = fn(*args, **kwargs)
\'\'\'在xxxx之后\'\'\'
return ret
return inner
@wrapper # target = wrapper(target)
def target():
pass
print(target.__name__)
给装饰器传参:
再提一层函数. 专门给装饰器传递参数用的.
def wrapper_out(flag): # 给装饰器传参, True, False
def wrapper(fn):
def inner(*args, **kwargs):
if flag:
print("问问吴老板, 现在适不适合约. ")
ret = fn(*args, **kwargs)
print("吴老板骗我.....")
else:
ret = fn(*args, **kwargs)
return ret
return inner
return wrapper
@wrapper_out(True) 先执行后面的括号, 返回一个装饰器再和前面的@拼接.成一个语法糖
同一个函数被多个装饰器装饰
迭代器:
存在的意义: 为了让所有的数据类型拥有相同的遍历方式
__iter__获取到迭代器
__next__获取到下一个元素. 获取到最后的时候会报错. StopIteration
list. dict, range, open(), str, tuple, set
都可以被迭代. 都可以使用for循环
特点:
1. 省内存 -> 生成器
2. 惰性机制
3. 只能向前. 不能反复
生成器:
面试题很恶心
# 生成器
# def add(a, b): # 求和
# return a + b
#
#
# def func(): # 生成器函数 0 1 2 3
# for i in range(4):
# yield i
#
# g = func() # 生成器 0 1 2 3
#
#
# n = 2
# g = (add(n, i) for i in g)
#
# ##############
# n = 10
# g = (add(n, i) for i in g)
#
# ############
#
# # for n in [2,10]:
# # g = (add(n, i) for i in g)
#
# print(list(g)) # [g...] 会吧生成器拿空
# # n = 10
# # 20 21 22 23
# 函数闭包
# def add():
# return [lambda x: x * i for i in range(4)]
# # lst = []
# # for i in range(4):
# # def fn(x):
# # return x * i
# # return lst
#
# print([m(2) for m in add()])
1. 生成器函数: yield
def func():
yield
func() 创建生成器对象 不会执行函数
g.next() 运行到下一个yield. 把yield后的数据返回
g.send(123) 给上一个yield位置传值
2. 生成器表达式
[结果 for if]
{key:value for if}
{key for if}
(结果 for if) 直接获取到生成器对象
内置函数:
map()
sorted() 排序
filter() 筛选和过滤
super()
divmod() 计算商和余数
len()
zip()
enumerate() 枚举
all() and
any() or
bin()
hex()
int()
format()
max()
sum()
avg()
range()
lambda x: xxxxxx
递归函数
函数自己调用自己
优势:简单.
缺点:耗内存. 容易崩溃
二分法
掐头结尾取中间
缺点: 必须有序
第三部分
collections
Counter:
defaultdict
OrderDict
Namedtuple
Iterator
Iterable
time模块
时间
time.time() 系统时间 时间戳 数字. 1970-01-01 00:00:00
time.strftime(“%Y-%m-%d %H:%M:%S”) 格式化时间
time.localtime() 转换成结构化时间
pickle: 序列化.
dumps 没有文件
dump 有文件
loads 没有文件
load 有文件
json:
dumps 没有文件
dump 有文件
loads 没有文件
load 有文件
ensure_ascii = False
True:true
False:false
None: null
数字: 字符串
random
randint() 随机整数
choice() 随机选择一个
sample() 随机选择n个
shuffle() 打乱
os
os.path.join
os.path.abspath
os.path.dirname
os.path.exists 判断是否存在
os.path.getSize()
os.rename
os.remove
sys
sys.path
sys.argv
sys.modules
第四部分
类和对象
class 类名(object):
def init(self, 参数1, 参数2…):
对属性的封装
self.属性 = 参数1
self.属性 = 参数2
self.属性 = 参数3
self.属性 = 参数4
def jump(self):
pass
obj = 类名()
obj...
封装:
1. 对属性的封装 对象.属性 = 值
2. 对方法的封装 类中定义方法
继承:
子类自动拥有父类中的除了私有内容外的所有内容
多继承
MRO: C3算法来完成
多态:
类的成员:
1. 变量
1. 实例变量 -> 给对象用的.
2. 类变量 -> 给类用的.
2. 方法
1. 实例方法 -> 对象
2. 类方法 -> 类 @classmethod
3. 静态方法 -> 函数 @staticmethod
3. 属性
@property
4. 私有
私有 __开头 只能自己用
5. 特殊
__new__ 创建对象
__init__
__call__
__str__
__repr__
__dict__
__getitem__
__setitem__
__eq__
__iter__
__next__
hasattr()
getattr()
setattr()
delattr()
type()
issubclass()
isinstance()
约束:
1. raise NotImplementedError
2. 使用抽象类
from abc import ABCMeta, abstractmethod
try:
xxxx
except Exception as e:
....
网络编程
一 CS架构
客户端服务端架构
BS架构
浏览器与服务端
二 网络通信流程
网卡 收发网络电信息
mac地址 网卡的全球唯一标识 广播的通信方式 — 广播风暴 — 造成网络拥堵 信息不安全
ip地址 划分网段 192.168.1.0 — 192.168.1.255 属于同一子网 同一子网内可以进行广播通信 arp协议 通过ip地址获取mac
子网掩码 255.255.255.0 11111111.111111111.11111111.00000000
192.168.1.16 — 192.168.1.0 计算两个ip地址是否为同一网段
DNS服务器 DNS保存着ip地址和域名的一个对应关系, www.baidu.com|波多野结衣| www.baidu.com — 103.235.46.39
网关
交换机 升级版的集线器
路由器 管理内网 联通外网
集线器
广播\单播
广播风暴
三 osi七层协议
应 表 会 传 网 数 物
tcp\id五层
应 传 网 数 物
你好|80|IP地址|mac地址 ---- 电信号 --网线 --- 电信号 -- 你好
传输层
tcp\udp
tcp: 面向连接,消息可靠,面向流,无消息保护边界,相对效率低
tcp要建立连接:
三次握手 详情 https://github.com/jawil/blog/issues/14
四次挥手
udp: 面向无连接,消息不可靠,面向包的,有消息保护边界,效率高
socket在应用层和传输层之间的一个抽象层
socket tcp和udp下的写法都要会
粘包
解决粘包
struct
并发编程
重看 博客
操作系统, 进程,线程,GIL,协程,IO多路复用
IO多路复用,select、poll、epoll 原理 TODO 有点难理解
算法
希尔排序
def shell_sort(list):
n = len(list)
# 初始步長
gap = n // 2
while gap > 0:
for i in range(gap, n):
# 每个步長進行插入排序
temp = list[i]
j = i - gap
# 插入排序
while j >= 0 and list[j] > temp:
list[j + gap] = list[j]
j -= gap
list[j + gap] = temp
# 得到新的步長
gap = gap // 2
return list
k数之和 TODO dp版本
SQLAlchemy
Flask-SQLAlchemy
Flask-Script
Flask-Migrate
Celery
设计模式
Flask
- response
- request
- session
- 路由
- 初始化配置
- config
- buleprint
- 特殊装饰器
- CBV
- requestsContent
websocket
原理,封包、解包
数据分析 爬虫
知识点总结
- 通用爬虫
- 聚焦爬虫
- 增量式
- requests模块 — urllib
- 爬取数据流程:
- 指定url
- 发起请求
- 获取响应数据
- 数据解析
- 持久化存储
- get,post作用:
- get,post参数:
- url
- headers
- params/data
- proxies
- 处理ajax动态加载的数据:
- url:必须通过抓包工具捕获
- get/post发起请求获取响应数据,对响应数据进行解析,持久化存储
-
模拟登陆:
- 打码平台使用:
- 开发者用户:
- 创建一个软件(id,秘钥)
- 下载示例代码
- 开发者用户:
- cookie的处理:
- 手动处理:
- 将cookie值封装到headers中
- 自动处理:
- session对象. session = requests.Session()
- 手动处理:
- 代理ip:
- proxies参数: requests.get(proxies={\’http://\’:\’ip:port\’})
- 透明,匿名,高匿
- 快代理,西祠代理
- 线程池:
- 图片懒加载:
- 伪属性:scr2
- 爬取数据流程:
- 数据解析
- 解析原理:
- 标签的定位
- 提取标签中的数据
- 正则表达式:
- bs4:
- soup.tagName
- find系列函数:
- find(\’tagName\’,class_=\’xxx\’)
- find_all(tagName)
- select:层级选择器(> )
- text,string,get_text()
- soup.a[\’href\’]
- xpath:
- xpath函数结合着xpath表达式实现标签定位和数据提取
- 解析原理:
- selenium
- 作用:实现浏览器自动化的操作(通过代码定制相关的行为动作,且将该行为动作同步映射到浏览器中)
- 使用流程:
- 导包:from selenium import webdriver
- 实例化一个浏览器对象(驱动程序)
- 发起请求(get)
- …
- 关闭浏览器(bro.quit())
- find系列函数:
- find_element_by_id
- 定位标签
- switch_to.frame函数:
- qq空间
- bro.switch_to.frame(\’iframe_id\’)
- page_source:
- phantomJs:
- 浏览器
- 谷歌无头浏览器:
- scrapy
- 项目创建流程:
- 创建工程
- cd ProName
- 创建爬虫文件
- 父类:Spider
- name
- start_urls
- parse(self,response)
- response.xpath(\’//a/@href\’):返回值是一个列表.(列表元素:Selector对象),extract/extract_first
- 持久化存储:
- 基于终端指令
- scrapy crawl spiderName -o xxx.csv
- 基于管道
- item对象:存储解析到的某一组数据.因为管道文件中的process_item这方法只可以处理和操作item类型的对象.
- 编码流程:
- 数据解析
- 实例化item对象,将解析到的数据封装到item对象中
- 将item提交给管道
- 在管道的process_item方法中接收item,将item中存储的数据进行持久化存储
- 在配置文件中开启管道
- 如何将同一份数据存储到不同的平台中?
- 在管道文件中封装多个管道类(负责将数据存储到一个平台)
- process_item中返回值(return item)的作用:传递给下一个即将被执行的管道类
- 基于终端指令
- 处理分页数据爬取:
- 基于全站数据爬取:
- 手动请求发送+递归解析
- 手动请求发送:
- yield scrapy.Request/FormRequest()
- 基于全站数据爬取:
- post请求
- start_urls:
- start_requests():
- cookie处理:
- 自动处理
- 日志等级:
- LOG_LEVEL=\’ERROR\’ LOG_FILE=\’log.txt\’
- 请求传参(item):
- 使用场景:当爬取的数据不在同一张页面中.
- yield scrapy.Request(url=url,callback=self.parse_detail,meta={\’item\’:item})
-
五大核心组件原理:
- 下载中间件:
- UA池和代理池:
- process_request(self,request,spider):
- request.headers[\’User-Agent\’] = random.chioose(UAList)
- process_exception(request):
- request.url 返回发生异常请求的url
- request.meta[\’proxy\’] = \’http://ip:port\’
- process_request(self,request,spider):
- selenium在scrapy中的应用:
- 编码流程:
- 实例化一个浏览器对象(爬虫文件的构造方法中)
- 在爬虫文件的closed方法中关闭浏览器对象
- 在中间件的process_response(response)方法中编写自动化的操作
- page_source(包含了动态加载的数据)
- 实例化一个新的响应对象,且将page_source封装到该响应对象中
- 返回新的响应对象
- 编码流程:
- crawlSpider:
- 全站数据爬取
- 创建爬虫文件的指令:scrapy genspider -t crawl spiderName xxx.com
- 爬虫文件的父类:CrawlSpider
- LinkExtractor:连接提取器,根据指定规则(正则)提取连接(url)
- Rule:规则解析器,负责将连接提取器提取到的连接发起请求获取对应的页面数据,且对该数据进行指定规则的解析.
- 一个连接提取器对应一个规则解析器.
- 深度提取:
- 项目创建流程:
- 分布式
- scrapy为何不能实现分布式:
- 管道和调度器无法被所有的分布式机群共享
- scrapy-redis的作用:
- 给scrapy提供了可以被共享的管道和调度器(spider)
- redis_key:
- 实现分布式的方式:
- 流程:
- scrapy为何不能实现分布式:
- 增量式爬虫
- 概念:用来 检测 网站数据的更新情况.
- 去重
- 对url去重
- 爬取的数据去重
案例总结
- 爬取肯德基餐厅位置信息:http://www.kfc.com.cn/kfccda/index.aspx
- 爬取药监总局:http://125.35.6.84:81/xk/
- 爬取糗事百科图片:https://www.qiushibaike.com/pic/
- 下载免费简历模板:http://sc.chinaz.com/jianli/free.html
- ConnectionPool:
- 请求过密,ip被封,连接池中的资源被耗尽
- sleep 代理ip headers中封装Connection:\’close\’
- ConnectionPool:
- 煎蛋网图片爬取:http://jandan.net/ooxx
- 解析城市名称:https://www.aqistudy.cn/historydata/
- xpath(\’xxx | xxx\’)
- 古诗文网:https://so.gushiwen.org/user/login.aspx?from=http://so.gushiwen.org/user/collect.aspx
- cookie
- 动态post请求参数
- 网易新闻:https://news.163.com/
- 动态数据加载
- scrapy+selenium
反爬机制总结
- robots.txt
- UA检测
- 验证码
- 数据加密
- cookie
- 禁IP
- 动态token
- 数据动态加载
数据清洗
- 空值检测删除空值所在的行数据:
- df.dropna(axis=0)
- 手动处理:
- 检测df中存在空值的行(isnull notnull any all)
- 获取行索引
- 使用drop删除指定的行(行索引)
- 将合适的bool值作为行索引
- 空值检测填充空值:
- fillna(method=\’ffill/bfill\’,axis=0/1)
- 异常值检测和过滤:
- 判断异常值的条件
- 条件对应的表达式一定是一组bool值(df[\’C\’] <= df[\’C\’].std()*2)
- 重复行检测和删除:
- drop_duplicated(keep)
面试题
- 如何提升爬虫的效率
- 线程池
- scrapy配置文件相关配置(禁用cookie,禁止重试,减小下载超时,增加并发,日志等级)
- scrapy核心组件工作流程
- scrapy中如何设置代理(两种方法)
- 中间件
- 环境变量(os.environ[\’HTTPS_PROXY\’] = \’https:ip:port\’)
- scrapy如何实现限速
- DOWNLOAD_DELAY = 1
- scrapy如何实现暂停爬虫
- JOBDIR=\’sharejs.com\’
- control-C
- pipeline如何丢弃一个item对象
- yield item 在spider 中判断
- item.class 在pipeline 中放弃持久化操作
- scrapy-redis组件作用
- 实现深度和广度优先:默认为深度优先。
- DEPTH_PRIORITY = 1
- SCHEDULER_DISK_QUEUE = \’scrapy.squeues.PickleFifoDiskQueue\’
- SCHEDULER_MEMORY_QUEUE = \’scrapy.squeues.FifoMemoryQueue\’
- 广度优先:不全部保留结点,占用空间少;运行速度慢
- 深度优先:保留全部结点,占用空间大;运行速度快
- https://www.cnblogs.com/zhaof/p/7092400.html
Git
git的使用生命周期
工作目录(你当前linux操作的目录) > 暂存区 > 本地仓库 > 远程github
git的命令,就是将文件变化,在这四个区域,来回变动
初始化git版本库的方式,有三个
1.对已经有的代码进行 版本管理
我这台机器 已经有了一个django项目,对它进行管理
1.对当前已经有的django项目进行git初始化
git init
2.查看git状态
git status #查看git状态
(gitlearn) [root@lht1 dj220]# git status
# On branch master #在master分支上
#
# Initial commit
#
# Untracked files: #未标记的文件如下
# (use "git add <file>..." to include in what will be committed)
#
# dj220/
# manage.py
3.git项目的第一次管理,初始化的流程
1.git init 对django代码初始化
2.git status 查看git版本库的状态
3.对django代码,进行跟踪,标记 ,然后提交本地工作区的代码,到暂存区
git add .
4.提交暂存区的代码,到本地版本库
git commit -m "写入你的提交备注信息"
# -m 是标记注释的意思
5.查看git提交日志
git log
6.git的各种命令,就是对四个区域来回切换,并且只能在git工作区下去敲
必须得在含有.git文件夹的目录,去敲命令,才可以
7.在git版本库目录下,新创建的文件,都会被标记为 Untracked files,代表未跟踪的文件
8.对新创建的文件,进行跟踪
git add .
9.修改django的url.py,写入新功能,也是对文件进行修改标记 modified
对修改过的代码文件,也必须git add 添加到暂存区
git add .
9.2 commit 新版本 git commit -m "XXXXX"
10.任何的对项目修改的操作,注意都要git status看一下
11.查看git提交日志
git log
12.git回退历史
语法: git reset --hard commit的id记录 --hard参数是强制性回退
git reset --hard 954e6df1c0a2a71dd141850727d3eddd580518b3
再次回到另一个提交版本信息,
git reset --hard 2444fd8ed876eab2a95a697d039916510b356104
13.git穿梭未来
git 回退,前进版本,其实就是是对git的文件指针,来回切换
文件指针叫做head
git reflog #查看所有回退历史记录的命令
然后再使用命令前进,其实就是修改了head指针
git reset --hard
14.撤回git修改的记录
对已经跟踪的文件app01/views.py进行修改,此时标记为了modified: app01/views.py
c
git add .
如果你发现代码修改错了,git可以很方便的撤回
git checkout -- 文件名
git checkout -- app01/views.py
15.理解git命令
git init 初始化一个git版本库,会生成一个.git 文件夹,此时这个目录就是git仓库了!!!
16.修改git工作区的文件,重命名,以及删除文件
linux的命令如下
rm 删除
mv 移动目录,或者重命名
但是,你对git仓库中的代码,请使用git的命令
git rm 删除git管理的代码
git mv 对git管理的代码,改名
17.git临时区的概念
使用场景:
git add 作用是? 是把本地工作区的代码,提交到暂存区
git commit 将暂存区的代码,提交到本地版本仓库中,提交完毕,这件事就结束了
使用流程,场景,在你开发新功能的时候,突然线上代码有问题,你必须得改线上代码,
将你目前已经开发好的功能,临时存储起来,
待你修复bug完毕之后,再把这个临时存储的代码,回退回来即可
:
1.git stash # 将你暂存区提交的代码,放到一个stash临时区中
2.修复bug完毕
3.拿回stash的代码
git stash pop
4.查看stash是否还有临时代码
git stash list
5.注意未标记的,已修改的文件,都得git add 添加到暂存区之后,才可以提交到本地仓库
git add .
6.如果你想提交这个代码
git commit -m "提交注释信息"
18.git分支功能,每个人都有自己的分支,不直接影响本体代码,在自己的分支上,写完代码后,通过管理员吧分支的代码,合并到主干上即可
git branch #查看当前所在的分支
git branch wupeiqi #创建吴佩琪分支
git branch alex #创建艾利克斯分支
git checkout wupeiqi #切换到吴佩琪分支
分支开发使用流程
1.创建新的分支
git branch wupeiqi
2.切换分支
git checkout wupeiqi
3.在分支下,写自己的代码
........ add , commit
4.切换到主干分支上
git checkout master
5.合并分支的代码,此时吴佩琪开发提交的代码,就被合并到master了
git merge wupeiqi
分支冲突怎么办?手动解决冲突的代码即可
思路:master分支和wupeiqi分支,同时操作一个文件,对同一行代码进行写入
0. git branch wupeiqi 创建另一个分支
1.用master主干分支,操作一个文件,并且提交commit
git branch #当前是主干master
模拟对一个文件的第二行写入代码
2.master提交本次修改记录
git add .
git commit -m "提交注释"
3.切换分支,也对同一个文件,进行写入代码,且提交
git checkout wupeiqi
模拟对同一个文件,写入同一行代码,肯定会和master冲突
git add .
git commit -m "分支提交的注释"
4.回到master主分支,合并吴佩琪分支,然后手动解决
git checkout master
git merge wupeiqi
如果出现了冲突,就手动编辑这个文件,删除git自动添加的冲突注释
5.再次提交
git add .
git commit -m "master最终合并的注释"
6.git分支的命令
git branch 分支名linux 创建分支linux
git checkout 分支名linux 切换分支到linux
git branch 查看当前分支情况,在哪一个就有*符
git check -- filename 一键还原文件,将git仓库的文件覆盖当前文件,危险命令
git checkout -b name 创建+切换新的分支
2.当前机器没有项目,直接进行git初始化,这个是管理一个空的目录
mkdir 目录名
git init 初始化这个空目录
3. 远程克隆下载一个项目,从github,或者gitlab ********公司使用方式是他
远程克隆下载一个项目,从github,或者gitlab ,一台新的机器,啥也没有,把公司的代码下载出来,进行开发,以及版本管理
github的使用
1.注册一个github账号
https://github.com
2.登录后,添加创建一个新的github仓库,用于传输本地代码
3.新建github仓库,填写github仓库的名字,描述信息,以及redame文件,以及忽略文件(忽略编程语言的一些缓存文件)
4.添加ssh秘钥,让github和linux机器进行免密登录
1.linux推送代码到github有2个登录方式
一个是账号密码方式
一个是ssh秘钥方式
2.选择ssh秘钥,安全性更高
ssh是一个远程安全登录的命令,可以通过ssh-keygen命令生成一对公私钥(其实就是2个秘钥文件),然后把公钥发给github,私钥自己本地保留
输入如下命令
[root@fd dj220]# ssh-keygen #这个命令生成一对公私钥,一路回车
Generating public/private rsa key pair.
Enter file in which to save the key (/root/.ssh/id_rsa):
Created directory \'/root/.ssh\'.
Enter passphrase (empty for no passphrase):
Enter same passphrase again:
Your identification has been saved in /root/.ssh/id_rsa.
Your public key has been saved in /root/.ssh/id_rsa.pub.
The key fingerprint is:
SHA256:ResKz3ErviC3OjbHe+Hqog2290YrqgCVlsMcpL+JUmg root@fd
The key\'s randomart image is:
+---[RSA 2048]----+
| .o . |
| + + . . |
|. O o |
| = . o |
|oEo . S o |
|oo o .+.+ . |
|+ = .ooo=.. |
|o. +Bo=+o. |
|..+=o@*+o. |
+----[SHA256]-----+
[root@fd dj220]#
[root@fd dj220]#
[root@fd dj220]# cd ~/.ssh/
[root@fd .ssh]# ls
#公私钥内容如下 id_rsa是秘钥 id_rsa.pub 是公钥
id_rsa id_rsa.pub
3.把公钥的内容,赋值粘贴发给github
#查看如下内容,
[root@fd .ssh]# cat id_rsa.pub
#将如下公钥信息,复制
ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABAQDKfEGqHrIf8n6NrawBFt0/slRobTVuI9HoLxBWx0SdhIj+ATKgsEoVryG1S3WXulStNgDqF4dBSTRbNPFO/rrMdyURYRnSceQBKdNe+SmW2ttb/bfxd4JOnsC2ARCBK+DCTB48gtoSx+x4AUx3HGMUkOlgCjhHxk55CaMY8BtrBvdBAuOtUrv2RVOiheTTI+Sr8OJL/7lHEkZWGkW1n+xnx4/Urph4oa6lg8gQgFMWlLA9z5+cN8ZrQUi0MLX4p2e8sYfMnkzra5sSsUKQulqRsATaD8RK4FD+VEDWYwGfbdncCIMgiqol6gEQXKc4OJ/mU/xQMx5RQFwQGXW4hFFX root@fd
4.此时你的linux 机器和github已经建立ssh通道了
5.获取你的github项目仓库地址
比如你的项目地址如下:
git@github.com:examole/example.git
6.在linux机器上配置远程仓库别名
# git remote add 都是关键字 然后给你的github项目地址添加一个别名叫做origin
git remote add origin git@github.com:examole/example.git
7.保证你的本地代码,和远程github仓库内容一致,如果不一致,会失败,先pull下载代码,保证一致性
git pull origin master #向远程的github origin别名下的master分支下载代码
8.此时可以吧你本地的代码,推送到github仓库了
#git push 是推送的意思 origin是远程仓库地址的别名 master 推到远程仓库的master分支上
#得到git管理的版本仓库下敲
git push origin master
9.去github去查看代码
到了公司里,给了你一个新电脑,该干啥???
1.配置ssh秘钥,方式在笔记上面
2.在一个目录,克隆一个新项目代码
git clone git@github.com:examole/example.git
3.在github仓库下,在浏览器中,新建一个分支,名字是development
4.下载最新的github代码
git pull origin
5.此时项目,默认只有一个master分支,所以需要新建一个分支去开发,便于维护master的代码
#在本地新建一个dev分支,并且和远程的github的dev分支建立关系
git branch development origin/development
6.在项目中使用development分支去开发
...开发代码省略...
7.提交本地开发
git add .
git commit -m "分支提交了新的代码"
8.提交分支本地的代码,到github中
git push origin development
9.合并分支代码,推送到master主干线中
git checkout master
git merge development #合并分支的代码
git push origin master #推送本地master的代码到github中
git常用命令
git init 初始化
git status 查看git版本库的状态
git add 指定文件或者 .
git commit -m "提交的注释" 提交暂存区的内容到本地仓库
git checkout 文件名 #撤回对文件的修改
git checkout 分支名 #切换不同的分支
git log #查看git提交的日志记录
git reflog #查看所有提交以及回退的记录
git reset --hard commitID #回退到某一个提交的id版本下
git config --global user.name "你的名字"
git config --global user.umail "你的邮件"
git branch #查看分支
git branch 分支名 #创建一个新的分支
git branch -d 分支 #删除这个分支
git checkout -b 分支名 #创建并且切换到一个新的分支下
git stash #将暂存区的记录,临时放到一个区域 ,先git add之后,再git stash
git stash pop #删除最后一个stash记录,放回暂存区
git rm #删除git版本库中的文件
git mv #改名
git remote add 别名 github仓库的地址
用法如下
git remote add origin git@github.com:examole/example.git
git push 别名 分支名
用法
git push origin master #推送本地git仓库到github仓库了
git pull origin master #下载github远程仓库到本地来
nginx git yum python mysql redis 都是linux上的软件
gitlab私有仓库的搭建, github共有仓库不安全,虽然现在也有私有仓库的功能了
携程,美团运维开发组都是搭建的gitlab企业私有代码仓库
1.环境配置,至少4G内存的虚拟机
2.通过yum安装gitlab,阿里云的源也没有gitlab这个软件包
解决方案:1.选择gitlab官网提供的yum仓库地址
2.还是去找一个第三方,拥有gitlab软件包的yum仓库
3.配置清华大学的yum源
找到yum仓库目录
/etc/yum.repos.d
然后手动创建一个 以.repo结尾的文件
touch gitlab.repo
4.写入如下信息
cat gitlab.repo
[gitlab-ce]
name=Gitlab CE Repository
baseurl=https://mirrors.tuna.tsinghua.edu.cn/gitlab-ce/yum/el$releasever/
gpgcheck=0
enabled=1
~
5.安装gitlab
yum install gitlab-ce
6.如何启动?
确保服务器内存足够,可以用如下三个命令,清空buff内存缓存
[root@DD-Server-9F ~]# echo 1 > /proc/sys/vm/drop_caches
[root@DD-Server-9F ~]# echo 2 > /proc/sys/vm/drop_caches
[root@DD-Server-9F ~]# echo 3 > /proc/sys/vm/drop_caches
gitlab-ctl reconfigure 初始化gitlab,只能执行一次
gitlab-ctl status/stop/start 启动gitlab
gitlab-ctl status #确保你的gitlab启动了
访问方式:
直接访问你linux服务器的ip即可,注意关闭linux防火墙(咱们学习阶段的配置)
iptables -F #清空规则
systemctl stop firewalld
systemctl disable firewalld
#临时关闭selinux,也是一个防火墙
setenforce 0
#永久关闭selinux,修改/etc/selinux/config
修改如下参数
通过浏览器访问页面服务器ip,默认开启了nginx的web端口,设置初始密码,操作类似github
第一次访问会设置新密码 至少8个字符
默认登录用户root
密码11111111
即可看到gitlab
2.启动了gitlab之后,修改了账号密码
3.配置ssh公钥,发送给gitlab
4.下载私有的gitlab仓库
git clone git@192.168.15.62:root/s16gitlab.git
5.进入gitlab下载的代码中,此时就可以pull push代码了
Linux
linux是操作系统的平台,安装了linux系统的机器,称为服务器
我们本地开发的机器 windows系统,测试开发使用
1.linux服务器,
有centos7发行版,有ubuntu,redhat发行版
手机(linux) 是个名词
redhat,ubuntu(华为,iphone)
2.物理服务器,真实的一台机器
3.阿里云服务器(用的最多的)
服务器的ip地址
服务器的账号
密码
4.如何登陆使用服务器呀
-你可以选择用xshell工具,远程登录linux服务器,去使用服务器的!!!!
-macos自带的 ssh命令
-secureCRT也是远程登录工具
5.用命令登录
ssh 用户名(linux服务器的那个用户,基本是运维给你创建的)
ssh root@服务器的ip
6.vmware workstation (虚拟化操作系统工具)
-下载你想要的操作系统,你可以去阿里云镜像站去下载
https://opsx.alibaba.com/mirror
-获取操作系统地址后,下载即可
LInux复习题
答案linux考试题
- 在登录Linux时,一个具有唯一进程ID号的shell将被调用,这个ID是什么(b)
A.NID B.PID C.UID C.CID
答:
w命令查看用户tty终端信息
ps -ef|grep pts/0 - 下面那个用户存放用户密码信息(b)
A./boot B./etc C./var D./dev - 用于自动补全功能时,输入命令或文件的前1个或后几个字母按什么键(b)
A.ctrl B.tab C.alt D.esc - vim退出不保存的命令是(d)
A.:q B.q C.:wq D.:q! - 文件权限读、写、执行三种符号的标志依次是(a)
A.rwx B.xrw C.rdx D.rws - 某文件的组外成员的权限是只读、属主是全部权限、组内权限是可读可写、该文件权限为(d)
A.467 B.674 C.476 D.764 - 改变文件的属主的命令是(c)
A.chmod B.touch C.chown D.cat - 解压缩文件mydjango.tar.gz,我们可以用(a)
A.tar -zxvf mydjango.tar.gz
B.tar -xvz mydjango.tar.gz
C.tar -czf mydjango.tar.gz
D.tar – xvf mydjango.tar.gz - 检查linux是否安装了,可用哪些命令(b) #注意rpm -qi只能查询用yum安装的软件,编译的查不到
A.rpm -ivh nginx
B.rpm -q nginx
C.rpm -U nginx
D.rpm -x nginx - Linux配置文件一般放在什么目录(a)
A.etc B.bin C.lib D.dev - linux中查看内存,交换内存的情况命令是(c) #free -m
A.top(任务管理器) B.last(用户最后登录信息) c.free() D.lastcomm - 观察系统动态进程的命令是(b)
A.free B.top C.lastcomm D.df - 如果执行命令,chmod 746 file.txt ,那么该文件的权限是(a)
A.rwxr—rw-
B.rw-r—r—
C.—xr—rwx
D.rwxr—r— - 找出当前目录以及其子目录所有扩展名为”.txt”的文件,那么命令是(d)
A.ls .txt
B.find /opt -name “.txt”
C.ls -d .txt
d.find -name “.txt” - 什么命令常用于检测网络主机是否可达? c
A.ssh(远程登录) B.netstat(查看Linux端口信息) C.ping D.exit(退出会话) - 退出交互式shell,应该输入什么? d
A:q! B.quit C.; D.exit - 创建文件时父目录不存在,添加的参数是? d
A.-P B.-d C.-f D.-p - 下列文件中,包含了主机名到IP地址映射关系的文件是? b
A./etc/hostname 主机名
B./etc/hosts 强制写入域名解析记录
C./etc/resolv.conf 存放dns服务器的文件
D./etc/networks- 查看网站的web服务器种类 curl -I 域名/ip
- 请问你使用的linux发行版是什么?如何查看linux发行版信息?
centos7
cat /etc/os-release - 请问你公司的服务器环境是物理机还是虚拟化?
500人企:
26台dell power r720服务器,托管在世纪互联
通过vmware esxi虚拟化的280+linux服务器,有100+centos 100+redhat
分为三个环境
测试服务器、预生产服务器、生产服务器
技术栈:
svn 、java、apache、tomcat、oracle、nagios、redhat、centos、weblogic
初创企业:
5台阿里云 - vim有几种工作模式
命令模式
编辑模式
底线命令模式 - nginx的主配置文件是?如何实现多虚拟主机?nginx反向代理参数是?
nginx.conf
多个server{}
proxy_pass http://ip - 如何解压缩后缀是.gz文件?
gipz -d *.gz - 如何解压缩后缀是.tar文件?
tar -xf .tar - 如何解压缩后缀是.xz文件?
xz -d .xz - www服务在internet最为广泛,采用的结构是?
Browser/Server - 如何给linux添加dns服务器记录?
/etc/resolv.conf
添加2条主备dns记录
nameserver dns服务器ip - 每月的5,15,25的晚上5点50重启nginx
ctontab -e 详情
50 17 5,15,25 /usr/bin/systemctl restart nginx
50 17 5,15,25 /opt/nginx112/sbin/nginx -s reload - 每分钟清空/tmp/内容
/usr/bin/rm -rf /tmp/*
- 每天早上6.30清空/tmp/的内容
30 6 /usr/bin/rm -rf /tmp/ - 每个星期三的下午6点和8点的第5到15分钟之间备份mysql数据到/opt/
* * * * * 命令
分 时 日 月 周 命令(绝对路径)
5-15 18,20 3 /usr/bin/cp -r /var/lib/mysql /opt/ - 某文件权限是drw-r—rw-,请解读该权限?
d:目录文件
rw- 属主:可读可写
r— 属组:可读
rw- other:可读可写 - centos版本系统服务管理命令是?
centos6 service
centos7 systemctl - 如何远程登录阿里云123.206.16.61?
ssh root@123.206.16.61 - 备份mariadb的命令是?
mysqldump -uroot -p - 简述特殊符号的含义?
# root用户的身份提示符 或 注释符
$ 普通用户身份的提示符
. 当前目录
.. 上一级目录
- 上一次工作目录
$PATH 取值环境变量的值
> 重定向覆盖写
>> 重定向追加写
- 如果你发现在公司无法使用rm,使用提示’禁止你使用rm’,是为什么?
别名alias 或者 配置了权限 - 如何修改test.py属组为alex?
chgrp alex test.py - 如何在windows和linux传输文件?有哪些方法?
xftp (建立ssh)、lrzsz(拖动发送,rz,sz)、 scp(linux 之间) - 如何杀死mariad进程?
杀死一个进程
ps -ef | grep mariadb
kill pid
杀死一组进程
pkill mariadb
killall mariadb
- 简述dns解析流程?访问www.pythonav.cn的解析流程
自上而下的顺序
1.优先查找本地dns缓存
2.查找本地/etc/hosts文件,是否有强制解析
3.如果没有去/etc/resolv.conf指定的dns服务器中查找记录(需联网
4.在dns服务器中找到解析记录后,在本地dns中添加缓存
5.完成一次dns解析 - linux如何安装软件?有几种方式?
yum 自动解决依赖关系,只需要配置好yum仓库,适合安装各种小工具,并且不需要自定义的软件
rpm 舍弃
源码包 可以自由定制软件 - 出于安全角度,简述如何安装启动redis服务端?
更改端口
开启protomode yes安全模式
设置redis密码
redis-server redis.conf - 如何保证本地测试环境和线上开发环境一致性?思路?
1.docker打包镜像
2.手动解决环境问题 pip3 freeze导出依赖 - virtualenv是什么?简述如何使用
在开发Python应用程序的时候,系统安装的Python3只有一个版本:3.4。所有第三方的包都会被pip安装到Python3的site-packages目录下。
如果我们要同时开发多个应用程序,那这些应用程序都会共用一个Python,就是安装在系统的Python 3。如果应用A需要jinja 2.7,而应用B需要jinja 2.6怎么办?
这种情况下,每个应用可能需要各自拥有一套“独立”的Python运行环境。
virtualenv就是用来为一个应用创建一套“隔离”的Python运行环境。
1.安装 pip3 install virtualenv
2.创建虚拟环境 virtualenv —no-site-packages —python=python3 env1
3.激活虚拟环境 sourcce /opt/MyVirtualenv/venvDjango1/bin/activate
4.测试 python3 或者 pip3 list
46.virtulevnwrapper是什么?简述使用
解决python解释器模块依赖问题的,可以在一台机器上,虚拟化出N多个解释器,解决环境隔离问题
virtualenv 的一个最大的缺点就是,每次开启虚拟环境之前要去虚拟环境所在目录下的 bin 目录下 source 一下 activate,这就需要我们记住每个虚拟环境所在的目录。
Virtaulenvwrapper是virtualenv的扩展包,用于更方便管理虚拟环
1.安装虚拟环境 pip3 install virtualenvwrapper
2.创建并进入虚拟环境 mkvirtualenv env1
3.切换虚拟环境 workon 虚拟环境名
redis是什么?
Redis是一个开源的基于内存的,key-value数据结构的缓存数据库,支持数据持久化,m-s复制,
常用数据类型有string set hash list,
最佳应用场景:适用于数据变化的应用程序。
例如:股票价格、数据分析、实时数据搜集、实时通讯。
Redis只能使用单线程,性能受限于CPU性能,故单实例CPU最高才可能达到5-6wQPS每秒
(取决于数据结构,数据大小以及服务器硬件性能,日常环境中QPS高峰大约在1-2w左右)
redis持久化机制
rdb
aof
redis 相关 https://www.cnblogs.com/pyyu/tag/redis/
其他nosql数据库?
QPS每秒查询速度
Memcached可以利用多核优势,单实例吞吐量极高,可以达到几十万QPS(取决于key、value的字节大小以及服务器硬件性能,日常环境中QPS高峰大约在4-6w左右)
php + memcache开发的抢红包后台
。适用于最大程度扛量。
只支持简单的key/value数据结构,不像Redis可以支持丰富的数据类型。
无法进行持久化,数据不能备份,只能用于缓存使用,且重启后数据全部丢失。
MongoDB
更高的写负载,MongoDB拥有更高的插入速度,支持高可用性,支持索引高速查询,占用磁盘空间较大,支持持久化
redis主从复制
思路
1.通过redis.conf 支持多实例的数据库功能
2.在配置文件中添加
slaveof 127.0.0.1 端口
即可配置主从关系
如果主从复制架构故障,master宕机,背景,一主两从,主6380,从6378、6381
解决思路
1.2个从库功能都还尚好,数据也在,第一步应该数据持久化,防止数据丢失
2. 6379 6381两个从库还活着,登录某一个数据,进行持久化,建立6379是主库,6381是新的从库
redis-cli -p 6379
先save保存数据
然后 slaveof no one
3.登录6381数据库,更改主从身份
slaveof 127.0.0.1 6379
手动切换故障如上
自动切换 redis哨兵功能
1.环境准备,三个redis哨兵(保安)配置文件 ,3个redis数据库配置文件
-rw-r--r-- 1 root root 28 Apr 20 19:52 redis-6379.conf 三个redis数据库之间是端口的区分,和slaveof参数的区分
-rw-r--r-- 1 root root 50 Apr 20 19:53 redis-6380.conf
-rw-r--r-- 1 root root 51 Apr 20 19:54 redis-6381.conf
三个哨兵配置一模一样,仅仅是端口的区分
-rw-r--r-- 1 root root 0 Apr 20 19:51 redis-sentinel-26379.conf
-rw-r--r-- 1 root root 0 Apr 20 19:51 redis-sentinel-26380.conf
-rw-r--r-- 1 root root 0 Apr 20 19:51 redis-sentinel-26381.conf
4.分别启动三个redis哨兵,三个redis主从架构
5.启动正确,即,redis哨兵,能够自动切换主从故障
TODO 如果不懂可以在237视频最后一部分看到
-
redis哨兵是什么?作用是
Redis-Sentinel是Redis官方推荐的高可用性(HA)解决方案
redis哨兵是监控redis主从服务,不存储数据的,作用是用于自动切换reidis服务主从关系,即当主库服务停止后,会将其中一个从库变为主库 -
redis-cluster是什么?
即使使用哨兵,redis每个实例也是全量数据存储,每个redis存储的内容都是完整的数据。
为了最大化利用内存,可以采用cluster群集,就是分布式存储。即每台redis存储不同的内容。
采用redis-cluster架构正是满足这种分布式存储要求的集群的一种体现。redis-cluster架构中,被设计成共有16384个hash slot。每个master分得一部分slot,其算法为:hash_slot = crc16(key) mod 16384 ,这就找到对应slot。采用hash slot的算法,实际上是解决了redis-cluster架构下,有多个master节点的时候,数据如何分布到这些节点上去。key是可用key,如果有{}则取{}内的作为可用key,否则整个可以是可用key。群集至少需要3主3从,且每个实例使用不同的配置文件。
redis-cluster搭建 详情 redis-cluster配置
- 什么是静态资源,什么是动态资源?
静态资源指定的是网站的CSS/JS/HTML文件
动态资源一般指的是数据,即后端给前端提供的数据 - 配置linux软连接的命令?
ln -s 目标文件名 软连接名
ln -s /root/大爷来玩呀 /tmp/hehe.txt
- 如何永久添加/opt/python36/的环境变量?
vim /etc/profile 每次登陆都会加载这个全局文件
添加PATH = /opt/python36/bin:
source /etc/profile
52.给如下代码添加注释
server{ # 一个虚拟主机
listen 80; # 监听的端口,访问的端口80
server_name 192.168.11.11; # 访问的域名192.168.11.11
location / { # 访问的路径 / 当你请求url是 192.168.11.11:80/
root html; # 指定页面的目录,访问/会找到html目录
index index.html # 指定网页,访问/就是访问index.html
}
}
server{ #虚拟主机
listen 8080; #nginx监听端口
server_name 192.168.11.11; #nginx访问域名
location / { #location匹配url
include uwsgi_params; #将uwsgi参数添加进nginx
uwsgi_pass 0.0.0.0:8000; #反向代理转发请求给uwsgi
}
}
- supervisor是什么?如何使用? 后台管理进程任务的
你本来自己手动敲的命令,现在交给supervisor去管理
使用:
1.安装 easy_install supervisor
2.生成配置文件 echo_supervisord_conf > /etc/supervisor.conf
3.写入自定义的配置
[program:crm] ; 项目名称
command=/root/Envs/knight/bin/uwsgi —ini /opt/knight/uwsgi.ini ;启动项目的命令
stopasgroup=true ;默认为false,进程被杀死时,是否向这个进程组发送stop信号,包括子进程
killasgroup=true ;默认为false,向进程组发送kill信号,包括子进程
4.启动supervisor服务
supervisord -c /etc/supervisor.conf
5.启动所有项目
supervisorctl -c /etc/supervisor.conf start all
54.简述项目部署流程?如何部署路飞,uwsgi+nginx+supervisor+nginx
部署路飞:
1.安装python3 环境
2.安装 mysql,redis,nginx
3.部署前端
1.安装node.js的环境
2.安装依赖包 npm instlal
3.修改axios的发送的端口接口 axios.get("后台接口的地址 ")
4.打包
4.部署后端
1.安装virtualenv
2.创建虚拟环境
3.安装django和uwsgi,以及项目的依赖包
4.修改uwsgi的配置文件
5.通过uwsgi -ini 配置文件启动django项目
5.配置nginx
1.创建两个虚拟主机,分别监听80和8000端口
2.访问80端口是访问呢vue
3.访问8000端口是vue发起的8000端口请求,反向代理到9000的uwsgi
6.启动nginx,mysql,redis
7.通过supervisor来管理
-
docker是什么?简述docker优势
linux容器软件
docker应用于快速构建应用,解决环境部署依赖的麻烦问题 -
你常用的docker常用命令有哪些?操作镜像、容器、仓库的命令
docker images # 查看本地镜像
docker serach 镜像 # 通过docker hub搜索镜像
docker rmi 镜像 # 删除镜像
docker save 镜像 > 路径 # 导出镜像
docker load < 路径 # 导入镜像
docker build -t . # 打包生成镜像,打包dockerfile生成docker镜像
docker的生命周期
开发写好 dockerfile ,docker build 生成镜像
镜像文件 就可以生成docker容器了,应用跑在docker容器当中
镜像文件,通过docker hub同一管理
镜像
容器
仓库
操作容器命令:
docker run -d 镜像 解释器 # 根据镜像生成容器,后台允许
docker run -it 镜像 解释器 # 根据镜像生成并进入容器
docker start/stop 容器id # 启动/停止容器
docker ps # 查看当前运行的容器
docker rm 容器id # 删除容器
docker exec 容器id # 进入当前正在运行的容器
docker commit 容器id 镜像名 # 将容器提交为镜像
docker contain ls # 查看当前运行的容器
操作仓库的命令:
docker pull 镜像 # 下载镜像
docker push 镜像 # 推送镜像
- 哪个命令无法查看linux文件内容? d
A.tac B.more C.head D.man - 使用rm -i 系统会提示什么信息? b
A.命令所有参数
B.是否真的删除
C.是否有写的权限
D.文件的路径 - 为何说rm -rf 慎用? -r递归删除 -f强制删除
60 .python操作linux的模块是? os,subprocess ,sys
-
如果端口8080被占用,如何查看是什么进程? netstat -tunlp | grep 8080
-
redis是如何做持久化的?
RDB AOF
rdb
定期执行save指令
Redis会定期保存数据快照至一个rdb文件中,并在启动时自动加载rdb文件,恢复之前保存的数据,通过save指令触发持久化,redis单独开启一个子进程进行数据持久化。
rdb缺点,定期执行,可能会丢失数据,并且数据量特别大时候,如果服务器cpu性能较低,rdb开启子进程持久化性能影响很大,影响redis对外提供服务的能力。
2U
4G内存
3G的数据 需要持久化
aof
Redis会把每一个写请求都记录在一个日志文件里。
在Redis重启时,会把AOF文件中记录的所有写操作顺序执行一遍,确保数据恢复到最新。
随着AOF不断地记录写操作日志,因为所有的操作都会记录,所以必定会出现一些无用的日志。大量无用的日志会让AOF文件过大,也会让数据恢复的时间过长。
优先:数据安全,不怕数据损坏,如断电等问题,还可以用redis-check-aof修复数据,AOF文件人为可读
缺点:占磁盘,性能损耗高,数据恢复慢
jemmory
怎么用rdb和aof
如果既配置了RDB,又配置了AOF,则在进行数据持久化的时候,都会进行,但是在根据文件恢复数据的时候,以AOF文件为准,RDB文件作废
-
简述mysql主从复制原理?
(1) master将改变记录到二进制日志(binary log)中(这些记录叫做二进制日志事件,binary log events);
(2) slave将master的binary log events拷贝到它的中继日志(relay log);
(3) slave重做中继日志中的事件,将改变反映它自己的数据。 -
创建mysql用户alex,并且授予权限select权限,命令是什么?
useradd 创建linux用户
create user alex@"%" identified by "alexdsb";
grant select on *.* to alex@’%’;
- nginx如何实现负载均衡?负载均衡的目录? 请求分流,解决单点机器的压力 ,压力平摊
123.206.16.61 access.log 检测用户来源ip
upstream mydjango {
server xxx
server xxx
server xxx
ip_hash;
}
uwsgi_pass mydjango
- nginx的负载均衡调度算法有几种?是什么?
调度算法 概述
轮询 按时间顺序逐一分配到不同的后端服务器(默认)
weight 加权轮询,weight值越大,分配到的访问几率越高
ip_hash 每个请求按访问IP的hash结果分配,这样来自同一IP的固定访问一个后端服务器
url_hash 按照访问URL的hash结果来分配请求,是每个URL定向到同一个后端服务器
least_conn 最少链接数,那个机器链接数少就分发
- linux下载软件包的方法有?
wget
curl
yum
- windows和linux常用远程连接工具有哪些?
xshell
putty
securecrt
macos 自带 ssh
-
如何给与一个脚本可执行权限
chmod u+x file
-
过滤出settings.py中所有的空白和注释行
grep -v “^#” file |grep -v “^$”
-
过滤出file1中以abc结尾的行
grep “abc$” file1
-
容器退出后,通过docker ps查看不到,数据会丢吗?
docker ps #查看的是正在运行的docker容器
docker ps -a #查看所有运行过的容器记录 ,这个容器挂了,但是没被删除
不会,因为docker ps -a 还能查到容器记录,数据存放在这个容器记录中
如果docker ps -a 也看不到或者被 docker rm 容器id 删除后,数据即丢失
- 如何批量清理后台停止的容器
docker rm docker ps -aq
docker ps -aq #取出所有的容器id号
docker ps -aq
#代表保存这个命令的值
- 如何查看容器日志?
比如你的crm跑在docker容器中
docker logs -f 容器id ,查看容器正在运行的日志信息
tail -f
-
wsgi是什么?
WSGI是Web服务器网关接口。它是一个协议,描述了Web服务器(nginx,uWSGI)如何与Web应用程序(web框架 django flask )通信。 -
Django中使用的是?
wsgiref 是个单击socket模块,性能很低,用于测试django代码正常运行的
uwsgi 替代wsgiref
uwsgi –ini uwsgi.ini
uwsgi支持多进线程,让你的django,并发性更好
用nginx结合uwsgi,nginx处理静态文件,uwsgi处理动态请求,实现网站的高并发
答:Django中实现wsgi的是:wsgiref和uwsgi,wsgiref是开发测试用的,uwsgi是线上用的。
Flask中实现wsgi的是:werkzurg
Tornado中实现wsgi的是:tornado和gevent
greenlet
asyncio
- 消息队列的作用? 实现消息队列的软件,市面主流的有 kafka,rabbitmq,nsq,等等等….
1)程序解耦
2)数据冗余,例如rabbitmq的ack机制,消息确认机制
rabbitmq支持数据持久化,消息持久化
3)削峰能力
假设我本来业务,路飞本来只有 8个服务器,支撑业务正常运转
路飞突然有一天要做一个秒杀活动
4)可恢复性,就算系统中部分组件挂掉,消息在队列也不丢失,待组件恢复后继续处理消息。
5)异步通信,如发红包,短信等流程丢入队列,可以优先级很低的去处理。
git常用命令
本地工作区 git add
暂存区 git commit -m “注释”
本地代码仓库 git push
公网代码仓库 github
1:git init—————————初始化 ,这个文件夹就是一个git工作区了
2:git add .————————-从工作区,添加到版本库
3:git commit -m”xxx”————从暂存区,添加到分支
4:git status————————查看状态
5:git log —————————查看版本库的日志
6:git reflog————————查看所有日志,用于回退历史版本记录的
7:git reset —head 提交id号 —-切换
8:git stash————————-将暂存区中的数据,放到一个临时区
9:git stash————————-将第一个记录从“某个地方”重新拿到工作区(可能有冲突)
git stash list——————————————————————————查看“某个地方”存储的所有记录
git stash clear—————————————————————————-清空“某个地方”
git stash pop——————————————————————————-将第一个记录从“某个地方”重新拿到工作区(可能有冲突)
git stash apply —————————————————————————编号,将指定编号记录从“某个地方”重新拿到工作区(可能有冲突)
git stash drop —————————————————————————编号 ,删除指定编号的记录
10:git branch dev—————创建分支
11:git branch -d dev———-删除分支
12:git checkout dev————切换分支
13:git merge dev—————-合并分支 ,先切换到master分支,然后合并dev分支
14:git branch———————查看所有分支
15:git clone https:xxx——-克隆 ,在一个新的机器上,如果没有代码,可以从github克隆一个
16:git add origin https:xxx-起个别名
17:git push origin dev ——添加到dev分支
18:git pull origin master—拉代码
19:git fetch origin master-去仓库获取
20:git merge origin/master-和网上下的master分支合并
协同开发:
默认线上diamante是master分支——————————master
开发的分支—————————————dev
做代码review————————————review(代码审计的分支 )
程序员自己的分支——————————…….
1:每个员工创建自己的分支
2:将自己的代码提交的到自己的分支—————xxx,sss,wwww…….
3:由组长或老大做代码的review,——————-代码提交的review分支
4:再提交到dev.
5: 再合并到master分支
熟悉 Linux常用操作。
1:man rm———————————————查看命令帮助
2:mkdir———————————————-创建目录
3:touch———————————————-创建文件
4:cd—————————————————切换。
5:ls—————————————————查看目录
6:ls -lh————————————————查看目录详细
7:pwd————————————————-查看当前目录
8:vim————————————————-添加内容
9:echo————————————————追加内容
10:cat————————————————查看文件内容
11:mv————————————————-移动
12:cp————————————————-拷贝
13:mv————————————————重命名
15:find———————————————-搜索
16:rm————————————————-删除数据
17:ping———————————————-查看能不能上网
19:tar cf ————————————————打压缩
20:tar xf——————————————-解压缩
安装:
yum install
rpm包安装
编译安装
快捷键:
1:Tab键—————————————-自动补全命令或路劲。
2:ctrl+l—————————————清屏
3: ctrl+c—————————————取消当前操作
4:vi/vim 快捷键:
复制当前行 ——————————yy
粘贴—————————————-p
剪切—————————————-dd
撤销—————————————-u
恢复—————————————-ctrl + r
路飞项目
项目介绍
2012年 -> 卖视频 1000RMB
2014年 -> 和51CTO合作, 老师直播答疑, 3000RMB ~ 5000RMB
2015底, -> 一对一导师服务, 6到7K
2017年7月 做路飞
通过一些技术的手段, 让学员在线上也可以学的更好.
项目架构
- 主站(供广大用户访问, 在上学习)
- luffiyadmin root123456
- 管理后台(运营维护网站站点)
- 导师后台(供导师使用的)
组织结构
- CEO (架构师, 把控项目的进度, ) 1
- 产品(提需求, ) 产出 -> 原型图, 产品需求文档 1
- UI 根据原型图 产出 -> 设计图 1
- 开发(前端1, 后端各一个, 1写管理后台) -> 概要设计文档 –> 评审 ——》开发
- 测试 (测试) 产出 -> 测试用例, 测试
- 运维 (上限) 部署项目架构, 项目上线
- 运营
技术栈
- nginx
- web服务器, 动静分离, 负载均衡, 反向代理
- 提高网站的并发性
- uwsgi
- 网关接口, 用来连接 django服务和nginx服务的桥梁
- django+drf
- 实现业务逻辑
- vue
- 前端的页面渲染
- mysql 重点
- 提供数据服务
- 索引, 事务,
- redis 重点
- 提供缓存服务
- 为什么要用redis(减小数据库的压力, 读取效率高, )
- redis的数据类型你都有哪些业务场景,
- jwt
- 用户认证系统
- jenkins
- 自动化部署的工具
- CI 持续集成
- sentry
- 错误日志的收集管理工具, 提供了一个web页面让你的错误信息可视化
- logging除了可以做错误日志信息的收集, 还可以做用户日志分析.
- celery
- 异步和定时任务
- 发送邮件
- 超过24小时订单关闭
- 导师超过24小时未跟进惩罚
- 异步和定时任务
- 第三方的服务
- 微信和支付宝的支付, 通知消息
- 视频服务
- 短信服务
- 滑动验证
项目周期
- 第一版本(2017-07 ~~ 2017-11, 一直处于一个维护的阶段至新年)
- 课程
- 课程的展示, 专题课和学位课
- 用户
- 登录注册/短信登录
- 滑动验证码
- 支付
- 从课程页面点击立即购买, 跳转到确认订单页面
- 触发确认订单的接口, 用户的购买信息(课程ID, 有效期ID), 后台校验并验证, 课程, 返回课程信息, 返回可用的课程优惠券, 通用优惠券, 可用的虚拟货币, 让用户选择最优支付方案, 进行支付, 校验通过, 生成订单, 根据用户选择的支付方式, 生成支付链接, 跳转, 让用户进行支付, 支付成功之后, 修改订单状态, 创建用户报名的课程.
- 策略模式,支付,课程优惠券,通用优惠券,贝利,
- 存储,临时数据,操作频繁
- 购物车
- 缓存数据结构
- 奖惩体系
- 导师超过24小时未跟进扣导师费
- 未批改作业扣费
- 视频服务
- 自己做 不安全
- 保利威视频服务
- 资讯
- 类似于博客
- 课程
- 第二版本(2018-03 ~~ 2018-07, 题库)
- 爬虫, 人为出题
- 进行用户的行为埋点, 比如说 用户观看的视频数, 某个视频次数, 观看视频的时长, 错题情况, , 多个系列的维度, 可以给它推荐题.
- 第三版本(2018-08 ~~ 2018-12, )
- 问答系统(学员提问题, 导师回答)
- 评价系统(评价作业, 评价跟进信息, 评价回答信息)
- 网站改版, 业务逻辑并没有多大变化,(维护你的项目)
项目中遇到的问题
- 产生重复订单的问题 (网络不好,前端页面没反应,用户多次下单)
- 前端
- 后端
- 用户支付成功, 服务宕机了, 如何解决
- 1, 第三方支付平台, 每隔2分钟, 4分钟, 8分钟, 在没有响应正确的字符串的情况下, 24个小时
- 2, 定时任务, 每隔一段时间, 查询未支付成功的订单, 根据订单号根据支付方式, 去第三方平台查询是否支付成功
- 在服务器上跑, 经常会抛出内存错误,
- uwsgi + django 观察, 把问题规模不断地进行缩小,
- 结果,调整的uwsgi的配置参数, workers, 调优, 服务器的横向扩展
- 遇到不会写的情况
- 画流程图
- 伪代码
项目的亮点
- 项目优化做的特别好
- 项目文档设施很完善(开发说明文档)
- 代码格式很规范, 遵守PEP8规范,
- git协作开发
- 抽离出很多公共的代码, 让它复用性很强, 不要重复造轮子
- 支付, 短信, 业务层面
- 项目架构很好
- 扩展性好等等
扩展
- redis
- 为什么要用redis? (缓存数据库, 非关系型数据库)
- 读写速度快, 丰富的数据类型, 支持持久化
- 数据类型的业务应用
- 购物车, redis, 哈希, 字符串, 比如说 哈希 {“SHOP_CART”: “UID”: “json数据结构”}
- 字符串结构自增, 学习人数, 点赞
- 做好宕机的准备
- 集群, 哨兵监控
- 持久化(AOF, RDB)
- 为什么要用redis? (缓存数据库, 非关系型数据库)
- mysql数据库是怎么设计的, 数据库优化
- 数据库引擎选型,
- 建索引,
- explan 分析sql语句, 用索引
- 慢日志查询
- 为什么要用读写分离, 好处: ….
学习链接
- pythonCookBook, 流畅的python
- 掘金, 极客时间
- 缓存: https://juejin.im/post/5b961172f265da0ab7198f4d
- 索引: https://juejin.im/post/5cb1dec9f265da0382610968
- 有一个无序列表, 找出第五大个数, [4, 19, 1, 8, 14, 22, 101, 3]
- 25匹马, 5个赛道, 找出前三名.
第三方服务
sentry
日志
ck-editor
富文本编辑框
说明: https://www.jianshu.com/p/65d2a748634b
读写分离
视频配置
- 保利威服务
logging配置
last day
今日内容
- 模拟面试(回顾和补充)
- 简历的撰写
- 就业标准(工作)
- 复习计划 ( 执行力 )
模拟面试
-
- python怎么学的? 有运维经验.
- 组织架构.
- git合并时间.
- 代码review
- git知识补充:
- git是做版本管理的 ( SVN & VSS)
- git + github / 码云 / gitlab
- 分支
- master
- release,发布版本
- dev , 开发版本
- 张扬
- 张阳
- 张杨
- 合并(小的功能2左右)
- 代码review , 组长.
- git 命令 , 笔试题.
- git add .
- git commit -m \’xx\’
- git push origin master
- git pull origin master
- git stash
- git branch
- git reset …
- git merge
- git rebase
- 你想要给开源的项目贡献代码:
- fork
- 在自己仓库进行修改
- pull request 提交给作者
- 先进行pull再进行push提交.
- 敏捷开发(看板) 任务管理工具
- 禅道
- tower
- 蒲公英
- 软件:compare
- 其他:
程序员入职之后会有几个账号: 钉钉 / 邮箱(周报/日报) / git 账号 / 禅道 / VPN .
- 运维项目(*)
- 爬虫
- 用什么做的?
- requests
- selenuim
- scrapy
- 分布式爬虫
- 爬虫面试:
- 案例
- 滑动验证码
- 数据量级 一天爬多少数据
- 神箭手 第三方爬虫
- 数据结构 + 消息队列
- 给问题让你解决
- 案例
- 用什么做的?
-
-
函數有什麽坑?
def func(a,b=[]): pass
-
装饰器的应用场景?
- flask路由系统.
- filter
- inclustion_tag
- simple_tag
- 用户认证(不推荐)
- csrf_token
-
手写装饰器:不带参数和带参数
-
不带
def wrapper(func): @funtools.wrap(func) def inner(*args,**kwargs): return func(*args,**kwargs) return inner
-
带参数
# 写装饰器实现让被装饰的函数执行N次 def x(count): def wrapper(func): @funtools.wrap(func) def inner(*args,**kwargs): for i in range(count): data = func(*args,**kwargs) return data return inner return wrapper @x(5) def func(): pass
-
-
面向对象中的双下滑方法.
-
单例模式
# 错误示例 class Person: _obj = None def __new__(cls): if cls._obj is None: cls._obj = super().__new__(cls) return cls._obj
import threading class Singleton(object): _instance = None _lock = threading.RLock() def __new__(cls, *args, **kwargs): if cls._instance: return cls._instance with cls._lock: if not cls._instance: cls._instance = super().__new__(cls, *args, **kwargs) return cls._instance
class Foo(object): def __setitem__(self, key, value): pass def __getitem__(self, item): pass def __delitem__(self, key): pass obj = Foo() obj[\'k1\'] = \'alex\' obj[\'k1\'] del obj[\'k1\']
class Foo(object): def __enter__(self): print(\'进入\') return 123 def __exit__(self, exc_type, exc_val, exc_tb): print(\'退出\') obj = Foo() with obj as f: print(f)
class Foo(object): def __call__(self, *args, **kwargs): pass Foo()() # flask源码入口
-
手写栈
class Stack(object): def __init__(self): self.data = [] def push(self,value): self.data.append(value) def pop(self): return self.data.pop() obj = Stack() obj.push(\'alex\') obj.push(\'eric\') val = obj.pop() print(val)
-
你如何理解面型对象的三大特性?
-
封装
-
继承,哪里用过继承.( drf的视图 )
-
多态(什么是鸭子模型)
class Foo(object): def xxxxx(self): pass class Base(object): def xxxxx(self): pass def func(arg): arg.xxxxx() obj1 = Foo() obj2 = Base() func(obj1) func(obj2)
-
-
-
什么是反射?
通过字符串形式去一个对象找到指定的属性. -
反射应用场景:
-
crm, 公户和私户的处理(下拉框action)
-
cbv
def dispatch(self, request, *args, **kwargs): # Try to dispatch to the right method; if a method doesn\'t exist, # defer to the error handler. Also defer to the error handler if the # request method isn\'t on the approved list. if request.method.lower() in self.http_method_names: handler = getattr(self, request.method.lower(), self.http_method_not_allowed) else: handler = self.http_method_not_allowed return handler(request, *args, **kwargs)
-
django配置文件(中间件)
-
restful api
-
-
TCP三次握手和四次挥手
-
osi 模型
-
c/s 和 b/s
-
简述http和 https协议.
-
http协议:
-
连接状态:一次请求一次响应然后断开连接.
-
数据传输格式:
client = socket.socket() client.connect((...)) client.sendall(b\'GET /s?wd=alex HTTP1/1\r\n.....\r\n\r\n\') client.sendall(b\'POST /s?wd=alex HTTP1/1\r\n.....\r\n\r\nname=alex&age=19\')
-
常见问题:
- 状态码
- 常见请求头
- 常见请求方式
-
-
https: ca证书 + SSL
-
websocket: 双工 / 魔法字符串 magic string
-
-
进程线程协程的区别?
-
IO多路复用:select / poll / epoll 的区别.
-
GIL锁
-
-
第一章 知识点串讲
1.1 Python基础
-
解释型语言和编译型语言的区别?
-
你除了python以外还会哪些编程语言?
-
你为什么选择python?
- 语法简洁 - 从诞生之初,类库丰富,不用重复造轮子. - 大势所趋: - 底层算法/api - 应用开发 购买现成的解决方案.
-
列举你常用数据类型及其中的方法.
-
深浅拷贝 ?
# 针对可变类型: list,dict,set # 浅拷贝:拷贝第一层 # 深拷贝:所有层的可变类型都会被拷贝.
-
is 和 == 的区别?
is是内存 ==值
-
看代码写结果
v = 1 or 2 v = 0 or 6 v = 1 and 2 v = 0 and 2
-
给你一个大文件,如何查看所有内容?
# for 文件对象 # tell 和 seek
-
列举常用的内置函数?
len range open help type id bin/hex/oct/int filter/map/zip enumrate divmod
-
filter/map/reduce 的作用?
-
比较两个值
v = (1) v = (1,)
-
列表推导式
v = [i for i in range(10)] v = [lambda:i for i in range(10)] print(v[0]()) print(v[9]()) def func(): return [lambda:i for i in range(5)] v = [m() for m in func()] # [4,4,4,4,4]
-
(i for i in range(10)) 和 [i for i in range(10)] 的区别?
-
def func(a,b=[]):pass 有什么陷阱?
-
看代码
def func(a,b=[]): b.append(a) return b l1 = func(1) l2 = func(2,[11,22]) l3 = func(9) print(l1,l2,l3) # [1,9] [11,22,2] [1,9]
-
装饰器: 不带参数 和 带参数(手写)
-
IP地址转换
-
常用内置模块?
os/json/time/re/datetime/sys
-
你了解的第三方模块
-
re中match和search的区别?
-
正则中什么是贪婪匹配?
-
如果获取一个目录中的所有文件?
import os # os.listdir,只能获取一级目录. # for path in os.listdir(\'src\'): # print(path) # os.walk,获取目录中所有文件. for path,folder,files in os.walk(\'src\'): for file in files: file_path = os.path.join(path,file) print(file_path)
-
列举你了解的双下划线方法?
-
__call__
方法的作用? -
__new__
方法的作用? -
手写栈
-
单例模式(加锁)
-
面向对象中的上下文管理指的是什么?
class Foo: pass with Foo() as f: pass
-
都在哪里用过继承? drf时都继承哪些类?
-
写输出
class Parent(object): x = 1 class Child1(Parent): pass class Child2(Parent): pass print(Parent.x, Child1.x, Child2.x) # 1 1 1 Child2.x = 2 print(Parent.x, Child1.x, Child2.x) # 1 1 2 Parent.x = 3 print(Parent.x, Child1.x, Child2.x) # 3 3 2
-
@classmethod和@staticmethod有什么区别?
类方法: 类直接调用; 至少有一个cls参数. 静态方法:类直接调用;可以有任意个参数.
-
Python垃圾回收机制?
1.2 网络并发编程
-
cs和bs架构?
-
osi 7层模型/5层/4层
-
TCP三次握手四次挥手
-
什么是粘包?
-
http协议
-
常见http请求头/常见请求方式/常见状态码
-
https协议(非常重要)
-
websocket协议
- 意义: 实现服务端向客户端主动推送消息(双工通信)
- 实现原理:
- 握手: 随机字符串+magic string (必须)
- 数据加密: 127/126/125
-
进程/线程/协程的区别?
-
什么是GIL锁?
一个进程中同一时刻只有一个线程被cpu调度. # 无法保证数据安全
-
IO多路复用,select/poll/epoll区别?
- 作用: 监听多个socket是否发生变化(新连接/新数据到来).
- 区别:
- select, 最多监听1024个; 轮训 (水平触发).
- poll, 最多监听无数个; 轮训 (水平触发). .
- epoll, 最多监听无数个; 回调.(边缘触发)
-
进程之间如何实现数据共享?
queue manager pipe 第三方: redis/rabbitMQ/socket
1.3 MySQL
-
数据的引擎以及区别?
- innodb
- 支持事务
- 支持行锁/表锁
- 慢
- myisam
- 不支持事务
- 表锁
- 快
- innodb
-
char和varchar的区别?
-
char(50) 中的50是什么意思?
-
left jon 和inner join的区别?
部门表 departid title 1 运营 2 销售 3 技术 用户表 user
id name depart_id 1 铁帅 1 2 耀中 1 3 张阳 2 select * from user left join depart on user.depart_id = depart.id # 3条数据 select * from depart left join user on user.depart_id = depart.id # 4条数据 select * from depart inner join user on user.depart_id = depart.id # 3条数据
-
联合索引: (a,b,c) [最左前缀]
- a,b
- b,c 无法命中
- a,c
- a,b,c
-
函数和like都是无法命中索引.
select * from user where name like \'%ex\' select * from user where 函数(name) like \'%ex\'
-
存储过程/触发器/视图
-
数据库优化方案
- 建索引 + 命中索引
- 固定长度在前面
- 特定数据放内存,不要创建表来进行存储(避免连表操作)
- 允许数据冗余,不建额外表(少了连表操作).
- 读写分离
- redis做缓存
- 分库分表
-
数据库设计 ( 重要 )
- fk
- m2m
-
SQL语句 (最重要)
1.4 前端
-
什么是响应式布局?
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>Title</title> <link href="https://cdn.bootcss.com/twitter-bootstrap/4.3.1/css/bootstrap.css" rel="stylesheet"> <style> .bg{ background-color: red; } @media (min-width: 768px) { .bg{ background-color: green; } } </style> </head> <body> <!--<div class="row">--> <!--<div class="col-md-6">坐标</div>--> <!--<div class="col-md-6">右边</div>--> <!--</div>--> <div class="bg">asdf</div> </body> </html>
-
js作用域
<script> var name = \'oldboy\'; function f1(){ console.log(name); } f1() </script>
<script> var name = \'oldboy\'; function f1(){ console.log(this.name); // window } window.f1() </script>
<script> function f1(){ console.log(213); } f1() (function(arg){ console.log(arg); console.log(this) })(123) </script>
info = { user:\'alex\', func:function(){ console.log(this); //info } } info.func()
name = \'alex\' info = { name:\'eric\', func:function(){ console.log(this.name); // eric function f1(){ console.log(this.name); // alex } f1() } } info.func()
name = \'alex\' info = { name:\'eric\', func:function(){ console.log(this.name); // eric var that = this; function f1(){ console.log(that.name); // eric } f1() } } info.func()
-
跨域
- jsonp (面试)
- cors
-
bootstrap常用的样式.
1.5 django框架
- django和flask的区别?
- django 路由中的别名 / include 路由分发
- FBV和CBV
- request对象中都用过哪些方法?响应时都返回过哪些对象?
- ORM ( 练习题 ) 重点中的重点 , 请补充.
- django中如何执行原生SQL ?
- raw
- extra
- connections (最原生)
- django如何实现数据库读写分离?
- 模板拔高:
- filter
- simple_tag
- inlusion_tag
- 中间件
- 执行流程
- 应用场景: 权限 / 用户认证 / 白名单 / csrf
- Form和ModelForm
- django的缓存如何实现?
- django中信号的作用?
1.6 爬虫 & 数据分析
1.7 Linux架构
- redis有哪些数据类型?
- redis中中RDB和AOF的区别?
- redis中如何实现读写分离?
- redis中的有多少哈西槽?
- redis分布式锁是什么?
- rabbitMQ和kafka的区别?
- 什么时rpc?
- git如何做协同开发?
- git常见命令?
- 如何做代码review?
- git 如何给开源项目贡献代码?
1.8 项目:CRM
1.9 项目:路飞学城
1.10 项目:智能玩具 & Flask
1.11 项目:代码发布
第二章 简历示例
2.1 个人技能
- 熟悉 Python、了解Golang
- 熟悉 Django、Flask、Tornado等Web框架
- 熟练 HTML、CSS、JavaScript、jQuery等
- 熟练 VUE、Ajax、JSONP、CORS、BootStrap、跨域等前端技术
- 熟悉MySQL、存储过程、触发器器、索引
- 熟悉 Redis、主从、分布式cluster
- 熟悉 celery、RabbitMQ 消息队列的使用
- 熟悉 Python⽹网络编程、IO多路路复⽤用
- 熟悉 多线程、多进程、协程、异步非阻塞等
- 熟悉 Scrapy框架和分布式爬⾍虫框架redis-scrapy组件
- 熟悉 爬⾍虫相关Requests和BeautifulSoup模块使⽤用
- 熟悉 常⽤用算法如冒泡、快排、堆排、希尔等;
- 熟悉 Git
- 熟悉 WebSocket
- 熟悉 Linux、ansible、saltsack、docker
2.2 项目经验
2.2.1 CRM
-
其他名称:SPATA系统/SELL系统(推荐)
-
项目介绍
随着公司日益发展以及市场和销售人员日益扩展,完成销售流程的规范化以及标准化并在SELL系统对员工进行行监管,项目主要用于为公司销售⼈员、运营、售后等⼈员提供公共的处理平台,在公司发展的过程中以便便实现信息的管理, 实现公司的信息化流程。为销售人员工提供客户关系的管理,对于新客户信息的录入和等级。定期对客户进行回访和跟进,从而增加用户粘性,便便于之后的转化。运营和渠道通过关系以及人脉获取有效客户,可以进⾏行录⼊和分配。 -
项目功能
SELL主要⽤用于为销售、渠道人员以及管理理者实现⼀个规范化的平台,为了防止销售之间存在的”恶意”或”非恶意”竞争,避免有人进⾏抢单导致部门不和谐因素实⾏公户和私户管理理,公户主要存放未指定销售的客户信息,公户可有两种⽅式进⾏分配到私户,第⼀种是销售⾃己申请,第⼆种是主管进⾏行行主动分配.
私户主要存放⾃己的客户,在申请客户时基于数据库事务/锁保证数据安全,从⽽安全将客户申请到⾃己的账户.批量量操作时候action… / 模糊搜索等操作。
项⽬中继承了⼀个独立的权限组件,权限组件主要⽤于为让各种⻆色的客户仅能访问⾃己拥有的功能,⽆无权越级访问,权限基本使用流程涵盖了了一下知识点,如:⽤户认证,将权限和菜单信息放⼊session/用户访问,在中间件中进行权限校验(⽩名单)/动态菜单,使⽤用inclusion_tag定制菜单的显示.
-
项目相关问题
- CRM系统是什么?里面都有哪些功能(业务)?
- 什么是公户?什么是私户?为什么要做这个区分?
- 请列举出CRM系统中的表。
- 对数据库的数据做展示时,不同字段类型有不同的展示方法,分别是什么?
- 请详细说说你们公司销售是如何使用CRM的。
- 详细说说班主任是如何使用CRM的。
- CRM中有哪些技术点,用于做什么(至少写出5个)?
- 为什么不用现成的crm而是自己去开发?
- 权限有多少张表?每张表中有哪些字段?(5分)
- 请简述实现权限控制的流程。(10分)
- 初始化权限时,定义了两个字典,分别是什么数据结构?为什么要把他们存在session中?
- 权限校验的中间中都做了什么事情?
- 如何实现二级菜单默认展开并且是选中状态的?
- 权限控制到按钮级别是如何实现的?
- 权限批量操作时,哪些权限是需要新增的?哪些是需要删除的?哪些是可更新的?
- 开发过程中遇到问题,一般都是怎么解决的?请说一下你印象比较深刻的一个问题。
- 请简述下管理权限信息的流程(管理、分配权限是如何操作的)?
- rbac组件中有哪些技术点,用于做什么(至少写出5个)?
2.2.2 路飞学城
-
其他名称:智慧树、猿辅导等
-
项目介绍
路⻜学城是⼀个基于Python和Django开发的平台,平台的⽬标致力于提升在线学习的完课率,目前在线教育领域都是在线看视频的方式,路飞学城从开创最新“一对⼀”模式辅导,实现导师每天跟进并定期考核制度,除次之外执行学、练、改、管、测五位⼀体的教学⽅法以及奖惩措施,以此促进完成学成率。 -
项目功能
路飞学城共包含三⼤大部分,即:导师平台、管理理平台、在线平台(APP),导师后台主要对导师进⾏行行跟进和考核监管,对导师采⽤用扣“奖金”措施来督促导师跟进率。管理后台主要⽤用于运操作管理,可以对于深科技和咨询信息的录⼊和编辑,除此之外还可以对课程上传管理以及学⽣休学和提现管理。在线平台部分主要为vue和app提供接口功能,接口基于django rest framewok框架的基础搭建,利用其内置组件和⾃定义扩展实现⽤户认证和访问频率限制,根据依赖django-redis组件实现对缓存的操作,将⽤户访问记录放⼊入redis实现认证操作。
在线业务主线主要将课程分为“学位课”和“专题课”,基于django contenttype组件实现课程多价格策略,为了减轻数据库压力将临时购买信息放⼊redis以便便操作,购物流程包含 ⻉里、优惠券、⽀付宝联合支付。在线通知使⽤用阿⾥短信接⼝和“微信服务号”模板消息对购买、提交作业、咨询等信息的提醒。最后整合第三⽅美洽、CC视频、保利威视在线咨询以及在线视频播放的功能。
-
项目相关问题:
- 简述rest ful 规范.
- drf提供了哪些组件?
- drf时都继承过哪些视图类.
- jwt的原理?
- 路飞学城有跨域吗?如何解决的?
- 购物车用redis做的时候,其结构长什么样子?
- 支付宝用的什么加密:?
- 视频是如何实现加密的?
- 支付寶支付完成时,服务器宕机怎么办 ?
- 如果避免点击按钮生成重复订单 ?
- 公司的组织架构?
- 如何做的协同开发?
2.2.3 智能玩具
-
介绍
关爱留守儿童, 让玩具成为父母间沟通的媒介, 建立沟通的桥梁,让玩具成为孩子的玩伴,实现无屏社交,依靠孩子的语音指令做出响应,例如我要和爸爸聊天,玩具会提示可以和爸爸聊天了并打开与app通讯的链接,我要听世上只有妈妈好,玩具就会依照指令播放相应的内容 -
功能
- 基于Websocket实现语音IM通讯
- 基于MUI实现app移动端应用布局
- 基于HTML5PLUS实现移动操作系统的硬件驱动调用及系统调用
- 基于MongoDB实现数据存储
- 基于Redis实现离线消息存储
- 基于BaiduAI开放技术实现语音合成和语音识别
- 基于gensim LSIModel 语言模型实现词语训练
- 基于gensim 稀疏矩阵相似度实现文本相似度匹配
- 基于jieba 实现语音指令分词
- 基于pypinyin 实现中文同音字识别
-
相关问题
-
说说你智能玩具的项目?
目的:关爱留守儿童, 让玩具成为父母间沟通的媒介, 建立沟通的桥梁,让玩具成为孩子的玩伴,实现无屏社交,依靠孩子的语音指令做出响应,例如我要和爸爸聊天,玩具会提示可以和爸爸聊天了并打开与app通讯的链接,我要听世上只有妈妈好,玩具就会依照指令播放相应的内容。 -
说说智能玩具有什么功能?
玩具可以语音点播朗诵诗歌,播放音乐,做游戏-成语接龙,与智能机器人聊天与手机app 的im通讯 ,手机app可以为玩具点播歌曲,玩具与玩具之间的通讯。 -
智能部分使用了什么算法:
两种回答:- 使用百度ai中的语音合成和语音识别,点播功能是使用Gensim库进行训练的,聊天做游戏是用的图灵机器人+百度语音合成
- 使用百度ai中的语音合成和语音识别 NLP自然语言处理 点播功能基于百度NLP,聊天做游戏是用的图灵机器人+百度语音合成
-
语音IM通讯是怎么实现的:
通过http传输音频文件,将音频文件保存在服务器中,并将聊天信息存储在服务器中,再通过Websocket进行实时通讯,收到消息之后第一时间去服务器中查询聊天信息 -
手机app是怎么做的(使用什么方式)?
使用MUI 前端布局,使用HTML5PLUS 完成系统硬件驱动调用 (摄像头,麦克风等) 。 -
谈谈你对人工智能的理解(说出人工智能技术的关键字至少5个):
语音类 : 语音识别 语音合成
图像类 : 图像识别 文字识别 人脸识别 视频审核
语言类 : 自然语言处理 机器翻译 词法分析 依存句法分析 文本纠错 对话情绪识别 词向量表示 短文本相似度
词义相似度 情感倾向分析 -
mongodb相关:
1.修改器: $push $set $pull $inc $pop 2.说说你对 $ 的理解 : $ 我的理解就是代指符号,代指所查询到的数据或索引位置 3.Mongodb中的数据类型 : ObjectID String Boolean Integer Double Arrays Object(Dict) Null Timestamp Date 4.mongodb的比较符 : $lt $gt $lte $gte ":"
-
公司组织架构:
1.综合人力财务行政:1个小姐姐
2.营销部:**
3.产品部:** + UI小姐姐
4.软件部:** + 前端小姐姐 + 你
5.硬件部:** -
项目不做底层,只使用三方的原因:
制作底层大量占用人力,公司资金不足以支撑底层研发,将大量成本投入到硬件研发中。 -
百度AI是网络请求,那如果出现延迟,怎么处理:
百度响应默认超时2秒,返回给用户语音识别失败 -
关于用户体验问题:
非极端情况下,用户会在3秒内得到响应的结果
-