提交 2e18a40c 编写于 作者: J jackfrued

更新了部分文档和代码

上级 5bf23a29
<!--
HTML - 超文本标记语言 - 可以在浏览器中运行出网页的编程语言
1. 标签 - 承载网页上显示的内容
2. 层叠样式表 - 负责网页的显示
3. JavaScript - 负责交互行为
-->
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8">
<title>垃圾分类查询助手</title>
<!--
0. 可回收物(如:玻璃类、牛奶盒、金属类、塑料类、废纸类、织物类)
1. 有害垃圾(如:废电池、废墨盒、废油漆桶、过期药品、废灯管、杀虫剂)
2. 厨余垃圾(如:骨骼内脏、菜梗菜叶、果皮、茶叶渣、残枝落叶、剩菜剩饭)
3. 其他垃圾(如:宠物粪便、烟头、污染纸张、破旧陶瓷品、灰土、一次性餐具)
-->
<!-- 层叠样式表 -->
<style>
.search, .result {
width: 720px;
margin: 50px auto;
}
.search > input {
width: 520px;
border: none;
outline: none;
text-align: center;
font-size: 36px;
line-height: 36px;
border-bottom: 1px solid gray;
margin: 0 20px;
}
.search button {
background-color: red;
color: white;
font-size: 28px;
border: none;
outline: none;
width: 120px;
}
.result > p, .result > div {
width: 640px;
margin: 0 auto;
}
.result > p, .result span {
text-align: left;
font-size: 28px;
}
.result img {
vertical-align: middle;
}
.explain {
font-size: 12px;
color: darkgray;
}
.result .pre {
font-size: 16px;
}
</style>
</head>
<body>
<!-- div 是代表一个逻辑区域的块标签 -->
<div id="app">
<div class="search">
<!-- type属性是text的input标签代表文本框 可以接收用户输入 -->
<!-- placeholder是文本框的输入提示 -->
<input type="text" placeholder="请输入垃圾名字" v-model="word" @keydown.enter="search()">
<!-- button代表按钮 点击可以开始查询 -->
<button @click="search()">查询</button>
</div>
<div class="result">
<!-- p代表一个段落 -->
<p v-if="searched && !results">没有对应的查询结果</p>
<div v-for="result in results">
<p>
<!-- img是图像标签 可以用来实现图片-->
<img :src="pictures[result.type]" width="56" :alt="types[result.type]">
&nbsp;&nbsp;
<!-- span是跨度标签 代表一个逻辑区域(不分段)-->
<span>{{ result.name }}</span>
&nbsp;&nbsp;
<span class="pre" v-if="result.aipre == 1">(预测结果)</span>
</p>
<p class="explain">说明:{{ result.explain }}</p>
</div>
</div>
</div>
<!-- JavaScript代码 可以负责在用户点击查询按钮时联网获取垃圾分类结果 -->
<script src="https://cdn.bootcss.com/vue/2.6.10/vue.min.js"></script>
<script>
new Vue({
el: '#app',
data: {
word: '',
searched: false,
types: ['可回收物', '有害垃圾', '厨余垃圾', '其他垃圾'],
pictures: ['recyclable.png', 'harmful-waste.png', 'kitchen-waste.png', 'other-waste.png'],
results: []
},
methods: {
// 查询垃圾分类的函数
search() {
if (this.word.trim().length > 0) {
let key = '9aeb28ee8858a167c1755f856f830e22'
let url = `http://api.tianapi.com/txapi/lajifenlei/?key=${key}&word=${this.word}`
fetch(url)
.then(resp => resp.json())
.then(json => {
// 处理返回的JSON格式数据
this.searched = true
this.results = json.newslist
})
}
}
}
})
</script>
</body>
</html>
\ No newline at end of file
## Docker在项目中的应用
### Docker简介
软件开发中最为麻烦的事情可能就是配置环境了。由于用户使用的操作系统具有多样性,即便使用跨平台的开发语言(如Java和Python)都不能保证代码能够在各种平台下都可以正常的运转,而且在不同的环境下我们安装的软件需要依赖的软件包也是不一样的。
那么问题来了,我们安装软件的时候可不可以把软件运行的环境一并安装?我们是不是可以把原始环境一模一样地复制过来呢?
虚拟机(virtual machine)就是带环境安装的一种解决方案,它可以在一种操作系统里面运行另一种操作系统,比如在Windows系统里面运行Linux系统,在macOS上运行Windows,而应用程序对此毫无感知。使用过虚拟机的人都知道,虚拟机用起来跟真实系统一模一样,而对于虚拟机的宿主系统来说,虚拟机就是一个普通文件,不需要了就删掉,对宿主系统或者其他的程序并没有影响。但是虚拟机通常会占用较多的系统资源,启动和关闭也非常的缓慢,总之用户体验并没有想象中的那么好。
Docker属于对Linux容器技术的一种封装(利用了Linux的namespace和cgroup技术),它提供了简单易用的容器使用接口,是目前最流行的 Linux 容器解决方案。Docker将应用程序与该程序的依赖打包在一个文件里面,运行这个文件,就会生成一个虚拟容器。程序在这个虚拟容器里运行,就好像在真实的物理机上运行一样。
![](./res/docker_vs_vm.png)
目前,Docker主要用于几下几个方面:
1. 提供一次性的环境。
2. 提供弹性的云服务(利用Docker很容易实现扩容和收缩)。
3. 实践微服务架构(隔离真实环境在容器中运行多个服务)。
### 安装Docker
下面的讲解以CentOS为例,使用[Ubuntu](https://docs.docker.com/install/linux/docker-ce/ubuntu/)[macOS](https://docs.docker.com/docker-for-mac/install/)[Windows](https://docs.docker.com/docker-for-windows/install/)的用户可以通过点击链接了解这些平台下如何安装和使用Docker。
0. 确定操作系统内核版本(CentOS 7要求64位,内核版本3.10+;CentOS 6要求64位,内核版本2.6+)。
```Shell
uname -r
```
1. 在CentOS下使用yum安装Docker并启动。
```Shell
yum -y install docker
systemctl start docker
```
2. 检视Docker的信息和版本。
```Shell
docker version
docker info
```
3. 下载镜像文件。
```Shell
docker pull <name>
```
例如:`docker pull hello-world`
4. 运行镜像文件。
```Shell
docker run <image-id>
```
例如:`docker run hello-world`
5. 查看镜像文件。
```Shell
docker image ls
docker images
```
6. 删除镜像文件。
```Shell
docker rmi <name>
```
例如:`docker rmi fce289e99eb9`
7. 查看正在运行容器。
```Shell
docker ps
```
8. 停止运行的容器。
```Shell
docker stop <container-id>
docker stop <name>
```
例如:`docker stop hello-world`
对于那些不会自动终止的容器,就可以用下面的方式来停止。
```Shell
docker container kill <container-id>
```
如果要在Ubuntu(内核版本3.10+)下面安装和启动Docker,可以按照如下的步骤进行。
```Shell
apt update
apt install docker-ce
service docker start
```
如果需要,可以更换Ubuntu软件下载源来提升下载速度,具体请参照清华大学开源软件镜像站上的[《Ubuntu镜像使用帮助》](<https://mirrors.tuna.tsinghua.edu.cn/help/ubuntu/>)
安装Docker后,由于直接访问dockerhub下载镜像会非常缓慢,建议更换国内镜像,可以通过修改 `/etc/docker/daemon.js` 文件来做到。云服务器(如:阿里云)通常已经设置了默认的镜像服务器,并不需要手动进行指定。
```JavaScript
{
"registry-mirrors": [
"http://hub-mirror.c.163.com",
"https://registry.docker-cn.com"
]
}
```
### 使用Docker
#### 安装Nginx
下面我们就基于Docker来创建一台HTTP服务器,我们选择用Nginx来搭建该服务,因为Nginx是高性能的Web服务器,同时也是做反向代理服务器的上佳选择。要做到这件事情,只需要使用下面的命令在Docker中创建一个容器即可。
```Shell
docker container run -d -p 80:80 --rm --name mynginx nginx
```
> 说明:上面的参数`-d`表示容器在后台运行(不产生输出到Shell)并显示容器的ID;`-p`是用来映射容器的端口到宿主机的端口;`--rm`表示容器停止后自动删除容器,例如通过`docker container stop mynginx`以后,容器就没有了;`—name`后面的mynginx就是自定义容器的名字。在创建容器的过程中,需要用到nginx的镜像文件,镜像文件的下载是自动完成的,如果没有指定版本号,默认是最新版本(latest)。
如果需要将自己的Web项目(页面)部署到Nginx上,可以使用容器拷贝命令将指定路径下所有的文件和文件夹拷贝到容器的指定目录中。
```Shell
docker container cp /root/web/index.html mynginx:/usr/share/nginx/html
```
如果不愿意拷贝文件也可以在创建容器时通过数据卷操作`--volume`将指定的文件夹映射到容器的某个目录中,例如将Web项目的文件夹直接映射到`/usr/share/nginx/html`目录。
```Shell
docker container run -d -p 80:80 --rm --name mynginx --volume $PWD/html:/usr/share/nginx/html nginx
```
> 说明:上面创建容器和拷贝文件的命令中,`container`是可以省略的,也就是说`docker container run`和`docker run`是一样的,而`docker container cp`和`docker cp`是一样的。此外,命令中的`--volume`也可以缩写为`-v`,就如同`-d`是`--detach`的缩写,`-p`是`--publish`的缩写。`$PWD`代表宿主系统当前文件夹,这些对于用过Linux系统的人来说相信很容易理解。
要查看运行中的容器,可以使用下面的命令。
```Shell
docker ps
```
要让刚才创建的容器停下来,可以使用下面的命令。
```Shell
docker stop mynginx
```
由于在创建容器时使用了`--rm`选项,容器在停止时会被移除,当我们使用下面的命令查看所有容器时,应该已经看不到刚才的`mynginx`容器了。
```Shell
docker container ls -a
```
如果在创建容器时没有指定`--rm`选项,那么也可以使用下面的命令来删除容器。
```Shell
docker rm mynginx
```
#### 安装MySQL
我们可以先检查一下服务器上有没有MySQL的镜像文件。
```Shell
docker search mysql
```
下载MySQL镜像并指定镜像的版本号。
```Shell
docker pull mysql:5.7
```
如果需要查看已经下载的镜像文件,可以使用下面的命令。
```Shell
docker images
```
创建并运行MySQL容器。
```Shell
docker run -d -p 3306:3306 --name mysql57 -v $PWD/mysql/conf:/etc/mysql/mysql.cnf.d -v $PWD/mysql/data:/var/lib/mysql -e MYSQL_ROOT_PASSWORD=123456 mysql:5.7
```
注意,上面创建容器时我们又一次使用了数据卷操作,那是因为通常容器是随时创建随时删除的,而数据库中的数据却是需要保留下来的,所以上面的两个数据卷操作一个是映射了MySQL配置文件所在的文件夹,一个是映射了MySQL数据所在的文件夹,这里的数据卷操作非常重要。我们可以将MySQL的配置文件放在`$PWD/mysql/conf`目录下,配置文件的具体内容如下所示:
```INI
[mysqld]
pid-file=/var/run/mysqld/mysqld.pid
socket=/var/run/mysqld/mysqld.sock
datadir=/var/lib/mysql
log-error=/var/log/mysql/error.log
server-id=1
log-bin=/var/log/mysql/mysql-bin.log
expire_logs_days=30
max_binlog_size=256M
symbolic-links=0
```
如果安装了MySQL 8.x版本(目前的最新版本),在使用客户端工具连接服务器时可能会遇到“error 2059: Authentication plugin 'caching_sha2_password' cannot be loaded”的问题,这是因为MySQL 8.x默认使用了名为“caching_sha2_password”的机制对用户口令进行了更好的保护,但是如果客户端工具不支持新的认证方式,连接就会失败。解决这个问题有两种方式:一是升级客户端工具来支持MySQL 8.x的认证方式;二是进入容器,修改MySQL的用户口令认证方式。下面是具体的步骤,我们先用`docker exec`命令进入容器的交互式环境,假设运行MySQL 8.x的容器名字叫`mysql8x`
```Shell
docker exec -it mysql8x /bin/bash
```
进入容器的交互式Shell之后,可以首先利用MySQL的客户端工具连接MySQL服务器。
```Shell
mysql -u root -p
Enter password:
Your MySQL connection id is 16
Server version: 8.0.12 MySQL Community Server - GPL
Copyright (c) 2000, 2018, Oracle and/or its affiliates. All rights reserved.
Oracle is a registered trademark of Oracle Corporation and/or its
affiliates. Other names may be trademarks of their respective
owners.
Type 'help;' or '\h' for help. Type '\c' to clear the current input statement.
mysql>
```
接下来通过SQL来修改用户口令就可以了。
```SQL
alter user 'root'@'%' identified with mysql_native_password by '123456' password expire never;
```
当然,如果愿意你也可以查看一下用户表检查是否修改成功。
```SQL
use mysql;
select user, host, plugin, authentication_string from user where user='root';
+------+-----------+-----------------------+-------------------------------------------+
| user | host | plugin | authentication_string |
+------+-----------+-----------------------+-------------------------------------------+
| root | % | mysql_native_password | *6BB4837EB74329105EE4568DDA7DC67ED2CA2AD9 |
| root | localhost | mysql_native_password | *6BB4837EB74329105EE4568DDA7DC67ED2CA2AD9 |
+------+-----------+-----------------------+-------------------------------------------+
2 rows in set (0.00 sec)
```
在完成上面的步骤后,现在即便不更新客户端工具也可以连接MySQL 8.x了。
此差异已折叠。
## 数据库设计和OOAD
## MySQL性能优化
### 存储引擎
### 使用索引
1. InnoDB
2. MyISAM
### 数据类型
### 索引
#### 索引的类型
在前面[《关系型数据库MySQL》](../Day36-40/36-38.关系型数据库MySQL.md)一文中,我们已经讲到过索引的相关知识,这里我们做一个简单的回顾。
1. B-Tree索引
2. HASH索引
3. R-Tree索引(空间索引)
4. Full-text索引(全文索引)
### 视图
查询的快照,可以将访问权限控制到列上。
```SQL
create view ... as select ...
drop view ...
```
### 使用过程
### 存储过程
过程,通常也称之为存储过程。
```SQL
create procedure ... (params)
......@@ -40,20 +26,12 @@ call ...
cursor.callproc('...')
```
### 触发器
不能用,因为多个行锁可能直接升级为表锁,导致性能低下。
### 数据分区
### 事务控制
### SQL注入攻击
### 数据分区
### SQL优化
#### 优化步骤
1. 通过`show status`了解各种SQL的执行频率。
```SQL
......@@ -82,20 +60,20 @@ cursor.callproc('...')
4. 通过`show profiles``show profile for query`分析SQL。
#### SQL优化
5. 优化CRUD操作。
1. 优化insert语句
2. 优化order by语句
3. 优化group by语句
4. 优化嵌套查询
5. 优化or条件
6. 优化分页查询
7. 使用SQL提示
- USE INDEX
- IGNORE INDEX
- FORCE INDEX
- 优化insert语句
- 优化order by语句
- 优化group by语句
- 优化嵌套查询
- 优化or条件
- 优化分页查询
- 使用SQL提示
- USE INDEX
- IGNORE INDEX
- FORCE INDEX
#### 配置优化
### 配置优化
1. 调整max_connections
2. 调整back_log
......@@ -103,7 +81,7 @@ cursor.callproc('...')
4. 调整thread_cache_size
5. 调整innodb_lock_wait_timeout
#### 架构优化
### 架构优化
1. 通过拆分提高表的访问效率
- 垂直拆分
......@@ -115,21 +93,6 @@ cursor.callproc('...')
- 3NF:所有的属性都直接依赖于主键(消除传递依赖)
- BCNF:消除非平凡多值依赖
3. 使用中间表提高统计查询速度
### 数据备份
#### 导入和导出
1. select ... into outfile ...
2. load data infile ... into table ...
3. mysqldump
4. mysqlimport
#### ibbackup工具
#### xtrabackup工具
### 主从复制
### 集群
4. 主从复制和读写分离
5. 配置MySQL集群
## 使用Django开发项目
## 使用Django开发商业项目
> 说明:本文的部分插图来自于《Python项目开发实战》和《精通Django》,这两本书中都包含了对Django框架精彩的讲解,有兴趣的读者可以自行购买阅读。
......
......@@ -2,7 +2,7 @@
> 作者:骆昊
>
> 最近有很多想学习Python的小伙伴陆陆续续加入我们的交流群,目前我们的交流群人数已经超过一万人,光靠我自己已经无法及时处理小伙伴们的入群申请,更无法及时为大家解答问题。目前我的想法是分技术方向建立讨论群并安排专门的人来管理这些群,群管理者应该具备专业的知识并有相对充裕的时间,可以解答小伙伴们提出的问题。当然,我会向这些管理者支付报酬,如果有兴趣成为管理者的可以跟我私聊。希望通过这种方式,我们能汇聚更多优秀的Python开发者,一方面打造沟通和交流的平台,另一方面让新入行的开发者获得问道的途径并藉此迅速成长。我会继续努力做好线上公开课以及线下技术交流活动,也希望各位小伙伴一如既往的支持我们。创作不易,感谢大家的打赏支持,这些钱不会用于购买咖啡而是捐赠给支教组织([点击](./更新日志.md)了解捐赠情况)。感谢**北京千锋互联科技有限公司Python教学部**对[公开课](https://ke.qq.com/course/406954)提供的支持。
> 最近有很多想学习Python的小伙伴陆陆续续加入我们的交流群,目前我们的交流群人数已经超过一万人,光靠我自己已经无法及时处理小伙伴们的入群申请,更无法及时为大家解答问题。目前我的想法是分技术方向建立讨论群并安排专门的人来管理这些群,群管理者应该具备专业的知识并有相对充裕的时间,可以解答小伙伴们提出的问题。当然,我会向这些管理者支付报酬,如果有兴趣成为管理者的可以跟我私聊。但愿通过这种方式,我们的群能汇聚更多优秀的Python开发者,一方面打造一个优质的沟通和交流的平台,另一方面让新入行的开发者获得问道的途径并藉此迅速成长。我会继续努力做好线上公开课以及线下技术交流活动,也希望各位小伙伴一如既往的支持我们。创作不易,感谢大家的打赏支持,这些钱不会用于购买咖啡而是捐赠给支教组织([点击](./更新日志.md)了解捐赠情况)。感谢北京千锋互联科技有限公司对[公开课](https://ke.qq.com/course/406954)提供的支持。
![](./res/python_qq_group.png)
......@@ -546,38 +546,37 @@
| | 查看评论 | 白元芳 | 正在进行 | 20% | 4 | 2018/8/7 | | 2018/8/7 | | 需要进行代码审查 |
| | 评论投票 | 白元芳 | 等待 | 0% | 4 | 2018/8/8 | | 2018/8/8 | | |
#### 第92天:[Docker的使用](./Day91-100/92.Docker在项目中的应用.md)
4. OOAD和数据库设计
#### 第93天:[数据库设计和OOAD](./Day91-100/93.数据库设计和OOAD.md)
- UML(统一建模语言)的类图
##### 概念模型和正向工程
![uml](./res/uml-class-diagram.png)
1. UML(统一建模语言)的类图
- 通过模型创建表(正向工程)
![uml](./res/uml-class-diagram.png)
```Shell
python manage.py makemigrations app
python manage.py migrate
```
2. 通过模型创建表(正向工程)
- 使用PowerDesigner绘制物理模型图。
```Shell
python manage.py makemigrations app
python manage.py migrate
```
![](./res/power-designer-pdm.png)
##### 物理模型和反向工程
- 通过数据表创建模型(反向工程)
1. PowerDesigner
```Shell
python manage.py inspectdb > app/models.py
```
![](./res/power-designer-pdm.png)
2. 通过数据表创建模型(反向工程)
#### 第92天:[Docker的使用](./Day91-100/92.Docker在项目中的应用.md)
```Shell
python manage.py inspectdb > app/models.py
```
#### 第93天:[MySQL性能优化](./Day91-100/93.MySQL性能优化.md)
#### 第94天:[网络API接口设计](./Day91-100/94.网络API接口设计.md)
#### 第95天:[使用Django开发项目](./Day91-100/95.使用Django开发项目.md)
#### 第95天:[使用Django开发商业项目](./Day91-100/95.使用Django开发商业项 目.md)
##### 项目开发中的公共问题
......@@ -625,7 +624,7 @@
- uWSGI支持异构部署。
- 由于Nginx本身支持uWSGI,在线上一般都将Nginx和uWSGI捆绑在一起部署,而且uWSGI属于功能齐全且高度定制的WSGI中间件。
- 在性能上,Gunicorn和uWSGI其实表现相当。
5. 虚拟化技术(Docker)
5. 使用虚拟化技术(Docker)部署测试环境和生产环境
##### 性能测试
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册