Jelajahi Sumber

更新了前15天和最后10天的内容

jackfrued 5 tahun lalu
induk
melakukan
dbe54797b0

+ 17 - 24
Day01-15/01.初识Python.md

@@ -10,33 +10,31 @@
 4. 2000年10月16日:Python 2.0发布,增加了完整的[垃圾回收](https://zh.wikipedia.org/wiki/%E5%9E%83%E5%9C%BE%E5%9B%9E%E6%94%B6_(%E8%A8%88%E7%AE%97%E6%A9%9F%E7%A7%91%E5%AD%B8)),提供了对[Unicode](https://zh.wikipedia.org/wiki/Unicode)的支持。与此同时,Python的整个开发过程更加透明,社区对开发进度的影响逐渐扩大,生态圈开始慢慢形成。
 5. 2008年12月3日:Python 3.0发布,它并不完全兼容之前的Python代码,不过因为目前还有不少公司在项目和运维中使用Python 2.x版本,所以Python 3.x的很多新特性后来也被移植到Python 2.6/2.7版本中。
 
-目前我们使用的Python 3.7.x的版本是在2018年发布的,Python的版本号分为三段,形如A.B.C。其中A表示大版本号,一般当整体重写,或出现不向后兼容的改变时,增加A;B表示功能更新,出现新功能时增加B;C表示小的改动(例如:修复了某个Bug),只要有修改就增加C。如果对Python的历史感兴趣,可以阅读名为[《Python简史》](http://www.cnblogs.com/vamei/archive/2013/02/06/2892628.html)的博文
+目前我们使用的Python 3.7.x的版本是在2018年发布的,Python的版本号分为三段,形如A.B.C。其中A表示大版本号,一般当整体重写,或出现不向后兼容的改变时,增加A;B表示功能更新,出现新功能时增加B;C表示小的改动(例如:修复了某个Bug),只要有修改就增加C。如果对Python的历史感兴趣,可以阅读名为[《Python简史》](http://www.cnblogs.com/vamei/archive/2013/02/06/2892628.html)的网络文章
 
 #### Python的优缺点
 
 Python的优点很多,简单的可以总结为以下几点。
 
-1. 简单和明确,做一件事只有一种方法。
-2. 学习曲线低,跟其他很多语言相比,Python更容易上手。
-3. 开放源代码,拥有强大的社区和生态圈。
-4. 解释型语言,天生具有平台可移植性。
-5. 对两种主流的编程范式(面向对象编程和函数式编程)都提供了支持。
-6. 可扩展性和可嵌入性,例如在Python中可以调用C/C++代码。
-7. 代码规范程度高,可读性强,适合有代码洁癖和强迫症的人群。
+1. 简单明了,学习曲线低,比很多编程语言都容易上手。
+2. 开放源代码,拥有强大的社区和生态圈,尤其是在数据分析和机器学习领域。
+3. 解释型语言,天生具有平台可移植性,代码可以工作于不同的操作系统。
+4. 对两种主流的编程范式(面向对象编程和函数式编程)都提供了支持。
+5. 代码规范程度高,可读性强,适合有代码洁癖和强迫症的人群。
 
 Python的缺点主要集中在以下几点。
 
-1. 执行效率稍低,因此计算密集型任务可以由C/C++编写。
+1. 执行效率稍低,对执行效率要求高的部分可以由其他语言(如:C、C++)编写。
 2. 代码无法加密,但是现在很多公司都不销售卖软件而是销售服务,这个问题会被弱化。
 3. 在开发时可以选择的框架太多(如Web框架就有100多个),有选择的地方就有错误。
 
 #### Python的应用领域
 
-目前Python在Web应用开发、云基础设施、DevOps、网络数据采集(爬虫)、数据分析挖掘、机器学习等领域都有着广泛的应用,因此也产生了Web后端开发、数据接口开发、自动化运维、自动化测试、科学计算和可视化、数据分析、量化交易、机器人开发、自然语言处理、图像识别等一系列相关的职位
+目前Python在Web应用后端开发、云基础设施建设、DevOps、网络数据采集(爬虫)、自动化测试、数据分析、机器学习等领域都有着广泛的应用。
 
 ### 安装Python解释器
 
-想要开始Python编程之旅,首先得在自己使用的计算机上安装Python解释器环境,下面将以安装官方的Python解释器为例,讲解如何在不同的操作系统上安装Python环境。官方的Python解释器是用C语言实现的,也是使用最为广泛的Python解释器,通常称之为CPython。除此之外,Python解释器还有Java语言实现的Jython、C#语言实现的IronPython以及PyPy、Brython、Pyston等版本,我们暂时不对这些内容进行介绍,有兴趣的读者可以自行了解。
+想要开始Python编程之旅,首先得在自己使用的计算机上安装Python解释器环境,下面将以安装官方的Python解释器为例,讲解如何在不同的操作系统上安装Python环境。官方的Python解释器是用C语言实现的,也是使用最为广泛的Python解释器,通常称之为CPython。除此之外,Python解释器还有Java语言实现的Jython、C#语言实现的IronPython以及PyPy、Brython、Pyston等版本,有兴趣的读者可以自行了解。
 
 #### Windows环境
 
@@ -104,13 +102,13 @@ macOS也自带了Python 2.x版本,可以通过[Python的官方网站](https://
 ```Shell
 python --version
 ```
-或者是在Linux或macOS系统的终端中键入下面的命令。
+在Linux或macOS系统的终端中键入下面的命令。
 
 ```Shell
 python3 --version
 ```
 
-当然也可以先输入python或python3进入交互式环境,再执行以下的代码检查Python的版本。
+当然也可以先输入`python``python3`进入交互式环境,再执行以下的代码检查Python的版本。
 
 ```Python
 import sys
@@ -156,12 +154,8 @@ python3 hello.py
 Version: 0.1
 Author: 骆昊
 """
-
 print('hello, world!')
-# print("你好,世界!")
-print('你好', '世界')
-print('hello', 'world', sep=', ', end='!')
-print('goodbye, world', end='!\n')
+# print("你好, 世界!")
 ```
 
 ### Python开发工具
@@ -174,7 +168,7 @@ IDLE是安装Python环境时自带的集成开发工具,如下图所示。但
 
 #### IPython - 更好的交互式编程工具
 
-IPython是一种基于Python的交互式解释器。相较于原生的Python交互式环境,IPython提供了更为强大的编辑和交互功能。可以通过Python的包管理工具pip安装IPython和Jupyter,具体的操作如下所示。
+IPython是一种基于Python的交互式解释器。相较于原生的Python交互式环境,IPython提供了更为强大的编辑和交互功能。可以通过Python的包管理工具pip安装IPython,具体的操作如下所示。
 
 ```Shell
 pip install ipython
@@ -220,7 +214,7 @@ pip3 install ipython
   - Python PEP8 Autoformat - PEP8规范自动格式化插件。
   - ConvertToUTF8 - 将本地编码转换为UTF-8。
 
-> 说明:事实上[Visual Studio Code](<https://code.visualstudio.com/>)可能是更好的选择,它不用花钱并提供了更为完整和强大的功能,有兴趣的读者可以自行研究。
+> **说明**:事实上[Visual Studio Code](<https://code.visualstudio.com/>)可能是更好的选择,它不用花钱并提供了更为完整和强大的功能,有兴趣的读者可以自行研究。
 
 #### PyCharm - Python开发神器
 
@@ -236,12 +230,11 @@ PyCharm的安装、配置和使用在[《玩转PyCharm》](../玩转PyCharm.md)
     import this
     ```
 
-    > 说明:输入上面的代码,在Python的交互式环境中可以看到Tim Peter撰写的[“Python之禅”](../Python之禅.md),里面讲述的道理不仅仅适用于Python,也适用于其他编程语言。
-    >
+    > **说明**:输入上面的代码,在Python的交互式环境中可以看到Tim Peter撰写的[“Python之禅”](../Python之禅.md),里面讲述的道理不仅仅适用于Python,也适用于其他编程语言。
 
 2. 学习使用turtle在屏幕上绘制图形。
 
-    > 说明:turtle是Python内置的一个非常有趣的模块,特别适合对计算机程序设计进行初体验的小伙伴,它最早是Logo语言的一部分,Logo语言是Wally Feurzig和Seymour Papert在1966发明的编程语言。
+    > **说明**:turtle是Python内置的一个非常有趣的模块,特别适合对计算机程序设计进行初体验的小伙伴,它最早是Logo语言的一部分,Logo语言是Wally Feurzig和Seymour Papert在1966发明的编程语言。
 
     ```Python
     import turtle
@@ -260,4 +253,4 @@ PyCharm的安装、配置和使用在[《玩转PyCharm》](../玩转PyCharm.md)
     turtle.mainloop()
     ```
 
-    > 提示:本章提供的代码中还有画国旗和画小猪佩奇的代码,有兴趣的读者请自行研究。
+    > **提示**:本章提供的代码中还有画国旗和画小猪佩奇的代码,有兴趣的读者请自行研究。

File diff ditekan karena terlalu besar
+ 0 - 0
Day01-15/02.语言元素.md


+ 2 - 6
Day01-15/03.分支结构.md

@@ -15,7 +15,6 @@
 Version: 0.1
 Author: 骆昊
 """
-
 username = input('请输入用户名: ')
 password = input('请输入口令: ')
 # 用户名是admin且密码是123456则身份验证成功否则身份验证失败
@@ -25,9 +24,9 @@ else:
     print('身份验证失败!')
 ```
 
-唯一需要说明的是和C/C++、Java等语言不同,Python中没有用花括号来构造代码块而是使用了缩进的方式来设置代码的层次结构,如果`if`条件成立的情况下需要执行多条语句,只要保持多条语句具有相同的缩进就可以了,换句话说连续的代码如果又保持了相同的缩进那么它们属于同一个代码块,相当于是一个执行的整体。
+需要说明的是和C/C++、Java等语言不同,Python中没有用花括号来构造代码块而是**使用了缩进的方式来表示代码的层次结构**,如果`if`条件成立的情况下需要执行多条语句,只要保持多条语句具有相同的缩进就可以了。换句话说**连续的代码如果又保持了相同的缩进那么它们属于同一个代码块**,相当于是一个执行的整体。**缩进**可以使用任意数量的空格,但**通常使用4个空格**,建议大家**不要使用制表键**或者**设置你的代码编辑工具自动将制表键变成4个空格**。
 
-当然如果要构造出更多的分支,可以使用`if…elif…else…`结构,例如下面的分段函数求值。
+当然如果要构造出更多的分支,可以使用`if...elif...else...`结构或者嵌套的`if...else...`结构,下面的代码演示了如何利用多分支结构实现分段函数求值。
 
 ![$$f(x)=\begin{cases} 3x-5&\text{(x>1)}\\x+2&\text{(-1}\leq\text{x}\leq\text{1)}\\5x+3&\text {(x<-1)}\end{cases}$$](./res/formula_1.png)
 
@@ -92,7 +91,6 @@ print('f(%.2f) = %.2f' % (x, y))
 Version: 0.1
 Author: 骆昊
 """
-
 value = float(input('请输入长度: '))
 unit = input('请输入单位: ')
 if unit == 'in' or unit == '英寸':
@@ -116,7 +114,6 @@ else:
 Version: 0.1
 Author: 骆昊
 """
-
 score = float(input('请输入成绩: '))
 if score >= 90:
     grade = 'A'
@@ -141,7 +138,6 @@ print('对应的等级是:', grade)
 Version: 0.1
 Author: 骆昊
 """
-
 a = float(input('a = '))
 b = float(input('b = '))
 c = float(input('c = '))

+ 15 - 11
Day01-15/04.循环结构.md

@@ -2,9 +2,9 @@
 
 ### 应用场景
 
-如果在程序中我们需要重复的执行某条或某些指令,例如用程序控制机器人踢足球,如果机器人持球而且还没有进入射门范围,那么我们就要一直发出让机器人向球门方向奔跑的指令。当然你可能已经注意到了,刚才的描述中不仅仅有需要重复的动作,还需要用到上一章讲的分支结构。再举一个简单的例子,我们要实现一个每隔1秒中在屏幕上打印一次&quot;hello, world&quot;并持续打印一个小时的程序,我们肯定不能够直接把`print('hello, world')`这句代码写3600遍,如果真的要这样做,那么编程的工作就太无聊乏味了。因此,我们还需要了解一下循环结构,有了循环结构我们就可以轻松的控制某件事或者某些事重复、重复、再重复的去执行
+我们在写程序的时候,一定会遇到需要重复执行某条或某些指令的场景。例如用程序控制机器人踢足球,如果机器人持球而且还没有进入射门范围,那么我们就要一直发出让机器人向球门方向移动的指令。在这个场景中,让机器人向球门方向移动就是一个需要重复的动作,当然这里还会用到上一课讲的分支结构来判断机器人是否持球以及是否进入射门范围。再举一个简单的例子,如果要实现每隔1秒中在屏幕上打印一次“hello, world”并持续打印一个小时,我们肯定不能够直接把`print('hello, world')`这句代码写3600遍,这里同样需要循环结构。
 
-在Python中构造循环结构有两种做法,一种是`for-in`循环,一种是`while`循环。
+循环结构就是程序中控制某条或某些指令重复执行的结构。在Python中构造循环结构有两种做法,一种是`for-in`循环,一种是`while`循环。
 
 ### for-in循环
 
@@ -24,11 +24,12 @@ for x in range(101):
 print(sum)
 ```
 
-需要说明的是上面代码中的`range(101)`可以用来构造一个从0到100的取值范围,这样就可以构造出一个整数的序列并用于循环中,例如
+需要说明的是上面代码中的`range(1, 101)`可以用来构造一个从1到100的范围,当我们把这样一个范围放到`for-in`循环中,就可以通过前面的循环变量`x`依次取出从1到100的整数。当然,`range`的用法非常灵活,下面给出了一个例子
 
-- `range(101)`可以产生一个0到100的整数序列。
-- `range(1, 100)`可以产生一个1到99的整数序列。
-- `range(1, 100, 2)`可以产生一个1到99的奇数序列,其中2是步长,即数值序列的增量。
+- `range(101)`:可以用来产生0到100范围的整数,需要注意的是取不到101。
+- `range(1, 101)`:可以用来产生1到100范围的整数,相当于前面是闭区间后面是开区间。
+- `range(1, 101, 2)`:可以用来产生1到100的奇数,其中2是步长,即每次数值递增的值。
+- `range(100, 0, -2)`:可以用来产生100到1的偶数,其中-2是步长,即每次数字递减的值。
 
 知道了这一点,我们可以用下面的代码来实现1~100之间的偶数求和。
 
@@ -46,7 +47,7 @@ for x in range(2, 101, 2):
 print(sum)
 ```
 
-也可以通过在循环中使用分支结构的方式来实现相同的功能,代码如下所示。
+当然,也可以通过在循环中使用分支结构的方式来实现相同的功能,代码如下所示。
 
 ```Python
 """
@@ -63,20 +64,21 @@ for x in range(1, 101):
 print(sum)
 ```
 
+> **说明**:相较于上面直接跳过奇数的做法,下面这种做法很明显并不是很好的选择。
+
 ### while循环
 
-如果要构造不知道具体循环次数的循环结构,我们推荐使用`while`循环。`while`循环通过一个能够产生或转换出`bool`值的表达式来控制循环,表达式的值为`True`循环继续,表达式的值为`False`循环结束。下面我们通过一个“猜数字”的小游戏(计算机出一个1~100之间的随机数,人输入自己猜的数字,计算机给出对应的提示信息,直到人猜出计算机出的数字)来看看如何使用`while`循环。
+如果要构造不知道具体循环次数的循环结构,我们推荐使用`while`循环。`while`循环通过一个能够产生或转换出`bool`值的表达式来控制循环,表达式的值为`True`则继续循环;表达式的值为`False`则结束循环。
+
+下面我们通过一个“猜数字”的小游戏来看看如何使用`while`循环。猜数字游戏的规则是:计算机出一个1到100之间的随机数,玩家输入自己猜的数字,计算机给出对应的提示信息(大一点、小一点或猜对了),如果玩家猜中了数字,计算机提示用户一共猜了多少次,游戏结束,否则游戏继续。
 
 ```Python
 """
 猜数字游戏
-计算机出一个1~100之间的随机数由人来猜
-计算机根据人猜的数字分别给出提示大一点/小一点/猜对了
 
 Version: 0.1
 Author: 骆昊
 """
-
 import random
 
 answer = random.randint(1, 100)
@@ -147,6 +149,8 @@ else:
 
 #### 练习2:输入两个正整数,计算它们的最大公约数和最小公倍数。
 
+> **提示**:两个数的最大公约数是两个数的公共因子中最大的那个数;两个数的最小公倍数则是能够同时被两个数整除的最小的那个数。
+
 参考答案:
 
 ```Python

+ 15 - 8
Day01-15/06.函数和模块的使用.md

@@ -17,7 +17,6 @@
 Version: 0.1
 Author: 骆昊
 """
-
 m = int(input('m = '))
 n = int(input('n = '))
 fm = 1
@@ -26,10 +25,10 @@ for num in range(1, m + 1):
 fn = 1
 for num in range(1, n + 1):
     fn *= num
-fmn = 1
+fm_n = 1
 for num in range(1, m - n + 1):
-    fmn *= num
-print(fm // fn // fmn)
+    fm_n *= num
+print(fm // fn // fm_n)
 ```
 
 ### 函数的作用
@@ -43,7 +42,13 @@ print(fm // fn // fmn)
 在了解了如何定义函数后,我们可以对上面的代码进行重构,所谓重构就是在不影响代码执行结果的前提下对代码的结构进行调整,重构之后的代码如下所示。
 
 ```Python
-def factorial(num):
+"""
+输入M和N计算C(M,N)
+
+Version: 0.1
+Author: 骆昊
+"""
+def fac(num):
     """求阶乘"""
     result = 1
     for n in range(1, num + 1):
@@ -54,10 +59,10 @@ def factorial(num):
 m = int(input('m = '))
 n = int(input('n = '))
 # 当需要计算阶乘的时候不用再写循环求阶乘而是直接调用已经定义好的函数
-print(factorial(m) // factorial(n) // factorial(m - n))
+print(fac(m) // fac(n) // fac(m - n))
 ```
 
-> **说明:** Python的`math`模块中其实已经有一个`factoria`l函数了,事实上要计算阶乘可以直接使用这个现成的函数而不用自己定义。下面例子中的一些函数在Python中也都是现成的,我们这里是为了讲解函数的定义和使用才把它们又实现了一遍,实际开发中不建议做这种低级的重复性的工作
+> **说明:** Python的`math`模块中其实已经有一个名为`factorial`函数实现了阶乘运算,事实上求阶乘并不用自己定义函数。下面的例子中,我们讲的函数在Python标准库已经实现过了,我们这里是为了讲解函数的定义和使用才把它们又实现了一遍,**实际开发中并不建议做这种低级的重复劳动**
 
 
 ### 函数的参数
@@ -267,7 +272,7 @@ def is_palindrome(num):
 ```Python
 def is_prime(num):
     """判断一个数是不是素数"""
-    for factor in range(2, num):
+    for factor in range(2, int(num ** 0.5) + 1):
         if num % factor == 0:
             return False
     return True if num != 1 else False
@@ -286,6 +291,8 @@ if __name__ == '__main__':
 
 > **注意**:通过上面的程序可以看出,当我们**将代码中重复出现的和相对独立的功能抽取成函数**后,我们可以**组合使用这些函数**来解决更为复杂的问题,这也是我们为什么要定义和使用函数的一个非常重要的原因。
 
+### 变量的作用域
+
 最后,我们来讨论一下Python中有关变量作用域的问题。
 
 ```Python

+ 1 - 1
Day16-20/16-20.Python语言进阶.md

@@ -652,7 +652,7 @@
           return 1800.0 + self.sales * 0.05
   
   
-  class EmployeeFactory():
+  class EmployeeFactory:
       """创建员工的工厂(工厂模式 - 通过工厂实现对象使用者和对象之间的解耦合)"""
   
       @staticmethod

+ 0 - 6
Day91-100/100.Python面试题集.md

@@ -69,14 +69,10 @@
    ''.join(reversed('hello'))
    ```
 
-   或
-
    ```Python
    'hello'[::-1]
    ```
 
-   或
-
    ```Python
    def reverse(content):
        return ''.join(content[i] for i in range(len(content) - 1, -1, -1))
@@ -84,8 +80,6 @@
    reverse('hello')
    ```
 
-   或
-
    ```Python
    def reverse(content):
        return reverse(content[1:]) + content[0] if len(content) > 1 else content

+ 7 - 7
Day91-100/91.团队项目开发的问题和解决方案.md

@@ -427,21 +427,21 @@ Git不像SVN那样一定需要中央服务器才能工作,上面我们演示
    创建`feature`分支:
 
    ```Shell
-   git switch -c myfeature develop
+   git switch -c feature/user develop
    ```
 
 
    ```Shell
-   git checkout -b myfeature develop
+   git checkout -b feature/user develop
    ```
 
-   将`feature`分支合并到`develop`分支:
+   接下来就是在`feature`分支上进行开发并实施版本控制,这一段如何操作我们就不再赘述了。工作完成后,将`feature`分支合并到`develop`分支:
 
    ```Shell
    git checkout develop
-   git merge --no-ff myfeature
-   git branch -d myfeature
+   git merge --no-ff feature/user
+   git branch -d feature/user
    git push origin develop
    ```
 
@@ -547,7 +547,7 @@ tar -xvf ZenTaoPMS.pro8.5.2.zbox_64.tar
 
 对敏捷开发以及敏捷闭环工具不是特别了解的,可以参考[《基于JIRA的Scrum敏捷开发的项目管理》](<https://blog.51cto.com/newthink/1775427>)一文。
 
-#### Gitlab
+#### GitLab
 
 常用的代码托管平台和之前提到的Git私服Gitlab都提供了缺陷管理的功能,当我们要报告一个bug时,可以在如下图所示的界面创建一个新的问题票(issue ticket)。填写的内容包括:
 
@@ -583,7 +583,7 @@ tar -xvf ZenTaoPMS.pro8.5.2.zbox_64.tar
 
 ![](./res/jenkins_new_project.png)
 
-持续集成对于编译型语言的意义更大,对于Python这样的解释型语言,更多的时候是用于对接版本控制系统触发自动化测试并产生相应的报告,类似的功能也可以通过配置**Webhook**来完成。如果要通过Docker这样的虚拟化容器进行项目打包部署或者通过K8S进行容器管理,可以在持续集成平台安装对应的插件来支持这些功能。码云甚至可以直接对接[钉钉开放平台](<https://ding-doc.dingtalk.com/>)使用钉钉机器人来向项目相关人员发送即时消息。Gitlab也对CI和CD(持续交付)提供了支持,具体内容请大家参考[《GitLab CI/CD基础教程》](<https://blog.stdioa.com/2018/06/gitlab-cicd-fundmental/>)。
+持续集成对于编译型语言的意义更大,对于Python这样的解释型语言,更多的时候是用于对接版本控制系统触发自动化测试并产生相应的报告,类似的功能也可以通过配置**Webhook**来完成。如果要通过Docker这样的虚拟化容器进行项目打包部署或者通过K8S进行容器管理,可以在持续集成平台安装对应的插件来支持这些功能。码云甚至可以直接对接[钉钉开放平台](<https://ding-doc.dingtalk.com/>)使用钉钉机器人来向项目相关人员发送即时消息。GitLab也对CI和CD(持续交付)提供了支持,具体内容请大家参考[《GitLab CI/CD基础教程》](<https://blog.stdioa.com/2018/06/gitlab-cicd-fundmental/>)。
 
 > **说明**:
 >

+ 2 - 2
Day91-100/92.Docker容器详解.md

@@ -30,7 +30,7 @@ Docker属于对Linux容器技术(LXC)的一种封装(利用了Linux的name
    uname -r
    ```
 
-2. 更系统底层的库文件(建议一定要执行,否则在使用Docker时可能会出现莫名其妙的问题)。
+2. 更系统底层的库文件(建议一定要执行,否则在使用Docker时可能会出现莫名其妙的问题)。
 
    ```Bash
    yum update
@@ -399,7 +399,7 @@ docker run -d -p 80:80 -p 22:22 --name gitlab -v /root/gitlab/config:/etc/gitlab
 
 ### 构建镜像
 
-通过上面的讲解,我们已经掌握了如何通过官方提供的镜像来创建容器。当然如果愿意,我们也可以用配置好的容器来生成镜像。简而言之,Docker镜像是由文件系统叠加而成的,系统的最底层是bootfs,相当于就是Linux内核的引导文件系统;接下来第二层是rootfs,这一层可以是一种或多种操作系统(如Debian或Ubuntu文件系统),Docker中的rootfs是只读状态的;Docker利用联合挂载技术将各层文件系统叠加到一起,最终的文件系统会包含有底层的文件和目录,这样的文件系统就是一个镜像。
+通过上面的讲解,我们已经掌握了如何通过官方提供的镜像来创建容器。当然如果愿意,我们也可以用配置好的容器来生成镜像。简而言之,**Docker镜像是由文件系统叠加而成的,系统的最底层是bootfs,相当于就是Linux内核的引导文件系统;接下来第二层是rootfs,这一层可以是一种或多种操作系统(如Debian或Ubuntu文件系统),Docker中的rootfs是只读状态的;Docker利用联合挂载技术将各层文件系统叠加到一起,最终的文件系统会包含有底层的文件和目录,这样的文件系统就是一个镜像**
 
 之前我们讲过了如何查找、列出镜像和拉取(下载)镜像,接下来看看构建镜像的两种方式:
 

+ 1 - 1
Day91-100/97.电商网站技术要点剖析.md

@@ -305,7 +305,7 @@ if alipay.verify(params, params.pop('sign')):
 1. 秒杀:秒杀是通常意味着要在很短的时间处理极高的并发,系统在短时间需要承受平时百倍以上的流量,因此秒杀架构是一个比较复杂的问题,其核心思路是流量控制和性能优化,需要从前端(通过JavaScript实现倒计时、避免重复提交和限制频繁刷新)到后台各个环节的配合。流量控制主要是限制只有少部分流量进入服务后端(毕竟最终只有少部分用户能够秒杀成功),同时在物理架构上使用缓存(一方面是因为读操作多写操作少;另外可以将库存放在Redis中,利用DECR原语实现减库存;同时也可以利用Redis来进行限流,道理跟限制频繁发送手机验证码是一样的)和消息队列(消息队列最为重要的作用就是“削峰”和“上下游节点解耦合”)来进行优化;此外还要采用无状态服务设计,这样才便于进行水平扩展(通过增加设备来为系统扩容)。
 2. 超卖现象:比如某商品的库存为1,此时用户1和用户2并发购买该商品,用户1提交订单后该商品的库存被修改为0,而此时用户2并不知道的情况下提交订单,该商品的库存再次被修改为-1这就是超卖现象。解决超卖现象有三种常见的思路:
    - 悲观锁控制:查询商品数量的时候就用`select ... for update`对数据加锁,这样的话用户1查询库存时,用户2因无法读取库存数量被阻塞,直到用户1提交或者回滚了更新库存的操作后才能继续,从而解决了超卖问题。但是这种做法对并发访问量很高的商品来说性能太过糟糕,实际开发中可以在库存小于某个值时才考虑加锁,但是总的来说这种做法不太可取。
-   - 乐观锁控制:查询商品数量不用加锁,更新库存的时候设定商品数量必须与之前查询数量相同才能更新,否则说明其他事务已经更新了库存,必须重新发出请求。这种做法要求事务隔离级别为可重复读(repeatable read),否则仍然会产生问题。
+   - 乐观锁控制:查询商品数量不用加锁,更新库存的时候设定商品数量必须与之前查询数量相同才能更新,否则说明其他事务已经更新了库存,必须重新发出请求。
    - 尝试减库存:将上面的查询(`select`)和更新(`update`)操作合并为一条SQL操作,更新库存的时候,在`where`筛选条件中加上`库存>=购买数量`或`库存-购买数量>=0`的条件,这种做法要求事务隔离级别为读提交(read committed)。
 
 > 提示:有兴趣的可以自己在知乎上看看关于这类问题的讨论。

+ 1 - 1
Day91-100/98.项目部署上线和性能调优.md

@@ -292,7 +292,7 @@ pip install -r code/teamproject/requirements.txt
 
     ```Nginx
     # 配置用户
-    user root;
+    user nginx;
     # 工作进程数(建议跟CPU的核数量一致)
     worker_processes auto;
     # 错误日志

+ 4 - 2
README.md

@@ -1,8 +1,10 @@
 ## Python - 100天从新手到大师
 
-> 作者:骆昊
+> **作者**:骆昊
 >
-> 最近有很多想学习Python的小伙伴陆陆续续加入我们的交流群,目前我们的交流群人数已经超过一万人。我们的目标是打造一个优质的Python交流社区,一方面为Python初学者扫平入门过程中的重重障碍,另一方为新入行的开发者提供问道的门径,帮助他们迅速成长。我自己很希望更多有经验的开发者加入到这个平台,把自己的工作经验无偿分享或有偿提供出来,让大家最终都能够通过这个平台获取对自己有帮助的信息。我的知乎号是[Python-Jack](https://www.zhihu.com/people/jackfrued),之前是我的团队在协助运营,从现在开始我会自己管理这个知乎号,持续为大家提供高质量的文章和新的学习内容,也欢迎大家关注我在知乎的文章和问题回答。创作不易,感谢大家的打赏支持,这些钱不会用于购买咖啡而是通过腾讯公益平台捐赠给需要帮助的人([点击](./更新日志.md)了解捐赠情况)。
+> **说明**:从项目上线到获得8w+星标以来,一直收到反馈说基础部分(前15天的内容)对新手来说是比较困难的,建议有配套视频进行讲解。最近把基础部分的内容重新创建了一个名为[“Python-Core-50-Courses”](<https://github.com/jackfrued/Python-Core-50-Courses>)的项目,**用更为简单通俗的方式重写了这部分内容并附带了视频讲解**,初学者可以关注下这个新项目。国内用户如果访问GitHub比较慢的话,也可以关注我的知乎号[Python-Jack](https://www.zhihu.com/people/jackfrued)上的[“从零开始学Python”](<https://zhuanlan.zhihu.com/c_1216656665569013760>)专栏,专栏会持续更新,还有大家比较期待的“数据分析”的内容也即将上线,**欢迎大家关注我在知乎的专栏、文章和回答**。
+>
+> 创作不易,感谢大家的打赏支持,这些钱基本不会用于购买咖啡,而是通过腾讯公益、美团公益、水滴筹等平台捐赠给需要帮助的人([点击](./更新日志.md)了解捐赠情况)。需要加入QQ交流群的可以扫描下面的二维码,交流群会为大家提供**学习资源**和**问题解答**,还会持续为大家带来**免费的线上Python体验课和行业公开课**,敬请关注。
 
 ![](./res/python-qq-group.png)
 

+ 5 - 0
更新日志.md

@@ -1,5 +1,10 @@
 ## 更新日志
 
+### 2020年4月2日
+
+1. 将基础部分(第1天到第15天)内容重新创建了一个名为“Python-Core-50-Courses”的仓库,更新了部分内容。
+2. 更新了README.md文件。
+
 ### 2020年3月8日
 
 1. 更新了最后10天的部分文档。

Beberapa file tidak ditampilkan karena terlalu banyak file yang berubah dalam diff ini