更新了部分代码

pull/25/head
jackfrued 2018-11-18 00:26:51 +08:00
parent bdaac3529b
commit 161af9c84d
28 changed files with 2248 additions and 71 deletions

View File

@ -1,20 +1,644 @@
## Python语言进阶
### 常用数据结构
### 数据结构和算法
#### 排序算法(冒泡和归并)
```Python
def bubble_sort(items, comp=lambda x, y: x > y):
"""高质量冒泡排序(搅拌排序)"""
for i in range(len(items) - 1):
swapped = False
for j in range(len(items) - 1 - i):
if comp(items[j], items[j + 1]):
items[j], items[j + 1] = items[j + 1], items[j]
swapped = True
if swapped:
swapped = False
for j in range(len(items) - 2 - i, i, -1):
if comp(items[j - 1], items[j]):
items[j], items[j - 1] = items[j - 1], items[j]
swapped = True
if not swapped:
break
```
```Python
def merge_sort(items, comp=lambda x, y: x <= y):
"""归并排序(分治法)"""
if len(items) < 2:
return items[:]
mid = len(items) // 2
left = merge_sort(items[:mid], comp)
right = merge_sort(items[mid:], comp)
return merge(left, right, comp)
def merge(items1, items2, comp=lambda x, y: x <= y):
"""合并(将两个有序的列表合并成一个有序的列表)"""
items = []
idx1, idx2 = 0, 0
while idx1 < len(items1) and idx2 < len(items2):
if comp(items1[idx1], items2[idx2]):
items.append(items1[idx1])
idx1 += 1
else:
items.append(items2[idx2])
idx2 += 1
items += items1[idx1:]
items += items2[idx2:]
return items
```
### 函数的高级用法
```Python
def seq_search(items, key):
"""顺序查找"""
for index, item in enumerate(items):
if item == key:
return index
return -1
```
#### 查找算法(顺序和折半)
```Python
def bin_search(items, key):
"""折半查找(循环实现)"""
start, end = 0, len(items) - 1
while start <= end:
mid = (start + end) // 2
if key > items[mid]:
start = mid + 1
elif key < items[mid]:
end = mid - 1
else:
return mid
return -1
```
#### 使用生成式(推导式)
```Python
prices = {
'AAPL': 191.88,
'GOOG': 1186.96,
'IBM': 149.24,
'ORCL': 48.44,
'ACN': 166.89,
'FB': 208.09,
'SYMC': 21.29
}
# 用股票价格大于100元的股票构造一个新的字典
prices2 = {key: value for key, value in prices.items() if value > 100}
print(prices2)
```
#### 嵌套的列表
```Python
def main():
names = ['关羽', '张飞', '赵云', '马超', '黄忠']
courses = ['语文', '数学', '英语']
# 录入五个学生三门课程的成绩
# 错误 - 参考http://pythontutor.com/visualize.html#mode=edit
# scores = [[None] * len(courses)] * len(names)
scores = [[None] * len(courses) for _ in range(len(names))]
for row, name in enumerate(names):
for col, course in enumerate(courses):
scores[row][col] = float(input(f'请输入{name}的{course}成绩: '))
print(scores)
if __name__ == '__main__':
main()
```
### 面向对象高级知识
[Python Tutor](http://pythontutor.com/) - VISUALIZE CODE AND GET LIVE HELP
#### heapq、itertools等的用法
```Python
"""
从列表中找出最大的或最小的N个元素
"""
import heapq
def main():
list1 = [34, 25, 12, 99, 87, 63, 58, 78, 88, 92]
list2 = [
{'name': 'IBM', 'shares': 100, 'price': 91.1},
{'name': 'AAPL', 'shares': 50, 'price': 543.22},
{'name': 'FB', 'shares': 200, 'price': 21.09},
{'name': 'HPQ', 'shares': 35, 'price': 31.75},
{'name': 'YHOO', 'shares': 45, 'price': 16.35},
{'name': 'ACME', 'shares': 75, 'price': 115.65}
]
print(heapq.nlargest(3, list1))
print(heapq.nsmallest(3, list1))
print(heapq.nlargest(2, list2, key=lambda x: x['price']))
print(heapq.nlargest(2, list2, key=lambda x: x['shares']))
if __name__ == '__main__':
main()
```
```Python
"""
排列 / 组合 / 笛卡尔积
"""
import itertools
def main():
for val in itertools.permutations('ABCD'):
print(val)
print('-' * 50)
for val in itertools.combinations('ABCDE', 3):
print(val)
print('-' * 50)
for val in itertools.product('ABCD', '123'):
print(val)
if __name__ == '__main__':
main()
```
#### collections模块下的工具类
```Python
"""
找出序列中出现次数最多的元素
"""
from collections import Counter
def main():
words = [
'look', 'into', 'my', 'eyes', 'look', 'into', 'my', 'eyes',
'the', 'eyes', 'the', 'eyes', 'the', 'eyes', 'not', 'around',
'the', 'eyes', "don't", 'look', 'around', 'the', 'eyes',
'look', 'into', 'my', 'eyes', "you're", 'under'
]
counter = Counter(words)
print(counter.most_common(3))
if __name__ == '__main__':
main()
```
#### 穷举法、贪婪法、分治法、动态规划
```Python
"""
穷举法 - 穷尽所有可能直到找到正确答案
"""
def main():
# 公鸡5元一只 母鸡3元一只 小鸡1元三只
# 用100元买100只鸡 问公鸡/母鸡/小鸡各多少只
for x in range(20):
for y in range(33):
z = 100 - x - y
if 5 * x + 3 * y + z // 3 == 100 and z % 3 == 0:
print(x, y, z)
# A、B、C、D、E五人在某天夜里合伙捕鱼 最后疲惫不堪各自睡觉
# 第二天A第一个醒来 他将鱼分为5份 扔掉多余的1条 拿走自己的一份
# B第二个醒来 也将鱼分为5份 扔掉多余的1条 拿走自己的一份
# 然后C、D、E依次醒来也按同样的方式分鱼 问他们至少捕了多少条鱼
fish = 1
while True:
total = fish
enough = True
for _ in range(5):
if (total - 1) % 5 == 0:
total = (total - 1) // 5 * 4
else:
enough = False
break
if enough:
print(fish)
break
fish += 1
if __name__ == '__main__':
main()
```
```Python
"""
动态规划 - 适用于有重叠子问题和最优子结构性质的问题
使用动态规划方法所耗时间往往远少于朴素解法(用空间换取时间)
"""
def fib(num, temp={}):
"""用递归计算Fibonacci数"""
if num in (1, 2):
return 1
try:
return temp[num]
except KeyError:
temp[num] = fib(num - 1) + fib(num - 2)
return temp[num]
```
### 函数的使用方式
- 将函数视为“一等公民”
- 高阶函数的用法filter、map以及它们的替代品
- 位置参数、可变参数、关键字参数、命名关键字参数
- 参数的元信息(代码可读性问题)
- 匿名函数和内联函数的用法lambda函数
- 闭包和作用域问题LEGB
- 装饰器函数(使用装饰器和取消装饰器)
输出函数执行时间的装饰器。
```Python
from functools import wraps
from time import time
def record(output):
def decorate(func):
@wraps(func)
def wrapper(*args, **kwargs):
start = time()
result = func(*args, **kwargs)
output(func.__name__, time() - start)
return result
return wrapper
return decorate
```
```Python
from functools import wraps
from time import time
class Record(object):
def __init__(self, output):
self.output = output
def __call__(self, func):
@wraps(func)
def wrapper(*args, **kwargs):
start = time()
result = func(*args, **kwargs)
self.output(func.__name__, time() - start)
return result
return wrapper
```
用装饰器来实现单例模式。
```Python
from functools import wraps
def singleton(cls):
instances = {}
@wraps(cls)
def wrapper(*args, **kwargs):
if cls not in instances:
instances[cls] = cls(*args, **kwargs)
return instances[cls]
return wrapper
@singleton
class Singleton(object):
pass
```
### 面向对象相关知识
- 三大支柱:封装、继承、多态
```Python
"""
月薪结算系统
部门经理每月15000 程序员每小时200 销售员1800底薪+销售额5%提成
"""
from abc import ABCMeta, abstractmethod
class Employee(metaclass=ABCMeta):
"""员工(抽象类)"""
def __init__(self, name):
self._name = name
@property
def name(self):
"""姓名"""
return self._name
@abstractmethod
def get_salary(self):
"""结算月薪(抽象方法)"""
pass
class Manager(Employee):
"""部门经理"""
def get_salary(self):
return 15000.0
class Programmer(Employee):
"""程序员"""
def __init__(self, name):
self._working_hour = 0
super().__init__(name)
@property
def working_hour(self):
"""工作时间"""
return self._working_hour
@working_hour.setter
def working_hour(self, hour):
self._working_hour = hour if hour > 0 else 0
def get_salary(self):
return 200.0 * self.working_hour
class Salesman(Employee):
"""销售员"""
def __init__(self, name):
self._sales = 0.0
super().__init__(name)
@property
def sales(self):
return self._sales
@sales.setter
def sales(self, sales):
self._sales = sales if sales > 0 else 0
def get_salary(self):
return 1800.0 + self.sales * 0.05
def main():
emps = [
Manager('刘备'), Manager('曹操'), Programmer('许褚'),
Salesman('貂蝉'), Salesman('赵云'), Programmer('张辽'),
Programmer('关羽'), Programmer('周瑜')
]
for emp in emps:
if isinstance(emp, Programmer):
emp.working_hour = int(input('本月工作时间: '))
elif isinstance(emp, Salesman):
emp.sales = float(input('本月销售额: '))
print('%s: %.2f元' % (emp.name, emp.get_salary()))
if __name__ == '__main__':
main()
```
- 对象的复制(深复制/深拷贝/深度克隆和浅复制/浅拷贝/影子克隆)
- 垃圾回收、循环引用和弱引用
Python使用了自动化内存管理这种管理机制以**引用计数**为基础,同时也引入了**标记-清除**和**分代收集**两种机制为辅的策略。
```C
typedef struct_object {
/* 引用计数 */
int ob_refcnt;
/* 对象指针 */
struct_typeobject *ob_type;
} PyObject;
```
```C
/* 增加引用计数的宏定义 */
#define Py_INCREF(op) ((op)->ob_refcnt++)
/* 减少引用计数的宏定义 */
#define Py_DECREF(op) \ //减少计数
if (--(op)->ob_refcnt != 0) \
; \
else \
__Py_Dealloc((PyObject *)(op))
```
导致引用计数+1的情况
- 对象被创建,例如`a = 23`
- 对象被引用,例如`b = a`
- 对象被作为参数,传入到一个函数中,例如`f(a)`
- 对象作为一个元素,存储在容器中,例如`list1 = [a, a]`
导致引用计数-1的情况
- 对象的别名被显式销毁,例如`del a`
- 对象的别名被赋予新的对象,例如`a = 24`
- 一个对象离开它的作用域例如f函数执行完毕时f函数中的局部变量全局变量不会
- 对象所在的容器被销毁,或从容器中删除对象
引用计数可能会导致循环引用问题而循环引用会导致内存泄露如下面的代码所示。为了解决这个问题Python中引入了“标记-清除”和“分代收集”。在创建一个对象的时候,对象被放在第一代中,如果在第一代的垃圾检查中对象存活了下来,该对象就会被放到第二代中,同理在第二代的垃圾检查中对象存活下来,该对象就会被放到第三代中。
```Python
list1 = []
list2 = []
list1.append(list2)
list2.append(list1)
```
以下情况会导致垃圾回收:
- 调用`gc.collect()`
- gc模块的计数器达到阀值
- 程序退出
如果循环引用中两个对象都定义了`__del__`方法gc模块不会销毁这些不可达对象因为gc模块不知道应该先调用哪个对象的`__del__`方法这个问题在Python 3.6中得到了解决。
也可以通过`weakref`模块构造弱引用的方式来解决循环引用的问题。
- 魔法属性和方法请参考《Python魔法方法指南》
有几个小问题请大家思考:
- 自定义的对象能不能使用运算符做运算?
- 自定义的对象能不能放到set中能去重吗
- 自定义的对象能不能作为dict的键
- 自定义的对象能不能使用上下文语法?
- 混入Mixin
```Python
"""
限制字典只有在指定的key不存在时才能设置键值对
MRO - Method Resolution Order - 多重继承时的方法解析顺序
"""
class SetOnceMappingMixin:
__slots__ = ()
def __setitem__(self, key, value):
if key in self:
raise KeyError(str(key) + ' already set')
return super().__setitem__(key, value)
class SetOnceDict(SetOnceMappingMixin, dict):
pass
def main():
dict1 = SetOnceDict()
try:
dict1['username'] = 'jackfrued'
dict1['username'] = 'hellokitty'
dict1['username'] = 'wangdachui'
except KeyError:
pass
print(dict1)
if __name__ == '__main__':
main()
```
- 元编程和元类
用元类实现单例模式。
```Python
"""
通过元类实现单例模式
"""
class SingletonMeta(type):
"""单例的元类"""
def __init__(cls, *args, **kwargs):
cls.__instance = None
super().__init__(*args, **kwargs)
def __call__(cls, *args, **kwargs):
if cls.__instance is None:
cls.__instance = super().__call__(*args, **kwargs)
return cls.__instance
class Singleton(metaclass=SingletonMeta):
"""单例类"""
def __init__(self, name):
self._name = name
from random import randrange
self._value = randrange(100000)
@property
def name(self):
return self._name
@property
def value(self):
return self._value
def main():
sin1 = Singleton('Lee')
sin2 = Singleton('Wang')
print(sin1 == sin2)
print(sin1.value, sin2.value)
print(sin1.name, sin2.name)
if __name__ == '__main__':
main()
```
### 迭代器和生成器
```Python
"""
生成器和迭代器
"""
### 并发和异步编程
def fib1(num):
"""普通函数"""
a, b = 0, 1
for _ in range(num):
a, b = b, a + b
return a
def fib2(num):
"""生成器"""
a, b = 0, 1
for _ in range(num):
a, b = b, a + b
yield a
class Fib3:
"""迭代器"""
def __init__(self, num):
self.num = num
self.a, self.b = 0, 1
self.idx = 0
def __iter__(self):
return self
def __next__(self):
if self.idx < self.num:
self.a, self.b = self.b, self.a + self.b
self.idx += 1
return self.a
raise StopIteration()
def main():
for val in fib2(20):
print(val)
print('-' * 50)
for val in Fib3(20):
print(val)
if __name__ == '__main__':
main()
```
### 并发编程
- 多线程和多进程
- 协程和异步I/O
- concurrent.futures

View File

@ -0,0 +1,25 @@
"""
实现查找功能的模块
"""
def seq_search(items, elem):
"""顺序查找"""
for index, item in enumerate(items):
if item == elem:
return index
return -1
def bin_search(items, elem):
"""折半查找(二分查找)"""
start, end = 0, len(items) - 1
while start <= end:
mid = (start + end) // 2
if elem < items[mid]:
end = mid - 1
elif elem > items[mid]:
start = mid + 1
else:
return mid
return -1

View File

@ -0,0 +1,113 @@
"""
排序 - 冒泡排序(简单O(N**2)) / 归并排序(高级O(N*log2N))
冒泡排序
34, 99, 52, 11, 47, 68, 50, 84
34, 52, 11, 47, 68, 50, 84, 99
34, 11, 47, 52, 50, 68, 84
11, 34, 47, 50, 52, 68
快速排序
34, 99, 52, 11, 47, 68, 50, 84
{34, 11, 47}, {50}, {99, 52, 68, 84}
{11}, {34}, {47}, {50}, {52, 68, 84}, {99}
{11}, {34}, {47}, {50}, {52}, {68, 84}, {99}
{11}, {34}, {47}, {50}, {52}, {68}, {84}, {99}
归并排序 - 分治法(divide-and-conquer)
34, 99, 52, 11, 47, 68, 50, 84
{34, 99, 52, 11}, {47, 68, 50, 84}
{34, 99}, {52, 11}, {47, 68}, {50, 84}
{34}, {99}, {52}, {11}, {47}, {68}, {50}, {84}
{34, 99}, {11, 52}, {47, 68}, {50, 84}
{11, 34, 52, 99}, {47, 50, 68, 84}
{11, 34, 47, 50, 52, 68, 84, 99}
在使用分治法的时候通常都会使用到递归调用这种编程手段
一个函数直接或间接的调用了自身就称之为递归调用
"""
# 9 1 2 3 4 5 6 7 8
# 2 3 4 5 6 7 8 9 1
# *前面的参数称为位置参数, *后面的参数称为命名关键字参数
# 所谓命名关键字参数就是调用函数时必须以"参数名=参数值"的形式传入参数
def bubble_sort(origin_items, *, comp=lambda x, y: x > y):
"""冒泡排序"""
items = origin_items[:]
length = len(items)
for i in range(1, length):
swapped = False
for j in range(0, length - i):
if comp(items[j], items[j + 1]):
items[j], items[j + 1] = items[j + 1], items[j]
swapped = True
if swapped:
swapped = False
for j in range(length - i - 1, i - 1, -1):
if comp(items[j - 1], items[j]):
items[j - 1], items[j] = items[j], items[j - 1]
swapped = True
if not swapped:
break
return items
def merge(list1, list2, comp=lambda x, y: x <= y):
""""有序合并(将两个有序的列表合并成一个新的有序的列表)"""
list3 = []
index1, index2 = 0, 0
while index1 < len(list1) and index2 < len(list2):
if comp(list1[index1], list2[index2]):
list3.append(list1[index1])
index1 += 1
else:
list3.append(list2[index2])
index2 += 1
list3 += list1[index1:]
list3 += list2[index2:]
return list3
def merge_sort(origin_items, comp=lambda x, y: x <= y):
"""归并排序"""
if len(origin_items) <= 1:
return origin_items[:]
mid = len(origin_items) // 2
left = merge_sort(origin_items[:mid], comp)
right = merge_sort(origin_items[mid:], comp)
return merge(left, right, comp)
class Person:
""""""
def __init__(self, name, age):
self.name = name
self.age = age
def __repr__(self):
return f'{self.name}: {self.age}'
def main():
# list1 = [12, 35, 48, 87, 92]
# list2 = [39, 44, 50, 60, 77, 88]
# list3 = merge(list1, list2)
# print(list3)
items = [34, 99, 52, 11, 47, 50, 84]
print(items)
print(merge_sort(items))
# items = ['hi', 'hello', 'orange', 'watermelon', 'zoo', 'pitaya']
# items = [
# Person("LuoHao", 38), Person("Baiyuanfang", 25),
# Person("Zhangsanfeng", 120), Person("Lee", 18)
# ]
# new_items = bubble_sort(items, comp=lambda x, y: len(x) > len(y))
# new_items = bubble_sort(items, comp=lambda x, y: x.age > y.age)
# print(items)
# print(new_items)
if __name__ == '__main__':
main()

View File

@ -0,0 +1,44 @@
"""
递归(recursion)
"""
def fac(num):
"""求阶乘"""
if num in (0, 1):
return 1
return num * fac(num - 1)
# 动态规划 - 把求解问题的中间结果保存起来
# 这种算法适合求解有最优子结构的问题或子问题会重复求解的问题
def fib(num, temp={}):
"""计算斐波拉切数"""
# 递归的两个要素
# 收敛条件 - 什么时候结束递归
if num in (1, 2):
return 1
# 递归公式 - 降低问题的求解难度
try:
return temp[num]
except KeyError:
temp[num] = fib(num - 1) + fib(num - 2)
return temp[num]
def fib2(total):
"""斐波拉切数列生成器"""
num1, num2 = 0, 1
for _ in range(total):
num1, num2 = num2, num1 + num2
yield num1
def main():
"""主函数"""
for num in fib2(120):
print(num)
if __name__ == '__main__':
main()

View File

@ -0,0 +1,145 @@
"""
程序设计的范式(理念)
1. 指令式程序设计 - 汇编语言
2. 面向过程程序设计 - 把一组指令封装成一个过程需要执行这组指令时调用这个过程即可 - C
3. 面向对象程序设计 - 将数据和操作数据的函数从逻辑上组织成了对象 - C++ / Java
4. 函数式程序设计 - 函数是一等对象(一等公民) - Haskell
面向对象程序设计步骤:
1. 定义类 - 抽象过程 - 数据抽象(静态特征-属性)/行为抽象(动态特征-方法)
2. 创建对象 - 构造器 - 初始化(__init__)
3. 给对象发消息 - 对象引用.对象方法(参数)
面向对象的三大支柱 - 封装 / 继承 / 多态
类与类(对象与对象)之间的关系:
1. is-a: 继承
2. has-a: 关联 / 聚合 / 合成
3. use-a: 依赖
面向对象的设计原则/SOLID原则:
1. 单一职责原则 - 类的设计要高内聚
2. 开闭原则 - 接受扩展不接受修改 - 抽象是关键/用继承封装可变性
3. 依赖倒转原则 - 面向抽象编程
4. 里氏替换原则 - 任何时候都可以使用子类型对象替换父类型对象
5. 接口隔离原则
6. 合成聚合复用原则 - 优先考虑用强关联而不是继承去复用代码
7. 最少知识原则(迪米特法则) - 不要跟陌生人讲话
GoF设计模式 - 23种场景(Python中有16中已经被弱化)
- 单例工厂原型适配器观察者策略
"""
from enum import Enum
from enum import unique
import random
# 经验: 符号常量优于字面常量
# 枚举类型是定义符号常量的最佳选择
# 如果一个变量的值只有有限多个选项那么最好使用枚举
@unique
class Suite(Enum):
"""花色"""
SPADE = 0
HEART = 1
CLUB = 2
DIAMOND = 3
class Card():
""""""
def __init__(self, suite, face):
self.suite = suite
self.face = face
def show(self):
"""显示牌的花色和点数"""
suites = ['♠️', '♥️', '♣️', '♦️']
faces = [
'', 'A', '2', '3', '4', '5', '6',
'7', '8', '9', '10', 'J', 'Q', 'K'
]
return f'{suites[self.suite.value]} {faces[self.face]}'
def __str__(self):
return self.show()
def __repr__(self):
return self.show()
class Poker():
"""扑克"""
def __init__(self):
self.index = 0
self.cards = [Card(suite, face)
for suite in Suite
for face in range(1, 14)]
def shuffle(self):
"""洗牌"""
random.shuffle(self.cards)
def deal(self):
"""发牌"""
temp = self.cards[self.index]
self.index += 1
return temp
@property
def has_more(self):
"""是否有牌可以发"""
return self.index < len(self.cards)
class Player():
"""玩家"""
def __init__(self, name):
self.name = name
self.cards = []
def get_one(self, card):
"""摸一张牌"""
self.cards.append(card)
def drop_one(self, index):
"""打出一张牌"""
return self.cards.remove(index)
def get_many(self, more_cards):
"""摸多张牌"""
self.cards += more_cards
def drop_cards(self):
"""扔掉所有牌"""
self.cards.clear()
def arrange(self):
"""整理手上的牌"""
self.cards.sort(key=lambda x: (x.suite.value, x.face))
def main():
"""主函数"""
poker = Poker()
poker.shuffle()
players = [
Player("东邪"), Player("西毒"),
Player("南帝"), Player("北丐")
]
for _ in range(3):
for player in players:
if poker.has_more:
player.get_one(poker.deal())
for player in players:
player.arrange()
print(player.name)
print(player.cards)
if __name__ == '__main__':
main()

View File

@ -0,0 +1,47 @@
"""
设计模式 - 策略模式(指定的策略不同执行的算法不同)
"""
from hashlib import md5
from hashlib import sha1
from hashlib import sha256
from hashlib import sha512
class StreamHasher():
"""哈希摘要生成器"""
def __init__(self, algorithm='md5', size=1024):
self.size = size
alg = algorithm.lower()
if alg == 'md5':
self.hasher = md5()
elif alg == 'sha1':
self.hasher = sha1()
elif alg == 'sha256':
self.hasher = sha256()
elif alg == 'sha512':
self.hasher = sha512()
else:
raise ValueError('不支持指定的摘要算法')
# 魔法方法: 让对象可以像函数一样被调用
def __call__(self, stream):
return self.to_digest(stream)
def to_digest(self, stream):
"""生成十六进制形式的哈希摘要字符串"""
for data in iter(lambda: stream.read(self.size), b''):
self.hasher.update(data)
return self.hasher.hexdigest()
def main():
"""主函数"""
hasher = StreamHasher('sha1', 4096)
with open('Python语言规范.pdf', 'rb') as stream:
# print(hasher.to_digest(stream))
print(hasher(stream))
if __name__ == '__main__':
main()

View File

@ -0,0 +1,81 @@
"""
抽象类 / 继承 / 多态
"""
from abc import ABCMeta, abstractmethod
class Employee(metaclass=ABCMeta):
"""员工"""
def __init__(self, name):
self.name = name
@abstractmethod
def get_salary(self):
"""结算月薪"""
pass
class Manager(Employee):
"""部门经理"""
def get_salary(self):
return 15000
class Programmer(Employee):
"""程序员"""
def __init__(self, name):
super().__init__(name)
self._working_hour = 0
@property
def working_hour(self):
return self._working_hour
@working_hour.setter
def working_hour(self, _working_hour):
self._working_hour = 0 if _working_hour < 0 \
else _working_hour
def get_salary(self):
return 200 * self.working_hour
class Salesman(Employee):
"""销售员"""
def __init__(self, name):
super().__init__(name)
self._sales = 0
@property
def sales(self):
return self._sales
@sales.setter
def sales(self, _sales):
self._sales = 0 if _sales < 0 else _sales
def get_salary(self):
return 1800 + 0.05 * self.sales
def main():
"""主函数"""
emps = [
Programmer("王大锤"), Manager("武则天"),
Programmer("狄仁杰"), Salesman("白洁"),
Programmer("白元芳"), Salesman("冷面")
]
for emp in emps:
if isinstance(emp, Programmer):
emp.working_hour = int(input(f'{emp.name}本月工作时间: '))
elif isinstance(emp, Salesman):
emp.sales = float(input(f'{emp.name}本月销售额: '))
print("%s本月工资为: ¥%.2f" % (emp.name, emp.get_salary()))
if __name__ == '__main__':
main()

View File

@ -0,0 +1,35 @@
"""
元类 - 设计模式 - 单例模式(让一个类只能创建唯一的实例)
"""
class SingletonMeta(type):
"""单例类的元类(描述其他类的类)"""
def __init__(cls, *args, **kwargs):
cls.__instance = None
def __call__(cls, *args, **kwargs):
if cls.__instance is None:
cls.__instance = super().__call__(*args, **kwargs)
return cls.__instance
class President(metaclass=SingletonMeta):
"""总统(单例类)"""
def __init__(self, name):
self.name = name
def main():
p1 = President("王大锤")
p2 = President("奥巴马")
print(p1.name)
print(p2.name)
print(p1 == p2)
print(p1 is p2)
if __name__ == '__main__':
main()

View File

@ -0,0 +1,46 @@
"""
设计模式 - 单例模式(让一个类只能创建唯一的实例)
"""
from functools import wraps
def singleton(cls):
instances = {}
@wraps(cls)
def wrapper(*args, **kwargs):
if cls not in instances:
instances[cls] = cls(*args, **kwargs)
return instances[cls]
return wrapper
@singleton
class President():
"""总统(单例类)"""
def __init__(self, name):
self.name = name
def main():
p1 = President("王大锤")
p2 = President("奥巴马")
print(p1.name)
print(p2.name)
print(p1 == p2)
print(p1 is p2)
print('-' * 30)
# 取消装饰器
President2 = President.__wrapped__
p2 = President2("奥巴马")
print(p1.name)
print(p2.name)
print(p1 == p2)
print(p1 is p2)
if __name__ == '__main__':
main()

View File

@ -0,0 +1,36 @@
"""
装饰器 - 背后的设计模式是代理模式(注意不是装饰器模式)
代理模式通常是让代理对象去执行被代理对象的行为并在这个过程中增加额外的操作
这种设计模式最适合处理代码中的横切关注功能(与正常业务没有必然联系但是又需要执行的功能)
"""
from functools import wraps
from time import time
def record(output=print):
def decorate(func):
@wraps(func)
def wrapper(*args, **kwargs):
start = time()
result = func(*args, **kwargs)
output(func.__name__, time() - start)
return result
return wrapper
return decorate
@record()
def some_task():
print(123 ** 100000)
if __name__ == '__main__':
some_task()
print(some_task.__name__)
# 取消装饰器
some_task = some_task.__wrapped__
some_task()

View File

@ -0,0 +1,40 @@
"""
混入 - Mix-in
限制字典只有在指定的key不存在时才能设置键值对
原则上能够不使用多重继承的地方都不要用多重继承
MRO - Method Resolution Order - 方法解析顺序
Python2 - 深度优先搜索
Python3 - 类似于广度优先搜索 - C3算法
.__mro__ / .mro()
"""
class SetOnceMappingMixin():
"""混入类"""
__slots__ = ()
def __setitem__(self, key, value):
if key in self:
raise KeyError(f'{str(key)}已经存在')
return super().__setitem__(key, value)
class SetOnceDict(SetOnceMappingMixin, dict):
"""自定义字典"""
pass
def main():
"""主函数"""
dict1 = SetOnceDict()
try:
dict1['username'] = 'jackfrued'
dict1['username'] = 'hellokitty'
dict1['username'] = 'wangdachui'
except KeyError as error:
print('Error:', error)
print(dict1)
if __name__ == '__main__':
main()

View File

@ -0,0 +1,36 @@
"""
自定义迭代器
"""
class Fibo:
"""斐波拉切数列迭代器"""
def __init__(self, num):
self.num = num
self.a, self.b = 0, 1
self.idx = 0
def __iter__(self):
return self
def __next__(self):
if self.idx < self.num:
self.a, self.b = self.b, self.a + self.b
self.idx += 1
return self.a
raise StopIteration()
def main():
"""主函数"""
for val in Fibo(10):
print(val)
print('-' * 10)
fibo_iter = Fibo(10)
for _ in range(10):
print(next(fibo_iter))
if __name__ == '__main__':
main()

View File

@ -0,0 +1,45 @@
"""
协程 - 可以通过yield来调用其它协程yield将执行权转让给其他协程
协程之间不是调用者与被调用者的关系而是彼此对称平等的
"""
def num_generator(start, end):
"""指定起始值的整数生成器"""
for num in range(start, end + 1):
yield num
def square_mapper(numbers):
"""将数值映射为其平方的协程"""
for num in numbers:
yield num ** 2
def prime_filter(numbers):
"""从数值中过滤出素数的协程"""
for num in numbers:
flag = True
for factor in range(2, int(num ** 0.5 + 1)):
if num % factor == 0:
flag = False
break
if flag:
yield num
def main():
tasks = []
tasks.append(square_mapper(num_generator(1, 100)))
tasks.append(prime_filter(num_generator(2, 100)))
for _ in range(100):
for task in tasks:
print(f'切换到任务{task.__name__} => ', end='')
try:
print(task.__next__())
except StopIteration as error:
print(error)
if __name__ == '__main__':
main()

View File

@ -0,0 +1,53 @@
"""
魔术方法 - 哈希存储 / 上下文语法
"""
from random import randint
class Student():
"""学生"""
def __init__(self, stuid, name, gender):
self.stuid = stuid
self.name = name
self.gender = gender
def __enter__(self):
return self
def __exit__(self, exception_type, exception_value, traceback):
pass
def __hash__(self):
return hash(self.stuid)
def __eq__(self, other):
return self.stuid == other.stuid
def __repr__(self):
return f'{self.stuid}: {self.name}'
def create_student():
return Student(randint(1001, 9999),
"无名氏",
"" if randint(0, 1) == 1 else "")
def main():
"""主函数"""
students = {
Student(1001, "王大锤", ""),
Student(1001, "王小锤", ""),
Student(1003, "王捶捶", "")
}
print(len(students))
print(students)
with create_student() as stu:
print(stu.stuid)
print(stu.name)
print(stu.gender)
if __name__ == '__main__':
main()

View File

@ -82,14 +82,12 @@ Linux内核是芬兰人Linus Torvalds开发的于1991年9月发布。而Linux
Linux系统的命令通常都是如下所示的格式
```Shell
命令名称 [命名参数] [命令对象]
```
1. 获取登录信息 - **w** / **who** / **last**
```Shell
[root@izwz97tbgo9lkabnat2lo8z ~]# w
23:31:16 up 12:16, 2 users, load average: 0.00, 0.01, 0.05
USER TTY FROM LOGIN@ IDLE JCPU PCPU WHAT
@ -107,7 +105,6 @@ Linux系统的命令通常都是如下所示的格式
Shell也被称为“壳”它是用户与内核交流的翻译官简单的说就是人与计算机交互的接口。目前很多Linux系统默认的Shell都是bash<u>B</u>ourne <u>A</u>gain <u>SH</u>ell因为它可以使用Tab键进行命令补全、可以保存历史命令、可以方便的配置环境变量以及执行批处理操作等。
```Shell
[root@izwz97tbgo9lkabnat2lo8z ~]# ps
PID TTY TIME CMD
3531 pts/0 00:00:00 bash
@ -117,7 +114,6 @@ Linux系统的命令通常都是如下所示的格式
3. 查看命令的说明 - **whatis**
```Shell
[root@izwz97tbgo9lkabnat2lo8z ~]# whatis ps
ps (1) - report a snapshot of the current processes.
[root@izwz97tbgo9lkabnat2lo8z ~]# whatis python
@ -127,7 +123,6 @@ Linux系统的命令通常都是如下所示的格式
4. 查看命令的位置 - **which** / **whereis**
```Shell
[root@izwz97tbgo9lkabnat2lo8z ~]# whereis ps
ps: /usr/bin/ps /usr/share/man/man1/ps.1.gz
[root@izwz97tbgo9lkabnat2lo8z ~]# whereis python
@ -140,7 +135,6 @@ Linux系统的命令通常都是如下所示的格式
5. 查看帮助文档 - **man** / **info** / **apropos**
```Shell
[root@izwz97tbgo9lkabnat2lo8z ~]# ps --help
Usage:
ps [options]
@ -163,7 +157,6 @@ Linux系统的命令通常都是如下所示的格式
6. 切换用户 - **su**
```Shell
[root@izwz97tbgo9lkabnat2lo8z ~]# su hellokitty
[hellokitty@izwz97tbgo9lkabnat2lo8z root]$
```
@ -171,7 +164,6 @@ Linux系统的命令通常都是如下所示的格式
7. 以管理员身份执行命令 - **sudo**
```Shell
[jackfrued@izwz97tbgo9lkabnat2lo8z ~]$ ls /root
ls: cannot open directory /root: Permission denied
[jackfrued@izwz97tbgo9lkabnat2lo8z ~]$ sudo ls /root
@ -184,7 +176,6 @@ Linux系统的命令通常都是如下所示的格式
8. 登入登出相关 - **logout** / **exit** / **adduser** / **userdel** / **passwd** / **ssh**
```Shell
[root@izwz97tbgo9lkabnat2lo8z ~]# adduser hellokitty
[root@izwz97tbgo9lkabnat2lo8z ~]# passwd hellokitty
Changing password for user jackfrued.
@ -202,7 +193,6 @@ Linux系统的命令通常都是如下所示的格式
9. 查看系统和主机名 - **uname** / **hostname**
```Shell
[root@izwz97tbgo9lkabnat2lo8z ~]# uname
Linux
[root@izwz97tbgo9lkabnat2lo8z ~]# hostname
@ -216,7 +206,6 @@ Linux系统的命令通常都是如下所示的格式
11. 查看历史命令 - **history**
```Shell
[root@iZwz97tbgo9lkabnat2lo8Z ~]# history
...
452 ls
@ -235,7 +224,6 @@ Linux系统的命令通常都是如下所示的格式
1. 创建/删除目录 - **mkdir** / **rmdir**
```Shell
[root@iZwz97tbgo9lkabnat2lo8Z ~]# mkdir abc
[root@iZwz97tbgo9lkabnat2lo8Z ~]# mkdir -p xyz/abc
[root@iZwz97tbgo9lkabnat2lo8Z ~]# rmdir abc
@ -244,7 +232,6 @@ Linux系统的命令通常都是如下所示的格式
2. 创建/删除文件 - **touch** / **rm**
```Shell
[root@iZwz97tbgo9lkabnat2lo8Z ~]# touch readme.txt
[root@iZwz97tbgo9lkabnat2lo8Z ~]# touch error.txt
[root@iZwz97tbgo9lkabnat2lo8Z ~]# rm error.txt
@ -276,7 +263,6 @@ Linux系统的命令通常都是如下所示的格式
5. 查看文件内容 - **cat** / **head** / **tail** / **more** / **less**
```Shell
[root@iZwz97tbgo9lkabnat2lo8Z ~]# wget http://www.sohu.com/ -O sohu.html
--2018-06-20 18:42:34-- http://www.sohu.com/
Resolving www.sohu.com (www.sohu.com)... 14.18.240.6
@ -310,7 +296,6 @@ Linux系统的命令通常都是如下所示的格式
6. 拷贝/移动文件 - **cp** / **mv**
```Shell
[root@iZwz97tbgo9lkabnat2lo8Z ~]# mkdir backup
[root@iZwz97tbgo9lkabnat2lo8Z ~]# cp sohu.html backup/
[root@iZwz97tbgo9lkabnat2lo8Z ~]# cd backup
@ -324,7 +309,6 @@ Linux系统的命令通常都是如下所示的格式
7. 查找文件和查找内容 - **find** / **grep**
```Shell
[root@iZwz97tbgo9lkabnat2lo8Z ~]# find / -name "*.html"
/root/sohu.html
/root/backup/sohu_index.html
@ -348,7 +332,6 @@ Linux系统的命令通常都是如下所示的格式
8. 链接 - **ln**
```Shell
[root@iZwz97tbgo9lkabnat2lo8Z ~]# ls -l sohu.html
-rw-r--r-- 1 root root 212131 Jun 20 19:15 sohu.html
[root@iZwz97tbgo9lkabnat2lo8Z ~]# ln /root/sohu.html /root/backup/sohu_backup
@ -371,7 +354,6 @@ Linux系统的命令通常都是如下所示的格式
9. 压缩/解压缩和归档/解归档 - **gzip** / **gunzip** / **xz** / **tar**
```Shell
[root@iZwz97tbgo9lkabnat2lo8Z ~]# wget http://download.redis.io/releases/redis-4.0.10.tar.gz
--2018-06-20 19:29:59-- http://download.redis.io/releases/redis-4.0.10.tar.gz
Resolving download.redis.io (download.redis.io)... 109.74.203.151
@ -412,7 +394,6 @@ Linux系统的命令通常都是如下所示的格式
10. 其他工具 - **sort** / **uniq** / **diff** / **tr** / **cut** / **paste** / **file** / **wc**
```Shell
[root@iZwz97tbgo9lkabnat2lo8Z ~]# cat foo.txt
grape
apple
@ -461,7 +442,6 @@ Linux系统的命令通常都是如下所示的格式
例子:查找当前目录下文件个数。
```Shell
[root@iZwz97tbgo9lkabnat2lo8Z ~]# find ./ | wc -l
6152
```
@ -469,7 +449,6 @@ Linux系统的命令通常都是如下所示的格式
例子:列出当前路径下的文件和文件夹,给每一项加一个编号。
```Shell
[root@iZwz97tbgo9lkabnat2lo8Z ~]# ls | cat -n
1 dump.rdb
2 mongodb-3.6.5
@ -481,14 +460,12 @@ Linux系统的命令通常都是如下所示的格式
例子查找record.log中包含AAA但不包含BBB的记录的总数
```Shell
[root@iZwz97tbgo9lkabnat2lo8Z ~]# cat record.log | grep AAA | grep -v BBB | wc -l
```
2. 输出重定向和错误重定向 - **\>** / **>>** / **2\>**
```Shell
[root@iZwz97tbgo9lkabnat2lo8Z ~]# cat readme.txt
banana
apple
@ -511,7 +488,6 @@ Linux系统的命令通常都是如下所示的格式
3. 输入重定向 - **\<**。
```Shell
[root@iZwz97tbgo9lkabnat2lo8Z ~]# echo 'hello, world!' > hello.txt
[root@iZwz97tbgo9lkabnat2lo8Z ~]# wall < hello.txt
[root@iZwz97tbgo9lkabnat2lo8Z ~]#
@ -530,7 +506,6 @@ Linux系统的命令通常都是如下所示的格式
1. **alias**
```Shell
[root@iZwz97tbgo9lkabnat2lo8Z ~]# alias ll='ls -l'
[root@iZwz97tbgo9lkabnat2lo8Z ~]# alias frm='rm -rf'
[root@iZwz97tbgo9lkabnat2lo8Z ~]# ll
@ -543,7 +518,6 @@ Linux系统的命令通常都是如下所示的格式
2. **unalias**
```Shell
[root@iZwz97tbgo9lkabnat2lo8Z ~]# unalias frm
[root@iZwz97tbgo9lkabnat2lo8Z ~]# frm sohu.html
-bash: frm: command not found
@ -554,7 +528,6 @@ Linux系统的命令通常都是如下所示的格式
1. 时间和日期 - **date** / **cal**
```Shell
[root@iZwz97tbgo9lkabnat2lo8Z ~]# date
Wed Jun 20 12:53:19 CST 2018
[root@iZwz97tbgo9lkabnat2lo8Z ~]# cal
@ -615,7 +588,6 @@ Linux系统的命令通常都是如下所示的格式
1. **chmod** - 改变文件模式比特。
```Shell
[root@iZwz97tbgo9lkabnat2lo8Z ~]# ls -l
...
-rw-r--r-- 1 root root 211878 Jun 19 16:06 sohu.html
@ -640,7 +612,6 @@ Linux系统的命令通常都是如下所示的格式
2. **chown** - 改变文件所有者。
```Shell
[root@iZwz97tbgo9lkabnat2lo8Z ~]# ls -l
...
-rw-r--r-- 1 root root 54 Jun 20 10:06 readme.txt
@ -657,7 +628,6 @@ Linux系统的命令通常都是如下所示的格式
1. 列出文件系统的磁盘使用状况 - **df**
```Shell
[root@iZwz97tbgo9lkabnat2lo8Z ~]# df -h
Filesystem Size Used Avail Use% Mounted on
/dev/vda1 40G 5.0G 33G 14% /
@ -671,7 +641,6 @@ Linux系统的命令通常都是如下所示的格式
2. 磁盘分区表操作 - **fdisk**
```Shell
[root@iZwz97tbgo9lkabnat2lo8Z ~]# fdisk -l
Disk /dev/vda: 42.9 GB, 42949672960 bytes, 83886080 sectors
Units = sectors of 1 * 512 = 512 bytes
@ -698,7 +667,6 @@ Linux系统的命令通常都是如下所示的格式
1. 启动vim。可以通过`vi`或`vim`命令来启动vim启动时可以指定文件名来打开一个文件如果没有指定文件名也可以在保存的时候指定文件名。
```Shell
[root@iZwz97tbgo9lkabnat2lo8Z ~]# vim guess.py
```
@ -747,7 +715,6 @@ Linux系统的命令通常都是如下所示的格式
- 比较多个文件。
```Shell
[root@iZwz97tbgo9lkabnat2lo8Z ~]# vim -d foo.txt bar.txt
```
![](./res/vim-diff.png)
@ -755,7 +722,6 @@ Linux系统的命令通常都是如下所示的格式
- 打开多个文件。
```Shell
[root@iZwz97tbgo9lkabnat2lo8Z ~]# vim foo.txt bar.txt hello.txt
```
@ -812,7 +778,6 @@ Linux系统的命令通常都是如下所示的格式
下面以Nginx为例演示如何使用yum安装软件。
```Shell
[root@iZwz97tbgo9lkabnat2lo8Z ~]# yum -y install nginx
...
Installed:
@ -851,7 +816,6 @@ nginx version: nginx/1.12.2
移除Nginx。
```Shell
[root@iZwz97tbgo9lkabnat2lo8Z ~]# nginx -s stop
[root@iZwz97tbgo9lkabnat2lo8Z ~]# yum -y remove nginx
```
@ -859,7 +823,6 @@ nginx version: nginx/1.12.2
下面以MySQL为例演示如何使用rpm安装软件。要安装MySQL需要先到[MySQL官方网站](https://www.mysql.com/)下载对应的[RPM文件](https://dev.mysql.com/downloads/mysql/)当然要选择和你使用的Linux系统对应的版本。MySQL现在是Oracle公司旗下的产品在MySQL被收购后MySQL的作者重新制作了一个MySQL的分支MariaDB可以通过yum进行安装。如果要安装MySQL需要先通过yum删除`mariadb-libs`这个可能会跟MySQL底层库冲突的库然后还需要安装一个名为`libaio`的依赖库。
```Shell
[root@iZwz97tbgo9lkabnat2lo8Z mysql]# ls
mysql-community-client-5.7.22-1.el7.x86_64.rpm
mysql-community-common-5.7.22-1.el7.x86_64.rpm
@ -878,7 +841,6 @@ Preparing... ################################# [100%]
移除安装的MySQL。
```Shell
[root@iZwz97tbgo9lkabnat2lo8Z ~]# rpm -qa | grep mysql | xargs rpm -e
```
@ -887,7 +849,6 @@ Preparing... ################################# [100%]
下面以安装MongoDB为例演示这类软件应该如何安装。
```Shell
[root@iZwz97tbgo9lkabnat2lo8Z ~]# wget https://fastdl.mongodb.org/linux/mongodb-linux-x86_64-rhel70-3.6.5.tgz
--2018-06-21 18:32:53-- https://fastdl.mongodb.org/linux/mongodb-linux-x86_64-rhel70-3.6.5.tgz
Resolving fastdl.mongodb.org (fastdl.mongodb.org)... 52.85.83.16, 52.85.83.228, 52.85.83.186, ...
@ -952,7 +913,6 @@ build environment:
1. 安装Python 3.6。
```Shell
[root@iZwz97tbgo9lkabnat2lo8Z ~]# yum install gcc
[root@iZwz97tbgo9lkabnat2lo8Z ~]# wget https://www.python.org/ftp/python/3.6.5/Python-3.6.5.tgz
[root@iZwz97tbgo9lkabnat2lo8Z ~]# gunzip Python-3.6.5.tgz
@ -972,7 +932,6 @@ build environment:
2. 安装Redis-3.2.12。
```Shell
[root@iZwz97tbgo9lkabnat2lo8Z ~]# wget http://download.redis.io/releases/redis-3.2.12.tar.gz
[root@iZwz97tbgo9lkabnat2lo8Z ~]# gunzip redis-3.2.12.tar.gz
[root@iZwz97tbgo9lkabnat2lo8Z ~]# tar -xvf redis-3.2.12.tar
@ -989,35 +948,30 @@ build environment:
1. 启动服务。
```Shell
[root@iZwz97tbgo9lkabnat2lo8Z ~]# systemctl start firewalld
```
2. 终止服务。
```Shell
[root@iZwz97tbgo9lkabnat2lo8Z ~]# systemctl stop firewalld
```
3. 重启服务。
```Shell
[root@iZwz97tbgo9lkabnat2lo8Z ~]# systemctl restart firewalld
```
4. 查看服务。
```Shell
[root@iZwz97tbgo9lkabnat2lo8Z ~]# systemctl status firewalld
```
5. 设置是否开机自启。
```Shell
[root@iZwz97tbgo9lkabnat2lo8Z ~]# systemctl enable firewalld
Created symlink from /etc/systemd/system/dbus-org.fedoraproject.FirewallD1.service to /usr/lib/systemd/system/firewalld.service.
Created symlink from /etc/systemd/system/multi-user.target.wants/firewalld.service to /usr/lib/systemd/system/firewalld.service.
@ -1031,7 +985,6 @@ build environment:
1. **crontab**命令。
```Shell
[root@iZwz97tbgo9lkabnat2lo8Z ~]# crontab -e
* * * * * echo "hello, world!" >> /root/hello.txt
59 23 * * * rm -f /root/*.log
@ -1041,7 +994,6 @@ build environment:
2. crontab相关文件。
```Shell
[root@iZwz97tbgo9lkabnat2lo8Z ~]# cd /etc
[root@iZwz97tbgo9lkabnat2lo8Z etc]# ls -l | grep cron
-rw-------. 1 root root 541 Aug 3 2017 anacrontab
@ -1081,7 +1033,6 @@ build environment:
2. 显示/操作网络配置(旧) - **ifconfig**
```Shell
[root@iZwz97tbgo9lkabnat2lo8Z ~]# ifconfig eth0
eth0: flags=4163<UP,BROADCAST,RUNNING,MULTICAST> mtu 1500
inet 172.18.61.250 netmask 255.255.240.0 broadcast 172.18.63.255
@ -1095,7 +1046,6 @@ build environment:
3. 显示/操作网络配置(新) - **ip**
```Shell
[root@iZwz97tbgo9lkabnat2lo8Z ~]# ip address
1: lo: <LOOPBACK,UP,LOWER_UP> mtu 65536 qdisc noqueue state UNKNOWN qlen 1
link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00
@ -1110,7 +1060,6 @@ build environment:
4. 网络可达性检查 - **ping**
```Shell
[root@iZwz97tbgo9lkabnat2lo8Z ~]# ping www.baidu.com -c 3
PING www.a.shifen.com (220.181.111.188) 56(84) bytes of data.
64 bytes from 220.181.111.188 (220.181.111.188): icmp_seq=1 ttl=51 time=36.3 ms
@ -1124,21 +1073,18 @@ build environment:
5. 查看网络服务和端口 - **netstat**
```Shell
[root@iZwz97tbgo9lkabnat2lo8Z ~]# netstat -nap | grep nginx
```
6. 安全文件拷贝 - **scp**
```Shell
[root@iZwz97tbgo9lkabnat2lo8Z ~]# scp root@1.2.3.4:/root/guido.jpg hellokitty@4.3.2.1:/home/hellokitty/pic.jpg
```
7. 安全文件传输 - **sftp**
```Shell
[root@iZwz97tbgo9lkabnat2lo8Z ~]# sftp root@120.77.222.217
root@120.77.222.217's password:
Connected to 120.77.222.217.
@ -1168,7 +1114,6 @@ build environment:
1. **ps** - 查询进程。
```Shell
[root@iZwz97tbgo9lkabnat2lo8Z ~]# ps -ef
UID PID PPID C STIME TTY TIME CMD
root 1 0 0 Jun23 ? 00:00:05 /usr/lib/systemd/systemd --switched-root --system --deserialize 21
@ -1182,7 +1127,6 @@ build environment:
2. **kill** - 终止进程。
```Shell
[root@iZwz97tbgo9lkabnat2lo8Z ~]# kill 1234
[root@iZwz97tbgo9lkabnat2lo8Z ~]# kill -9 1234
```
@ -1190,7 +1134,6 @@ build environment:
例子用一条命令强制终止正在运行的Redis进程。
```Shell
ps -ef | grep redis | grep -v grep | awk '{print $2}' | xargs kill
```
@ -1200,7 +1143,6 @@ build environment:
- `&`
```Shell
[root@iZwz97tbgo9lkabnat2lo8Z ~]# mongod &
[root@iZwz97tbgo9lkabnat2lo8Z ~]# redis-server
...
@ -1211,7 +1153,6 @@ build environment:
4. **jobs** - 查询后台进程。
```Shell
[root@iZwz97tbgo9lkabnat2lo8Z ~]# jobs
[2] Running mongod &
[3]- Stopped cat
@ -1221,7 +1162,6 @@ build environment:
5. **bg** - 让进程在后台继续运行。
```Shell
[root@iZwz97tbgo9lkabnat2lo8Z ~]# bg %4
[4]+ redis-server &
[root@iZwz97tbgo9lkabnat2lo8Z ~]# jobs
@ -1233,7 +1173,6 @@ build environment:
6. **fg** - 将后台进程置于前台。
```Shell
[root@iZwz97tbgo9lkabnat2lo8Z ~]# fg %4
redis-server
^C5554:signal-handler (1530025281) Received SIGINT scheduling shutdown...
@ -1248,7 +1187,6 @@ build environment:
7. **top** - 进程监控。
```Shell
[root@iZwz97tbgo9lkabnat2lo8Z ~]# top
top - 23:04:23 up 3 days, 14:10, 1 user, load average: 0.00, 0.01, 0.05
Tasks: 65 total, 1 running, 64 sleeping, 0 stopped, 0 zombie
@ -1265,7 +1203,6 @@ build environment:
2. 查看内存使用情况 - **free**
```Shell
[root@iZwz97tbgo9lkabnat2lo8Z ~]# free
total used free shared buff/cache available
Mem: 1016168 323924 190452 356 501792 531800
@ -1275,7 +1212,6 @@ build environment:
3. 查看进程使用内存状况 - **pmap**
```Shell
[root@iZwz97tbgo9lkabnat2lo8Z ~]# ps
PID TTY TIME CMD
4581 pts/0 00:00:00 bash
@ -1295,7 +1231,6 @@ build environment:
4. 报告设备CPU和I/O统计信息 - **iostat**
```Shell
[root@iZwz97tbgo9lkabnat2lo8Z ~]# iostat
Linux 3.10.0-693.11.1.el7.x86_64 (iZwz97tbgo9lkabnat2lo8Z) 06/26/2018 _x86_64_ (1 CPU)
avg-cpu: %user %nice %system %iowait %steal %idle

View File

@ -0,0 +1,88 @@
-- 创建人力资源管理系统数据库
drop database if exists HRS;
create database HRS default charset utf8;
-- 切换数据库上下文环境
use HRS;
-- 删除表
drop table if exists TbEmp;
drop table if exists TbDept;
-- 创建部门表
create table TbDept
(
deptno tinyint primary key, -- 部门编号
dname varchar(10) not null, -- 部门名称
dloc varchar(20) not null -- 部门所在地
);
-- 添加部门记录
insert into TbDept values (10, '会计部', '北京');
insert into TbDept values (20, '研发部', '成都');
insert into TbDept values (30, '销售部', '重庆');
insert into TbDept values (40, '运维部', '深圳');
-- 创建员工表
create table TbEmp
(
empno int primary key, -- 员工编号
ename varchar(20) not null, -- 员工姓名
job varchar(20) not null, -- 员工职位
mgr int, -- 主管编号
sal int not null, -- 员工月薪
comm int, -- 每月补贴
dno tinyint -- 所在部门编号
);
-- 添加外键约束
alter table TbEmp add constraint fk_dno foreign key (dno) references TbDept(deptno);
-- 添加员工记录
insert into TbEmp values (7800, '张三丰', '总裁', null, 9000, 1200, 20);
insert into TbEmp values (2056, '乔峰', '分析师', 7800, 5000, 1500, 20);
insert into TbEmp values (3088, '李莫愁', '设计师', 2056, 3500, 800, 20);
insert into TbEmp values (3211, '张无忌', '程序员', 2056, 3200, null, 20);
insert into TbEmp values (3233, '丘处机', '程序员', 2056, 3400, null, 20);
insert into TbEmp values (3251, '张翠山', '程序员', 2056, 4000, null, 20);
insert into TbEmp values (5566, '宋远桥', '会计师', 7800, 4000, 1000, 10);
insert into TbEmp values (5234, '郭靖', '出纳', 5566, 2000, null, 10);
insert into TbEmp values (3344, '黄蓉', '销售主管', 7800, 3000, 800, 30);
insert into TbEmp values (1359, '胡一刀', '销售员', 3344, 1800, 200, 30);
insert into TbEmp values (4466, '苗人凤', '销售员', 3344, 2500, null, 30);
insert into TbEmp values (3244, '欧阳锋', '程序员', 3088, 3200, null, 20);
insert into TbEmp values (3577, '杨过', '会计', 5566, 2200, null, 10);
insert into TbEmp values (3588, '朱九真', '会计', 5566, 2500, null, 10);
-- 查询薪资最高的员工姓名和工资
-- 查询员工的姓名和年薪((月薪+补贴)*12)
-- 查询有员工的部门的编号和人数
-- 查询所有部门的名称和人数
-- 查询薪资最高的员工(Boss除外)的姓名和工资
-- 查询薪水超过平均薪水的员工的姓名和工资
-- 查询薪水超过其所在部门平均薪水的员工的姓名、部门编号和工资
-- 查询部门中薪水最高的人姓名、工资和所在部门名称
-- 查询主管的姓名和职位
-- 查询薪资排名4~6名的员工姓名和工资
use HRS;
drop procedure if exists sp_avg_sal_by_dept;
create procedure sp_avg_sal_by_dept(deptno integer, out avg_sal float)
begin
select avg(sal) into avg_sal from TbEmp where dno=deptno;
end;
call sp_avg_sal_by_dept(10, @avgSal);
select @avgSal;

View File

@ -0,0 +1,251 @@
-- 创建SRS数据库
drop database if exists SRS;
create database SRS default charset utf8 collate utf8_bin;
-- 切换到SRS数据库
use SRS;
-- 创建学院表
create table tb_college
(
collid int not null auto_increment comment '学院编号',
collname varchar(50) not null comment '学院名称',
collmaster varchar(20) not null comment '院长姓名',
collweb varchar(511) default '' comment '学院网站',
primary key (collid)
);
-- 添加唯一约束
alter table tb_college add constraint uni_college_collname unique (collname);
-- 创建学生表
create table tb_student
(
stuid int not null comment '学号',
sname varchar(20) not null comment '学生姓名',
gender bit default 1 comment '性别',
birth date not null comment '出生日期',
addr varchar(255) default '' comment '籍贯',
collid int not null comment '所属学院编号',
primary key (stuid)
);
-- 添加外键约束
alter table tb_student add constraint fk_student_collid foreign key (collid) references tb_college (collid);
-- 创建教师表
create table tb_teacher
(
teaid int not null comment '教师工号',
tname varchar(20) not null comment '教师姓名',
title varchar(10) default '' comment '职称',
collid int not null comment '所属学院编号'
);
-- 添加主键约束
alter table tb_teacher add constraint pk_teacher primary key (teaid);
-- 添加外键约束
alter table tb_teacher add constraint fk_teacher_collid foreign key (collid) references tb_college (collid);
-- 创建课程表
create table tb_course
(
couid int not null comment '课程编号',
cname varchar(50) not null comment '课程名称',
credit tinyint not null comment '学分',
teaid int not null comment '教师工号',
primary key (couid)
);
-- 添加外键约束
alter table tb_course add constraint fk_course_tid foreign key (teaid) references tb_teacher (teaid);
-- 创建学生选课表
create table tb_score
(
scid int not null auto_increment comment '选课编号',
sid int not null comment '学号',
cid int not null comment '课程编号',
seldate date comment '选课时间日期',
mark decimal(4,1) comment '考试成绩',
primary key (scid)
);
-- 添加外键约束
alter table tb_score add constraint fk_score_sid foreign key (sid) references tb_student (stuid);
alter table tb_score add constraint fk_score_cid foreign key (cid) references tb_course (couid);
-- 添加唯一约束
alter table tb_score add constraint uni_score_sid_cid unique (sid, cid);
-- 插入学院数据
insert into tb_college (collname, collmaster, collweb) values
('计算机学院', '左冷禅', 'http://www.abc.com'),
('外国语学院', '岳不群', 'http://www.xyz.com'),
('经济管理学院', '风清扬', 'http://www.foo.com');
-- 插入学生数据
insert into tb_student (stuid, sname, gender, birth, addr, collid) values
(1001, '杨逍', 1, '1990-3-4', '四川成都', 1),
(1002, '任我行', 1, '1992-2-2', '湖南长沙', 1),
(1033, '王语嫣', 0, '1989-12-3', '四川成都', 1),
(1572, '岳不群', 1, '1993-7-19', '陕西咸阳', 1),
(1378, '纪嫣然', 0, '1995-8-12', '四川绵阳', 1),
(1954, '林平之', 1, '1994-9-20', '福建莆田', 1),
(2035, '东方不败', 1, '1988-6-30', null, 2),
(3011, '林震南', 1, '1985-12-12', '福建莆田', 3),
(3755, '项少龙', 1, '1993-1-25', null, 3),
(3923, '杨不悔', 0, '1985-4-17', '四川成都', 3);
-- 插入老师数据
insert into tb_teacher (teaid, tname, title, collid) values
(1122, '张三丰', '教授', 1),
(1133, '宋远桥', '副教授', 1),
(1144, '杨逍', '副教授', 1),
(2255, '范遥', '副教授', 2),
(3366, '韦一笑', '讲师', 3);
-- 插入课程数据
insert into tb_course (couid, cname, credit, teaid) values
(1111, 'Python程序设计', 3, 1122),
(2222, 'Web前端开发', 2, 1122),
(3333, '操作系统', 4, 1122),
(4444, '计算机网络', 2, 1133),
(5555, '编译原理', 4, 1144),
(6666, '算法和数据结构', 3, 1144),
(7777, '经贸法语', 3, 2255),
(8888, '成本会计', 2, 3366),
(9999, '审计学', 3, 3366);
-- 插入选课数据
insert into tb_score (sid, cid, seldate, mark) values
(1001, 1111, '2017-09-01', 95),
(1001, 2222, '2017-09-01', 87.5),
(1001, 3333, '2017-09-01', 100),
(1001, 4444, '2018-09-03', null),
(1001, 6666, '2017-09-02', 100),
(1002, 1111, '2017-09-03', 65),
(1002, 5555, '2017-09-01', 42),
(1033, 1111, '2017-09-03', 92.5),
(1033, 4444, '2017-09-01', 78),
(1033, 5555, '2017-09-01', 82.5),
(1572, 1111, '2017-09-02', 78),
(1378, 1111, '2017-09-05', 82),
(1378, 7777, '2017-09-02', 65.5),
(2035, 7777, '2018-09-03', 88),
(2035, 9999, date(now()), null),
(3755, 1111, date(now()), null),
(3755, 8888, date(now()), null),
(3755, 9999, '2017-09-01', 92);
-- 查询所有学生信息
select * from tb_student;
-- 查询所有课程名称及学分(投影和别名)
select cname as , credit as from tb_course;
-- 查询所有女学生的姓名和出生日期(筛选)
select sname as , birth as from tb_student where gender=0;
-- 查询所有80后学生的姓名、性别和出生日期(筛选)
select sname, gender, birth from tb_student where birth between '1980-1-1' and '1989-12-31';
-- 查询姓”杨“的学生姓名和性别(模糊)
select sname, gender from tb_student where sname like '杨%';
-- 查询姓”杨“名字两个字的学生姓名和性别(模糊)
select sname, gender from tb_student where sname like '杨_';
-- 查询姓”杨“名字三个字的学生姓名和性别(模糊)
select sname, gender from tb_student where sname like '杨__';
-- 查询名字中有”不“字或“嫣”字的学生的姓名(模糊)
select sname from tb_student where sname like '%不%' or sname like '%嫣%';
-- 查询没有录入家庭住址的学生姓名(空值)
select sname from tb_student where addr is null or addr='';
-- 查询录入了家庭住址的学生姓名(空值)
select sname from tb_student where addr is not null and addr<>'';
-- 查询学生选课的所有日期(去重)
select distinct seldate from tb_score;
-- 查询学生的家庭住址(去重)
select distinct addr from tb_student where addr is not null and addr<>'';
-- 查询男学生的姓名和生日按年龄从大到小排列(排序)
select sname, birth from tb_student where gender=1 order by birth asc;
-- max() / min() / sum() / avg() / count()
-- 查询年龄最大的学生的出生日期(聚合函数)
select min(birth) from tb_student;
-- 查询年龄最小的学生的出生日期(聚合函数)
select max(birth) from tb_student;
-- 查询男女学生的人数(分组和聚合函数)
select if(gender, '', '') as , count(gender) as
from tb_student group by gender;
-- 查询课程编号为1111的课程的平均成绩(筛选和聚合函数)
select avg(mark) as from tb_score where cid=1111;
-- 查询学号为1001的学生所有课程的平均分(筛选和聚合函数)
select avg(mark) as from tb_score where sid=1001;
-- 查询每个学生的学号和平均成绩(分组和聚合函数)
select sid, avg(mark) from tb_score where mark is not null group by sid;
-- 查询平均成绩大于等于90分的学生的学号和平均成绩
select sid, avg(mark) from tb_score group by sid having avg(mark)>=90;
-- 子查询 - 在一个查询中又使用到了另外一个查询的结果
-- 查询年龄最大的学生的姓名(子查询)
select sname from tb_student where birth=(select min(birth) from tb_student);
-- 查询年龄最大的学生姓名和年龄(子查询+运算)
select sname as , year(now()) - year(birth) as
from tb_student where birth=(select min(birth) from tb_student);
-- 查询选了两门以上的课程的学生姓名(子查询/分组条件/集合运算)
select sname from tb_student where stuid in (
select sid from tb_score group by sid having count(sid)>2);
-- 连接查询(联结查询/联接查询)
-- 查询学生姓名、课程名称以及成绩
select sname, cname, mark
from tb_score t1, tb_student t2, tb_course t3
where t2.stuid=t1.sid and t3.couid=t1.cid and mark is not null;
select sname, cname, mark from tb_student t1
inner join tb_score t2 on t1.stuid=t2.sid
inner join tb_course t3 on t3.couid=t2.cid
where mark is not null;
-- 查询选课学生的姓名和平均成绩(子查询和连接查询)
select sname, avgmark from tb_student t1,
(select sid, avg(mark) as avgmark from tb_score group by sid) t2
where stuid=sid;
select sname, avgmark from tb_student inner join
(select sid, avg(mark) as avgmark from tb_score group by sid) t2
on stuid=sid;
-- 注意:在连接查询时如果没有给出连接条件就会形成笛卡尔积
-- 查询每个学生的姓名和选课数量(左外连接和子查询)
-- 左外连接 - 把左表(写在前面的表)不满足连接条件的记录也查出来对应记录补null值
-- 右外连接 - 把右表(写在后面的表)不满足连接条件的记录也查出来对应记录补null值
select sname, total from tb_student left join
(select sid, count(sid) as total from tb_score group by sid) tb_temp
on stuid=sid;
-- DDL (Data Definition Language)
-- DML (Data Manipulation Language)
-- DCL (Data Control Language)
-- 创建名为hellokitty的用户并设置口令
create user 'hellokitty'@'%' identified by '123123';
-- 授权
grant select on srs.* to 'hellokitty'@'%';
grant insert, delete, update on srs.* to 'hellokitty'@'%';
grant create, drop, alter on srs.* to 'hellokitty'@'%';
grant all privileges on srs.* to 'hellokitty'@'%';
grant all privileges on srs.* to 'hellokitty'@'%' with grant option;
-- 召回
revoke all privileges on srs.* from 'hellokitty'@'%';
-- 事务控制
-- 开启事务环境
begin;
-- start transaction;
update tb_score set mark=mark-2 where sid=1001 and mark is not null;
update tb_score set mark=mark+2 where sid=1002 and mark is not null;
-- 事务提交
commit;
-- 事务回滚
rollback;
begin;
delete from tb_score;
rollback;

View File

@ -0,0 +1,15 @@
drop database if exists Bank;
create database Bank default charset utf8;
use Bank;
create table TbAccount
(
accid char(8) primary key,
accowner varchar(20) not null,
accbalance float not null default 0
);
insert into TbAccount values (11223344, '王大锤', 1000);
insert into TbAccount values (22334455, '李小龙', 1000);

View File

@ -0,0 +1,27 @@
drop database if exists demo;
create database demo default charset utf8 collate utf8_general_ci;
use demo;
create table tb_teacher
(
teacherid int not null auto_increment,
tname varchar(20) not null,
tjob varchar(20) not null,
tintro varchar(1023) default '',
tmotto varchar(255) default '',
primary key (teacherid)
);
insert into tb_teacher (tname, tjob, tintro, tmotto) values
('骆昊', 'Python教学主管', '10年以上软硬件产品和系统设计、研发、架构和管理经验2003年毕业于四川大学四川大学Java技术俱乐部创始人四川省优秀大学毕业生在四川省网络通信技术重点实验室工作期间参与了2项国家自然科学基金项目、1项中国科学院中长期研究项目和多项四川省科技攻关项目在国际会议和国内顶级期刊上发表多篇论文1篇被SCI收录3篇被EI收录大规模网络性能测量系统DMC-TS的设计者和开发者perf-TTCN语言的发明者。国内最大程序员社区CSDN的博客专家在Github上参与和维护了多个高质量开源项目精通C/C++、Java、Python、R、Swift、JavaScript等编程语言擅长OOAD、系统架构、算法设计、协议分析和网络测量主持和参与过电子政务系统、KPI考核系统、P2P借贷平台等产品的研发一直践行“用知识创造快乐”的教学理念善于总结乐于分享。', '教育是让受教育者体会用知识创造快乐的过程'),
('肖世荣', 'Python高级讲师', '10年以上互联网和移动互联网产品设计、研发、技术架构和项目管理经验曾在中国移动、symbio、ajinga.com、万达信息等公司担任架构师、项目经理、技术总监等职务长期为苹果、保时捷、耐克、沃尔玛等国际客户以及国内的政府机构提供信息化服务主导的项目曾获得“世界科技先锋”称号个人作品“许愿吧”曾在腾讯应用市场生活类App排名前3拥有百万级用户群体运营的公众号“卵石坊”是国内知名的智能穿戴设备平台。精通Python、C++、Java、Ruby、JavaScript等开发语言主导和参与了20多个企业级项目含国家级重大项目和互联网创新项目涉及的领域包括政务、社交、电信、卫生和金融有极为丰富的项目实战经验。授课深入浅出、条理清晰善于调动学员的学习热情并帮助学员理清思路和方法。', '世上没有绝望的处境,只有对处境绝望的人'),
('余婷', 'Python高级讲师', '5年以上移动互联网项目开发经验和教学经验曾担任上市游戏公司高级软件研发工程师和移动端iOS技术负责人参了多个企业级应用和游戏类应用的移动端开发和后台服务器开发拥有丰富的开发经验和项目管理经验以个人开发者和协作开发者的身份在苹果的AppStore上发布过多款App。精通Python、C、Objective-C、Swift等开发语言熟悉iOS原生App开发、RESTful接口设计以及基于Cocos2d-x的游戏开发。授课条理清晰、细致入微性格活泼开朗、有较强的亲和力教学过程注重理论和实践的结合在学员中有良好的口碑。', '每天叫醒你的不是闹钟而是梦想'),
('王海飞', 'Python高级讲师', '5年以上Python开发经验先后参与了O2O商城、CRM系统、CMS平台、ERP系统等项目的设计与研发曾在全国最大最专业的汽车领域相关服务网站担任Python高级研发工程师、项目经理等职务擅长基于Python、Java、PHP等开发语言的企业级应用开发全程参与了多个企业级应用从需求到上线所涉及的各种工作精通Django、Flask等框架熟悉基于微服务的企业级项目开发拥有丰富的项目实战经验。善于用浅显易懂的方式在课堂上传授知识点在授课过程中经常穿插企业开发的实际案例并分析其中的重点和难点通过这种互动性极强的教学模式帮助学员找到解决问题的办法并提升学员的综合素质。', '不要给我说什么底层原理、框架内核!老夫敲代码就是一把梭!复制!黏贴!拿起键盘就是干!'),
('何翰宇', 'JavaEE高级讲师', '5年以上JavaEE项目开发和教学经验参与过人力资源管理系统、电子教育产品在线商城、平安好医生App、平安好车主App等项目的设计与研发。擅长Java语言、面向对象编程、JavaEE框架、Web前端开发、数据库编程和Android应用开发对新技术有着浓厚的兴趣和钻研精神对微服务架构、虚拟化技术、区块链、边缘计算等领域都有自己独到的认识和见解有丰富的项目经验和教学经验。授课时注重学习方法的引导提倡以项目为导向的实战型教学同时也注重基础知识的掌握和底层原理的理解课堂氛围轻松幽默能够把枯燥乏味的知识变成生动有趣的案例帮助学员更快更好的掌握技术的要领从事JavaEE教学工作以来获得了学生潮水般的好评。', '每天撸代码,生活乐无边!'),
('吴明富', 'HTML5教学主管', '毕业于西南交通大学高级软件研发工程师10年以上的开发和培训经验。曾就职于华为赛门铁克科技有限公司负责公司内部ERP系统的研发参与和主导过多个大型门户网站、电子商务网站、电子政务系统以及多个企业级Web项目的设计和开发同时负责过多门企业内训课程的研发与讲授有着非常丰富的JavaEE项目开发经验和Web前端开发经验精通C/C++、Java、PHP、JavaScript等开发语言能够使用多种技术进行全栈开发。授课经验丰富、思路清晰、富有激情对知识点的讲解由浅入深、深入浅出能够通过实际开发的场景引导学员思考业务并理解相关技术善于将多年的项目实战经验和企业内训经验融入课堂通过理论联系实际的方式帮助学员迅速提升就业能力。', '人生的道路在态度的岔口一分为二');

View File

@ -0,0 +1,88 @@
-- 创建人力资源管理系统数据库
drop database if exists HRS;
create database HRS default charset utf8;
-- 切换数据库上下文环境
use HRS;
-- 删除表
drop table if exists TbEmp;
drop table if exists TbDept;
-- 创建部门表
create table TbDept
(
deptno tinyint primary key, -- 部门编号
dname varchar(10) not null, -- 部门名称
dloc varchar(20) not null -- 部门所在地
);
-- 添加部门记录
insert into TbDept values (10, '会计部', '北京');
insert into TbDept values (20, '研发部', '成都');
insert into TbDept values (30, '销售部', '重庆');
insert into TbDept values (40, '运维部', '深圳');
-- 创建员工表
create table TbEmp
(
empno int primary key, -- 员工编号
ename varchar(20) not null, -- 员工姓名
job varchar(20) not null, -- 员工职位
mgr int, -- 主管编号
sal int not null, -- 员工月薪
comm int, -- 每月补贴
dno tinyint -- 所在部门编号
);
-- 添加外键约束
alter table TbEmp add constraint fk_dno foreign key (dno) references TbDept(deptno);
-- 添加员工记录
insert into TbEmp values (7800, '张三丰', '总裁', null, 9000, 1200, 20);
insert into TbEmp values (2056, '乔峰', '分析师', 7800, 5000, 1500, 20);
insert into TbEmp values (3088, '李莫愁', '设计师', 2056, 3500, 800, 20);
insert into TbEmp values (3211, '张无忌', '程序员', 2056, 3200, null, 20);
insert into TbEmp values (3233, '丘处机', '程序员', 2056, 3400, null, 20);
insert into TbEmp values (3251, '张翠山', '程序员', 2056, 4000, null, 20);
insert into TbEmp values (5566, '宋远桥', '会计师', 7800, 4000, 1000, 10);
insert into TbEmp values (5234, '郭靖', '出纳', 5566, 2000, null, 10);
insert into TbEmp values (3344, '黄蓉', '销售主管', 7800, 3000, 800, 30);
insert into TbEmp values (1359, '胡一刀', '销售员', 3344, 1800, 200, 30);
insert into TbEmp values (4466, '苗人凤', '销售员', 3344, 2500, null, 30);
insert into TbEmp values (3244, '欧阳锋', '程序员', 3088, 3200, null, 20);
insert into TbEmp values (3577, '杨过', '会计', 5566, 2200, null, 10);
insert into TbEmp values (3588, '朱九真', '会计', 5566, 2500, null, 10);
-- 查询薪资最高的员工姓名和工资
-- 查询员工的姓名和年薪((月薪+补贴)*12)
-- 查询有员工的部门的编号和人数
-- 查询所有部门的名称和人数
-- 查询薪资最高的员工(Boss除外)的姓名和工资
-- 查询薪水超过平均薪水的员工的姓名和工资
-- 查询薪水超过其所在部门平均薪水的员工的姓名、部门编号和工资
-- 查询部门中薪水最高的人姓名、工资和所在部门名称
-- 查询主管的姓名和职位
-- 查询薪资排名4~6名的员工姓名和工资
use HRS;
drop procedure if exists sp_avg_sal_by_dept;
create procedure sp_avg_sal_by_dept(deptno integer, out avg_sal float)
begin
select avg(sal) into avg_sal from TbEmp where dno=deptno;
end;
call sp_avg_sal_by_dept(10, @avgSal);
select @avgSal;

View File

@ -0,0 +1,31 @@
drop database if exists Library;
create database Library default charset utf8;
use Library;
create table TbBook
(
bookid integer primary key auto_increment,
title varchar(100) not null,
author varchar(50) not null,
publisher varchar(50) not null,
price float not null,
lendout bit default 0,
lenddate datetime,
lendcount integer default 0
);
insert into TbBook (title, author, publisher, price, lendcount) values ('Java核心技术(卷1)', '凯 S.霍斯特曼', '机械工业出版社', 98.2, 102);
insert into TbBook (title, author, publisher, price, lendcount) values ('Java编程思想', '埃史尔', '机械工业出版社', 86.4, 87);
insert into TbBook (title, author, publisher, price, lendcount) values ('深入理解Java虚拟机', '周志明', '机械工业出版社', 64.4, 32);
insert into TbBook (title, author, publisher, price, lendcount) values ('Effective Java中文版(第2版) ', '埃史尔', '机械工业出版社', 36.8, 200);
insert into TbBook (title, author, publisher, price, lendcount) values ('数据结构与算法分析:Java语言描述(原书第3版)', '马克·艾伦·维斯', '机械工业出版社', 51.0, 15);
insert into TbBook (title, author, publisher, price, lendcount) values ('Java 8实战', '厄马', '人民邮电出版社', 56.8, 25);
insert into TbBook (title, author, publisher, price, lendcount) values ('重构:改善既有代码的设计', '马丁·福勒', '人民邮电出版社', 53.1, 99);
insert into TbBook (title, author, publisher, price, lendcount) values ('代码大全(第2版)', '史蒂夫•迈克康奈尔', '电子工业出版社', 53.1, 99);
insert into TbBook (title, author, publisher, price, lendcount) values ('程序员修炼之道:从小工到专家', '亨特, 托马斯', '电子工业出版社', 45.4, 50);
insert into TbBook (title, author, publisher, price, lendcount) values ('代码整洁之道', '马丁', '人民邮电出版社', 45.4, 30);
insert into TbBook (title, author, publisher, price, lendcount) values ('设计模式 可复用面向对象软件的基础', 'Erich Gamma, Richard Helm', '机械工业出版社', 30.2, 77);
insert into TbBook (title, author, publisher, price, lendcount) values ('设计模式之禅(第2版)', '秦小波', '机械工业出版社', 70.4, 100);

View File

@ -0,0 +1,186 @@
-- 查看MySQL服务器所有数据库
show databases;
-- 删除SRS数据库
drop database if exists SRS;
-- 创建学生选课系统(SRS)数据库并指定默认字符集
create database SRS default charset utf8;
-- 切换至SRS数据库
use SRS;
-- 查看当前数据库中所有表
show tables;
-- 创建学生表
create table TbStudent
(
stuid integer not null,
stuname varchar(20) not null,
stusex bit default 1,
stubirth datetime not null,
stutel char(11),
stuaddr varchar(255),
stuphoto longblob,
primary key (stuid)
);
-- 修改学生表删除stutel列
alter table TbStudent drop column stutel;
-- 查看学生表结构
desc TbStudent;
-- 如果表TbCourse已经存在就删除它
drop table if exists TbCourse;
-- 创建课程表
create table TbCourse
(
cosid integer not null,
cosname varchar(50) not null,
coscredit tinyint not null,
cosintro varchar(255)
);
-- 给课程表指定主键
alter table TbCourse add constraint pk_course primary key (cosid);
-- 创建学生选课记录表
create table TbSC
(
scid integer primary key auto_increment,
sid integer not null,
cid integer,
scdate datetime not null,
score float
);
-- 给表TbSC添加外键约束
alter table TbSC add constraint fk_sid foreign key (sid) references TbStudent (stuid) on delete cascade on update cascade;
alter table TbSC add constraint fk_cid foreign key (cid) references TBCourse (cosid) on delete set null on update cascade;
-- 添加学生记录
insert into TbStudent values (1001, '张三丰', default, '1978-1-1', '成都市一环路西二段17号', null);
insert into TbStudent (stuid, stuname, stubirth) values (1002, '郭靖', '1980-2-2');
insert into TbStudent (stuid, stuname, stusex, stubirth, stuaddr) values (1003, '黄蓉', 0, '1982-3-3', '成都市二环路南四段123号');
insert into TbStudent values (1004, '张无忌', 1, '1990-4-4', null, null);
insert into TbStudent values
(1005, '丘处机', 1, '1983-5-5', '北京市海淀区宝盛北里西区28号', null),
(1006, '王处一', 1, '1985-6-6', '深圳市宝安区宝安大道5010号', null),
(1007, '刘处玄', 1, '1987-7-7', '郑州市金水区纬五路21号', null),
(1008, '孙不二', 0, '1989-8-8', '武汉市光谷大道61号', null),
(1009, '平一指', 1, '1992-9-9', '西安市雁塔区高新六路52号', null),
(1010, '老不死', 1, '1993-10-10', '广州市天河区元岗路310号', null),
(1011, '王大锤', 0, '1994-11-11', null, null),
(1012, '隔壁老王', 1, '1995-12-12', null, null),
(1013, '郭啸天', 1, '1977-10-25', null, null);
-- 删除学生记录
delete from TbStudent where stuid=1004;
-- 更新学生记录
update TbStudent set stubirth='1980-12-12', stuaddr='上海市宝山区同济支路199号' where stuid=1002;
-- 添加课程记录
insert into TbCourse values
(1111, 'C语言程序设计', 3, '大神级讲师授课需要抢座'),
(2222, 'Java程序设计', 3, null),
(3333, '数据库概论', 2, null),
(4444, '操作系统原理', 4, null);
-- 添加学生选课记录
insert into TbSC values
(default, 1001, 1111, '2016-9-1', 95),
(default, 1002, 1111, '2016-9-1', 94),
(default, 1001, 2222, now(), null),
(default, 1001, 3333, '2017-3-1', 85),
(default, 1001, 4444, now(), null),
(default, 1002, 4444, now(), null),
(default, 1003, 2222, now(), null),
(default, 1003, 3333, now(), null),
(default, 1005, 2222, now(), null),
(default, 1006, 1111, now(), null),
(default, 1006, 2222, '2017-3-1', 80),
(default, 1006, 3333, now(), null),
(default, 1006, 4444, now(), null),
(default, 1007, 1111, '2016-9-1', null),
(default, 1007, 3333, now(), null),
(default, 1007, 4444, now(), null),
(default, 1008, 2222, now(), null),
(default, 1010, 1111, now(), null);
-- 查询所有学生信息
select * from TbStudent;
-- 查询所有课程名称及学分(投影和别名)
select cosname as ``, coscredit as `` from TbCourse;
-- 查询所有女学生的姓名和出生日期(筛选)
select stuname, stubirth from TbStudent where stusex=0;
-- 查询所有80后学生的姓名、性别和出生日期(筛选)
select stuname as ``, if(stusex, '', '') as ``, stubirth as ``
from TbStudent where stubirth between '1980-1-1' and '1989-12-31';
-- 查询姓王的学生姓名和性别(模糊)
select stuname, stusex from TbStudent where stuname like '王%';
-- 查询姓郭名字总共两个字的学生的姓名(模糊)
select stuname from TbStudent where stuname like '郭_';
-- 查询姓郭名字总共三个字的学生的姓名(模糊)
select stuname from TbStudent where stuname like '郭__';
-- 查询名字中有王字的学生的姓名(模糊)
select stuname from TbStudent where stuname like '%王%';
-- 查询没有录入家庭住址和照片的学生姓名(多条件筛选和空值处理)
select stuname from TbStudent where stuaddr is null and stuphoto is null;
-- 查询学生选课的所有日期(去重)
select distinct scdate from TbSC;
-- 查询学生的姓名和生日按年龄从大到小排列(排序)
select stuname, stubirth from TbStudent order by stubirth;
-- 查询所有录入了家庭住址的男学生的姓名、出生日期和家庭住址按年龄从小到大排列(多条件筛选和排序)
select stuname, stubirth, stuaddr from TbStudent where stusex=1 and stuaddr is not null order by stubirth desc;
-- 查询年龄最大的学生的出生日期(聚合函数)
select min(stubirth) from TbStudent;
-- 查询年龄最小的学生的出生日期(聚合函数)
select max(stubirth) from TbStudent;
-- 查询男女学生的人数(分组和聚合函数)
select if(stusex, '', '') as ``, count(stusex) as `` from TbStudent group by stusex;
-- 查询课程编号为1111的课程的平均成绩(筛选和聚合函数)
select avg(score) as `` from TbSC where cid=1111;
-- 查询学号为1001的学生所有课程的总成绩(筛选和聚合函数)
select sum(score) as `` from TbSC where sid=1001;
-- 查询每个学生的学号和平均成绩, null值处理成0(分组和聚合函数)
select sid as ``, ifnull(avg(score), 0) as `` from TbSC group by sid;
-- 查询平均成绩大于等于90分的学生的学号和平均成绩
select sid as ``, avg(score) as `` from TbSC group by sid having avg(score)>=90;
-- 查询年龄最大的学生的姓名(子查询)
select stuname from TbStudent where stubirth=(select min(stubirth) from TbStudent);
-- 查询选了两门以上的课程的学生姓名(子查询/分组条件/集合运算)
select stuname from TbStudent where stuid in
(select sid from TbSC group by sid having count(sid)>2);
-- 查询选课学生的姓名和平均成绩(子查询和连接查询)
-- 写法1:
select stuname, avgscore from TbStudent t1 inner join
(select sid, avg(score) as avgscore from TbSC where score is not null group by sid) t2
on t1.stuid=t2.sid;
-- 写法2:
select stuname, avgscore from TbStudent t1,
(select sid, avg(score) as avgscore from TbSC where score is not null group by sid) t2
where t1.stuid=t2.sid;
-- 查询学生姓名、所选课程名称和成绩(连接查询)
-- 写法1:
select stuname, cosname, score from
TbStudent t1, TbCourse t2, TbSC t3
where t1.stuid=t3.sid and t2.cosid=t3.cid and t3.score is not null;
-- 写法2:
select stuname, cosname, score from TbStudent t1 inner join TbCourse t2
inner join (select sid, cid, score from TbSC where score is not null) t3
on t1.stuid=t3.sid and t2.cosid=t3.cid;
-- 查询每个学生的姓名和选课数量(左外连接和子查询)
select stuname as ``, ifnull(coscount, 0) as `` from TbStudent t1
left outer join (select sid, count(sid) as coscount from TbSC group by sid) t2
on t1.stuid=t2.sid;
-- 创建系统用户表(演示登录操作和SQL注入攻击)
create table TbUser
(
username varchar(20) primary key,
userpass varchar(20) not null
);
-- 插入用户数据
insert into TbUser values ('admin', 'admin');
insert into TbUser values ('hellokitty', '123123');
-- 创建根据学号查询课程平均成绩的存储过程
drop procedure if exists SpGetAvgScoreByStuId;
create procedure SpGetAvgScoreByStuId(stuId integer, out avgScore float)
begin
select avg(score) into avgScore from TbSC where sid=stuId;
end;
-- 调用上面的存储过程
-- set @stuId=1001;
call SpGetAvgScoreByStuId(1001, @avgScore);
select @avgScore as avgScore;

View File

@ -0,0 +1,30 @@
drop database if exists shiro;
create database shiro default charset utf8;
use shiro;
create table users (
id bigint auto_increment,
username varchar(100),
password varchar(100),
password_salt varchar(100),
constraint pk_users primary key(id)
) charset=utf8 ENGINE=InnoDB;
create unique index idx_users_username on users(username);
create table user_roles(
id bigint auto_increment,
username varchar(100),
role_name varchar(100),
constraint pk_user_roles primary key(id)
) charset=utf8 ENGINE=InnoDB;
create unique index idx_user_roles on user_roles(username, role_name);
create table roles_permissions(
id bigint auto_increment,
role_name varchar(100),
permission varchar(100),
constraint pk_roles_permissions primary key(id)
) charset=utf8 ENGINE=InnoDB;
create unique index idx_roles_permissions on roles_permissions(role_name, permission);
insert into users(username,password)values('zhang','123');

View File

@ -0,0 +1,46 @@
drop database if exists booksys;
create database booksys default charset utf8;
use booksys;
create table tb_book
(
bookid integer not null,
isbn char(13) not null,
bname varchar(100) not null,
price decimal(8,2) not null,
author varchar(100) not null,
publisher varchar(50) not null,
pubdate date,
intro varchar(500),
lended bit default 0,
counter integer default 0,
primary key (bookid)
);
create table tb_reader
(
readerid integer not null,
rname varchar(20) not null,
gender bit not null,
tel char(11) not null,
birth date,
regdate date not null,
available bit default 1,
primary key (readerid)
);
create table tb_record
(
recordid integer not null auto_increment,
bid integer not null,
rid integer not null,
lenddate datetime not null,
backdate datetime,
pulishment decimal(6,2),
primary key (recordid)
);
alter table tb_record add constraint fk_record_bid foreign key (bid) references tb_book (bookid) on update cascade;
alter table tb_record add constraint fk_record_rid foreign key (rid) references tb_reader (readerid) on update cascade;

View File

@ -0,0 +1,39 @@
drop database if exists mooc1706;
create database mooc1706 default charset utf8;
use mooc1706;
create table tb_course_catalog
(
catid integer not null auto_increment,
catname varchar(20) not null,
catparent integer,
primary key (catid)
);
alter table tb_course_catalog add constraint fk_catalog_parent
foreign key (catparent) references tb_course_catalog(catid)
on delete cascade
on update cascade;
insert into tb_course_catalog values (default, '前端开发', null);
insert into tb_course_catalog values (default, '后端开发', null);
insert into tb_course_catalog values (default, '移动开发', null);
insert into tb_course_catalog values (default, '数据库', null);
insert into tb_course_catalog values (default, '云计算&大数据', null);
insert into tb_course_catalog values (default, '运维&测试', null);
insert into tb_course_catalog values (default, 'UI设计', null);
insert into tb_course_catalog values (default, 'HTML/CSS', 1);
insert into tb_course_catalog values (default, 'JavaScript', 1);
insert into tb_course_catalog values (default, 'jQuery', 1);
insert into tb_course_catalog values (default, 'HTML5', 1);
insert into tb_course_catalog values (default, 'CSS3', 1);
insert into tb_course_catalog values (default, 'Node.js', 1);
insert into tb_course_catalog values (default, 'AngularJS', 1);
insert into tb_course_catalog values (default, 'Bootstrap', 1);
insert into tb_course_catalog values (default, 'React', 1);
insert into tb_course_catalog values (default, 'Sass/Less', 1);
insert into tb_course_catalog values (default, 'Vue.js', 1);
insert into tb_course_catalog values (default, 'WebApp', 1);

View File

@ -0,0 +1,54 @@
drop database if exists sharebike;
create database sharebike default charset utf8;
use sharebike;
create table tb_city
(
cityid integer not null auto_increment,
cityname varchar(20) not null,
primary key (cityid)
);
create table tb_user
(
userid integer not null auto_increment,
nickname varchar(50) not null,
tel char(11) not null,
cityid integer not null,
regdate date,
primary key (userid)
);
create table tb_bike
(
bikeid integer not null auto_increment,
statecode integer default 0,
broken bit default 0,
primary key (bikeid)
);
create table tb_record
(
recordid integer not null auto_increment,
userid integer not null,
bikeid integer not null,
begintime datetime not null,
endtime datetime,
payway integer,
cost float,
primary key (recordid)
);
alter table tb_record add constraint fk_record_userid foreign key (userid) references tb_user (userid);
alter table tb_record add constraint fk_record_bikeid foreign key (bikeid) references tb_bike (bikeid);
select cityname, total from (select cityid, count(cityid) as total from tb_user group by cityid) t1 inner join tb_city t2 on t1.cityid=t2.cityid;
select max(total) from (select userid, count(userid) as total from tb_record group by userid) t1
select nickname, cityname from (select userid, count(userid) as total from tb_record group by userid having total=(select max(total) from (select userid, count(userid) as total from tb_record group by userid) t1)) t2 inner join tb_user as t3 on t2.userid=t3.userid inner join tb_city as t4 on t3.cityid=t4.cityid;
select bikeid, broken from tb_bike

View File

@ -0,0 +1,19 @@
drop database if exists Shop;
create database Shop default charset utf8;
use Shop;
drop table if exists tb_goods;
create table tb_goods
(
gid int not null auto_increment,
gname varchar(50) not null,
gprice decimal(10,2) not null,
gimage varchar(255),
primary key (gid)
);
insert into tb_goods values
(default, '乐事Lays无限薯片', 8.2, 'images/lay.jpg'),
(default, '旺旺 仙贝 加量装 540g', 18.5, 'images/wang.jpg'),
(default, '多儿比Dolbee黄桃水果罐头', 6.8, 'images/dolbee.jpg'),
(default, '王致和 精制料酒 500ml', 7.9, 'images/wine.jpg'),
(default, '陈克明 面条 鸡蛋龙须挂面', 1.0, 'images/noodle.jpg'),
(default, '鲁花 菜籽油 4L', 69.9, 'images/oil.jpg');

View File

@ -343,5 +343,3 @@
1. MySQLdb
2. PyMySQL