Python-100天(二)-Python语言进阶

数据结构和算法

  • 算法:解决问题的方法和步骤
  • 评价算法的好坏:渐近时间复杂度和渐近空间复杂度。
  • 渐近时间复杂度的大O标记:
    • 常量时间复杂度 - 布隆过滤器 / 哈希存储

    • 对数时间复杂度 - 折半查找(二分查找)

    • 线性时间复杂度 - 顺序查找 / 桶排序

    • 对数线性时间复杂度 - 高级排序算法(归并排序、快速排序)

    • 平方时间复杂度 - 简单排序算法(选择排序、插入排序、冒泡排序)

    • 立方时间复杂度 - Floyd算法 / 矩阵乘法运算

    • 几何级数时间复杂度 - 汉诺塔

    • 阶乘时间复杂度 - 旅行经销商问题 - NP

  • 排序算法(选择、冒泡和归并)和查找算法(顺序和折半)
def select_sort(origin_items, comp=lambda x, y: x < y):
    """简单选择排序"""
    items = origin_items[:]
    for i in range(len(items) - 1):
        min_index = i
        for j in range(i + 1, len(items)):
            if comp(items[j], items[min_index]):
                min_index = j
        items[i], items[min_index] = items[min_index], items[i]
    return items
def bubble_sort(origin_items, comp=lambda x, y: x > y):
    """高质量冒泡排序(搅拌排序)"""
    items = origin_items[:]
    for i in range(len(items) - 1):
        swapped = False
        for j in range(i, 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
    return items
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):
    """合并(将两个有序的列表合并成一个有序的列表)"""
    items = []
    index1, index2 = 0, 0
    while index1 < len(items1) and index2 < len(items2):
        if comp(items1[index1], items2[index2]):
            items.append(items1[index1])
            index1 += 1
        else:
            items.append(items2[index2])
            index2 += 1
    items += items1[index1:]
    items += items2[index2:]
    return items
def seq_search(items, key):
    """顺序查找"""
    for index, item in enumerate(items):
        if item == key:
            return index
    return -1
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
  • 使用生成式(推导式)语法
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)

说明:生成式(推导式)可以用来生成列表、集合和字典。

  • 嵌套的列表
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)

Python Tutor - VISUALIZE CODE AND GET LIVE HELP

  • heapq、itertools等的用法
"""
从列表中找出最大的或最小的N个元素
堆结构(大根堆/小根堆)
"""
import heapq

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']))
"""
迭代工具 - 排列 / 组合 / 笛卡尔积
"""
import itertools

itertools.permutations('ABCD')
itertools.combinations('ABCDE', 3)
itertools.product('ABCD', '123')
  • collections模块下的工具类
"""
找出序列中出现次数最多的元素
"""
from collections import Counter

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))
  • 常用算法:
    • 穷举法 - 又称为暴力破解法,对所有的可能性进行验证,直到找到正确答案。
    • 贪婪法 - 在对问题求解时,总是做出在当前看来
    • 最好的选择,不追求最优解,快速找到满意解。
    • 分治法 - 把一个复杂的问题分成两个或更多的相同或相似的子问题,再把子问题分成更小的子问题,直到可以直接求解的程度,最后将子问题的解进行合并得到原问题的解。
    • 回溯法 - 回溯法又称为试探法,按选优条件向前搜索,当搜索到某一步发现原先选择并不优或达不到目标时,就退回一步重新选择。
    • 动态规划 - 基本思想也是将待求解问题分解成若干个子问题,先求解并保存这些子问题的解,避免产生大量的重复运算。

穷举法例子:百钱百鸡和五人分鱼。

# 公鸡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 = 6
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 += 5

贪婪法例子:假设小偷有一个背包,最多能装20公斤赃物,他闯入一户人家,发现如下表所示的物品。很显然,他不能把所有物品都装进背包,所以必须确定拿走哪些物品,留下哪些物品。

|  名称  | 价格(美元) | 重量(kg) |
| :----: | :----------: | :--------: |
|  电脑  |     200      |     20     |
| 收音机 |      20      |     4      |
|   钟   |     175      |     10     |
|  花瓶  |      50      |     2      |
|   书   |      10      |     1      |
|  油画  |      90      |     9      |
"""
贪婪法:在对问题求解时,总是做出在当前看来是最好的选择,不追求最优解,快速找到满意解。
输入:
20 6
电脑 200 20
收音机 20 4
钟 175 10
花瓶 50 2
书 10 1
油画 90 9
"""
class Thing(object):
    """物品"""

    def __init__(self, name, price, weight):
        self.name = name
        self.price = price
        self.weight = weight

    @property
    def value(self):
        """价格重量比"""
        return self.price / self.weight


def input_thing():
    """输入物品信息"""
    name_str, price_str, weight_str = input().split()
    return name_str, int(price_str), int(weight_str)


def main():
    """主函数"""
    max_weight, num_of_things = map(int, input().split())
    all_things = []
    for _ in range(num_of_things):
        all_things.append(Thing(*input_thing()))
    all_things.sort(key=lambda x: x.value, reverse=True)
    total_weight = 0
    total_price = 0
    for thing in all_things:
        if total_weight + thing.weight <= max_weight:
            print(f'小偷拿走了{thing.name}')
            total_weight += thing.weight
            total_price += thing.price
    print(f'总价值: {total_price}美元')


if __name__ == '__main__':
    main()

分治法例子:快速排序。

"""
快速排序 - 选择枢轴对元素进行划分,左边都比枢轴小右边都比枢轴大
"""
def quick_sort(origin_items, comp=lambda x, y: x <= y):
    items = origin_items[:]
    _quick_sort(items, 0, len(items) - 1, comp)
    return items


def _quick_sort(items, start, end, comp):
    if start < end:
        pos = _partition(items, start, end, comp)
        _quick_sort(items, start, pos - 1, comp)
        _quick_sort(items, pos + 1, end, comp)


def _partition(items, start, end, comp):
    pivot = items[end]
    i = start - 1
    for j in range(start, end):
        if comp(items[j], pivot):
            i += 1
            items[i], items[j] = items[j], items[i]
    items[i + 1], items[end] = items[end], items[i + 1]
    return i + 1

回溯法例子:骑士巡逻。

"""
递归回溯法:叫称为试探法,按选优条件向前搜索,当搜索到某一步,发现原先选择并不优或达不到目标时,就退回一步重新选择,比较经典的问题包括骑士巡逻、八皇后和迷宫寻路等。
"""
import sys
import time

SIZE = 5
total = 0


def print_board(board):
    for row in board:
        for col in row:
            print(str(col).center(4), end='')
        print()


def patrol(board, row, col, step=1):
    if row >= 0 and row < SIZE and \
        col >= 0 and col < SIZE and \
        board[row][col] == 0:
        board[row][col] = step
        if step == SIZE * SIZE:
            global total
            total += 1
            print(f'第{total}种走法: ')
            print_board(board)
        patrol(board, row - 2, col - 1, step + 1)
        patrol(board, row - 1, col - 2, step + 1)
        patrol(board, row + 1, col - 2, step + 1)
        patrol(board, row + 2, col - 1, step + 1)
        patrol(board, row + 2, col + 1, step + 1)
        patrol(board, row + 1, col + 2, step + 1)
        patrol(board, row - 1, col + 2, step + 1)
        patrol(board, row - 2, col + 1, step + 1)
        board[row][col] = 0


def main():
    board = [[0] * SIZE for _ in range(SIZE)]
    patrol(board, SIZE - 1, SIZE - 1)


if __name__ == '__main__':
    main()

动态规划例子1:斐波拉切数列。(不使用动态规划将会是几何级数复杂度)

"""
动态规划 - 适用于有重叠子问题和最优子结构性质的问题
使用动态规划方法所耗时间往往远少于朴素解法(用空间换取时间)
"""
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]

动态规划例子2:子列表元素之和的最大值。(使用动态规划可以避免二重循环)

说明:子列表指的是列表中索引(下标)连续的元素构成的列表;列表中的元素是int类型,可能包含正整数、0、负整数;程序输入列表中的元素,输出子列表元素求和的最大值,例如:

输入:1 -2 3 5 -3 2

输出:8

输入:0 -2 3 5 -1 2

输出:9

输入:-9 -2 -3 -5 -3

输出:-2

def main():
    items = list(map(int, input().split()))
    size = len(items)
    overall, partial = {}, {}
    overall[size - 1] = partial[size - 1] = items[size - 1]
    for i in range(size - 2, -1, -1):
        partial[i] = max(items[i], partial[i + 1] + items[i])
        overall[i] = max(partial[i], overall[i + 1])
    print(overall[0])


if __name__ == '__main__':
    main()

函数的使用方式

  • 将函数视为“一等公民”

    • 函数可以赋值给变量
    • 函数可以作为函数的参数
    • 函数可以作为函数的返回值
  • 高阶函数的用法(filtermap以及它们的替代品)

items1 = list(map(lambda x: x ** 2, filter(lambda x: x % 2, range(1, 10))))
items2 = [x ** 2 for x in range(1, 10) if x % 2]
  • 位置参数、可变参数、关键字参数、命名关键字参数

  • 参数的元信息(代码可读性问题)

  • 匿名函数和内联函数的用法(lambda函数)

  • 闭包和作用域问题

  • Python搜索变量的LEGB顺序(Local --> Embedded --> Global --> Built-in)

  • globalnonlocal关键字的作用
    global:声明或定义全局变量(要么直接使用现有的全局作用域的变量,要么定义一个变量放到全局作用域)。
    nonlocal:声明使用嵌套作用域的变量(嵌套作用域必须存在该变量,否则报错)。

  • 装饰器函数(使用装饰器和取消装饰器)

例子:输出函数执行时间的装饰器。

def record_time(func):
    """自定义装饰函数的装饰器"""
    
    @wraps(func)
    def wrapper(*args, **kwargs):
        start = time()
        result = func(*args, **kwargs)
        print(f'{func.__name__}: {time() - start}秒')
        return result
        
    return wrapper

如果装饰器不希望跟print函数耦合,可以编写带参数的装饰器。

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
from functools import wraps
from time import time


class Record():
    """自定义装饰器类(通过__call__魔术方法使得对象可以当成函数调用)"""

    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

说明:由于对带装饰功能的函数添加了@wraps装饰器,可以通过func.__wrapped__方式获得被装饰之前的函数或类来取消装饰器的作用。

例子:用装饰器来实现单例模式。

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():
    """总统(单例类)"""
    pass

说明:上面的代码中用到了闭包(closure),不知道你是否已经意识到了。还没有一个小问题就是,上面的代码并没有实现线程安全的单例,如果要实现线程安全的单例应该怎么做呢?

from functools import wraps
from threading import Lock


def singleton(cls):
    """线程安全的单例装饰器"""
    instances = {}
    locker = Lock()

    @wraps(cls)
    def wrapper(*args, **kwargs):
        if cls not in instances:
            with locker:
                if cls not in instances:
                    instances[cls] = cls(*args, **kwargs)
        return instances[cls]

    return wrapper

面向对象相关知识

  • 三大支柱:封装、继承、多态

例子:工资结算系统。

"""
月薪结算系统 - 部门经理每月15000 程序员每小时200 销售员1800底薪加销售额5%提成
"""
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.0


class Programmer(Employee):
    """程序员"""

    def __init__(self, name, working_hour=0):
        self.working_hour = working_hour
        super().__init__(name)

    def get_salary(self):
        return 200.0 * self.working_hour


class Salesman(Employee):
    """销售员"""

    def __init__(self, name, sales=0.0):
        self.sales = sales
        super().__init__(name)

    def get_salary(self):
        return 1800.0 + self.sales * 0.05


class EmployeeFactory():
    """创建员工的工厂(工厂模式 - 通过工厂实现对象使用者和对象之间的解耦合)"""

    @staticmethod
    def create(emp_type, *args, **kwargs):
        """创建员工"""
        emp_type = emp_type.upper()
        emp = None
        if emp_type == 'M':
            emp = Manager(*args, **kwargs)
        elif emp_type == 'P':
            emp = Programmer(*args, **kwargs)
        elif emp_type == 'S':
            emp = Salesman(*args, **kwargs)
        return emp


def main():
    """主函数"""
    emps = [
        EmployeeFactory.create('M', '曹操'), 
        EmployeeFactory.create('P', '荀彧', 120),
        EmployeeFactory.create('P', '郭嘉', 85), 
        EmployeeFactory.create('S', '典韦', 123000),
    ]
    for emp in emps:
        print('%s: %.2f元' % (emp.name, emp.get_salary()))


if __name__ == '__main__':
    main()
  • 类与类之间的关系

    • is-a关系:继承
    • has-a关系:关联 / 聚合 / 合成
    • use-a关系:依赖

例子:扑克游戏。

"""
经验:符号常量总是优于字面常量,枚举类型是定义符号常量的最佳选择
"""
from enum import Enum, unique

import random


@unique
class Suite(Enum):
    """花色"""

    SPADE, HEART, CLUB, DIAMOND = range(4)

    def __lt__(self, other):
        return self.value < other.value


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)
        self.index = 0

    def deal(self):
        """发牌"""
        card = self.cards[self.index]
        self.index += 1
        return card

    @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 sort(self, comp=lambda card: (card.suite, card.face)):
        """整理手上的牌"""
        self.cards.sort(key=comp)


def main():
    """主函数"""
    poker = Poker()
    poker.shuffle()
    players = [Player('东邪'), Player('西毒'), Player('南帝'), Player('北丐')]
    while poker.has_more:
        for player in players:
                player.get_one(poker.deal())
    for player in players:
        player.sort()
        print(player.name, end=': ')
        print(player.cards)


if __name__ == '__main__':
    main()

说明:上面的代码中使用了Emoji字符来表示扑克牌的四种花色,在某些不支持Emoji字符的系统上可能无法显示。

  • 对象的复制(深复制/深拷贝/深度克隆和浅复制/浅拷贝/影子克隆)
  • 垃圾回收、循环引用和弱引用
    Python使用了自动化内存管理,这种管理机制以引用计数为基础,同时也引入了标记-清除分代收集两种机制为辅的策略。
typedef struct_object {
    /* 引用计数 */
    int ob_refcnt;
    /* 对象指针 */
    struct_typeobject *ob_type;
} PyObject;
/* 增加引用计数的宏定义 */
#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
# 循环引用会导致内存泄露 - Python除了引用技术还引入了标记清理和分代回收
# 在Python 3.6以前如果重写__del__魔术方法会导致循环引用处理失效
# 如果不想造成循环引用可以使用弱引用
list1 = []
list2 = [] 
list1.append(list2)
list2.append(list1)
```

以下情况会导致垃圾回收:

- 调用`gc.collect()`
- gc模块的计数器达到阀值
- 程序退出

如果循环引用中两个对象都定义了`__del__`方法,gc模块不会销毁这些不可达对象,因为gc模块不知道应该先调用哪个对象的`__del__`方法,这个问题在Python 3.6中得到了解决。

也可以通过`weakref`模块构造弱引用的方式来解决循环引用的问题。
  • 魔法属性和方法(请参考《Python魔法方法指南》)

有几个小问题请大家思考:
- 自定义的对象能不能使用运算符做运算?
- 自定义的对象能不能放到set中?能去重吗?
- 自定义的对象能不能作为dict的键?
- 自定义的对象能不能使用上下文语法?

  • 混入(Mixin)

例子:自定义字典限制只有在指定的key不存在时才能在字典中设置键值对。

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


my_dict= SetOnceDict()
try:
    my_dict['username'] = 'jackfrued'
    my_dict['username'] = 'hellokitty'
except KeyError:
    pass
print(my_dict)
  • 元编程和元类

例子:用元类实现单例模式。

import threading


class SingletonMeta(type):
    """自定义元类"""

    def __init__(cls, *args, **kwargs):
        cls.__instance = None
        cls.__lock = threading.Lock()
        super().__init__(*args, **kwargs)

    def __call__(cls, *args, **kwargs):
        if cls.__instance is None:
            with cls.__lock:
                if cls.__instance is None:
                    cls.__instance = super().__call__(*args, **kwargs)
        return cls.__instance


class President(metaclass=SingletonMeta):
    """总统(单例类)"""
    
    pass
  • 面向对象设计原则

    • 单一职责原则 (SRP)- 一个类只做该做的事情(类的设计要高内聚)
    • 开闭原则 (OCP)- 软件实体应该对扩展开发对修改关闭
    • 依赖倒转原则(DIP)- 面向抽象编程(在弱类型语言中已经被弱化)
    • 里氏替换原则(LSP) - 任何时候可以用子类对象替换掉父类对象
    • 接口隔离原则(ISP)- 接口要小而专不要大而全(Python中没有接口的概念)
    • 合成聚合复用原则(CARP) - 优先使用强关联关系而不是继承关系复用代码
    • 最少知识原则(迪米特法则,LoD)- 不要给没有必然联系的对象发消息

    说明:上面加粗的字母放在一起称为面向对象的SOLID原则。

    GoF设计模式

    • 创建型模式:单例、工厂、建造者、原型
    • 结构型模式:适配器、门面(外观)、代理
    • 行为型模式:迭代器、观察者、状态、策略

例子:可插拔的哈希算法。

class StreamHasher():
    """哈希摘要生成器(策略模式)"""

    def __init__(self, alg='md5', size=4096):
        self.size = size
        alg = alg.lower()
        self.hasher = getattr(__import__('hashlib'), alg.lower())()

    def __call__(self, stream):
        return self.to_digest(stream)

    def to_digest(self, stream):
        """生成十六进制形式的摘要"""
        for buf in iter(lambda: stream.read(self.size), b''):
            self.hasher.update(buf)
        return self.hasher.hexdigest()

def main():
    """主函数"""
    hasher1 = StreamHasher()
    with open('Python-3.7.1.tgz', 'rb') as stream:
        print(hasher1.to_digest(stream))
    hasher2 = StreamHasher('sha1')
    with open('Python-3.7.1.tgz', 'rb') as stream:
        print(hasher2(stream))


if __name__ == '__main__':
    main()

迭代器和生成器

  • 和迭代器相关的魔术方法(__iter____next__

  • 两种创建生成器的方式(生成器表达式和yield关键字)

def fib(num):
    """生成器"""
    a, b = 0, 1
    for _ in range(num):
        a, b = b, a + b
        yield a


class Fib(object):
    """迭代器"""
    
    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()

并发编程

Python中实现并发编程的三种方案:多线程、多进程和异步I/O。并发编程的好处在于可以提升程序的执行效率以及改善用户体验;坏处在于并发的程序不容易开发和调试,同时对其他程序来说它并不友好。

  • 多线程:Python中提供了Thread类并辅以Lock、Condition、Event、Semaphore和Barrier。Python中有GIL来防止多个线程同时执行本地字节码,这个锁对于CPython是必须的,因为CPython的内存管理并不是线程安全的,因为GIL的存在多线程并不能发挥CPU的多核特性。
"""
面试题:进程和线程的区别和联系?
进程 - 操作系统分配内存的基本单位 - 一个进程可以包含一个或多个线程
线程 - 操作系统分配CPU的基本单位
并发编程(concurrent programming)
1. 提升执行性能 - 让程序中没有因果关系的部分可以并发的执行
2. 改善用户体验 - 让耗时间的操作不会造成程序的假死
"""
import glob
import os
import threading

from PIL import Image

PREFIX = 'thumbnails'


def generate_thumbnail(infile, size, format='PNG'):
    """生成指定图片文件的缩略图"""
file, ext = os.path.splitext(infile)
file = file[file.rfind('/') + 1:]
outfile = f'{PREFIX}/{file}_{size[0]}_{size[1]}.{ext}'
img = Image.open(infile)
img.thumbnail(size, Image.ANTIALIAS)
img.save(outfile, format)


def main():
    """主函数"""
if not os.path.exists(PREFIX):
    os.mkdir(PREFIX)
for infile in glob.glob('images/*.png'):
    for size in (32, 64, 128):
            # 创建并启动线程
        threading.Thread(
            target=generate_thumbnail, 
            args=(infile, (size, size))
        ).start()
        

if __name__ == '__main__':
main()

多个线程竞争资源的情况

"""
多线程程序如果没有竞争资源处理起来通常也比较简单
当多个线程竞争临界资源的时候如果缺乏必要的保护措施就会导致数据错乱
说明:临界资源就是被多个线程竞争的资源
"""
import time
import threading

from concurrent.futures import ThreadPoolExecutor


class Account(object):
    """银行账户"""

    def __init__(self):
        self.balance = 0.0
        self.lock = threading.Lock()

    def deposit(self, money):
        # 通过锁保护临界资源
        with self.lock:
            new_balance = self.balance + money
            time.sleep(0.001)
            self.balance = new_balance


class AddMoneyThread(threading.Thread):
    """自定义线程类"""

    def __init__(self, account, money):
        self.account = account
        self.money = money
        # 自定义线程的初始化方法中必须调用父类的初始化方法
        super().__init__()

    def run(self):
        # 线程启动之后要执行的操作
        self.account.deposit(self.money)

def main():
    """主函数"""
    account = Account()
    # 创建线程池
    pool = ThreadPoolExecutor(max_workers=10)
    futures = []
    for _ in range(100):
        # 创建线程的第1种方式
        # threading.Thread(
        #     target=account.deposit, args=(1, )
        # ).start()
        # 创建线程的第2种方式
        # AddMoneyThread(account, 1).start()
        # 创建线程的第3种方式
        # 调用线程池中的线程来执行特定的任务
        future = pool.submit(account.deposit, 1)
        futures.append(future)
    # 关闭线程池
    pool.shutdown()
    for future in futures:
        future.result()
    print(account.balance)


if __name__ == '__main__':
    main()

修改上面的程序,启动5个线程向账户中存钱,5个线程从账户中取钱,取钱时如果余额不足就暂停线程进行等待。为了达到上述目标,需要对存钱和取钱的线程进行调度,在余额不足时取钱的线程暂停并释放锁,而存钱的线程将钱存入后要通知取钱的线程,使其从暂停状态被唤醒。可以使用threading模块的Condition来实现线程调度,该对象也是基于锁来创建的,代码如下所示:

"""
多个线程竞争一个资源 - 保护临界资源 - 锁(Lock/RLock)
多个线程竞争多个资源(线程数>资源数) - 信号量(Semaphore)
多个线程的调度 - 暂停线程执行/唤醒等待中的线程 - Condition
"""
from concurrent.futures import ThreadPoolExecutor
from random import randint
from time import sleep

import threading


class Account():
    """银行账户"""

    def __init__(self, balance=0):
        self.balance = balance
        lock = threading.Lock()
        self.condition = threading.Condition(lock)

    def withdraw(self, money):
        """取钱"""
        with self.condition:
            while money > self.balance:
                self.condition.wait()
            new_balance = self.balance - money
            sleep(0.001)
            self.balance = new_balance

    def deposit(self, money):
        """存钱"""
        with self.condition:
            new_balance = self.balance + money
            sleep(0.001)
            self.balance = new_balance
            self.condition.notify_all()


def add_money(account):
    while True:
        money = randint(5, 10)
        account.deposit(money)
        print(threading.current_thread().name, 
            ':', money, '====>', account.balance)
        sleep(0.5)


def sub_money(account):
    while True:
        money = randint(10, 30)
        account.withdraw(money)
        print(threading.current_thread().name, 
            ':', money, '<====', account.balance)
        sleep(1)


def main():
    account = Account()
    with ThreadPoolExecutor(max_workers=10) as pool:
        for _ in range(5):
            pool.submit(add_money, account)
            pool.submit(sub_money, account)


if __name__ == '__main__':
    main()
  • 多进程:多进程可以有效的解决GIL的问题,实现多进程主要的类是Process,其他辅助的类跟threading模块中的类似,进程间共享数据可以使用管道、套接字等,在multiprocessing模块中有一个Queue类,它基于管道和锁机制提供了多个进程共享的队列。下面是官方文档上关于多进程和进程池的一个示例。
"""
多进程和进程池的使用
多线程因为GIL的存在不能够发挥CPU的多核特性
对于计算密集型任务应该考虑使用多进程
time python3 example22.py
real    0m11.512s
user    0m39.319s
sys     0m0.169s
使用多进程后实际执行时间为11.512秒,而用户时间39.319秒约为实际执行时间的4倍
这就证明我们的程序通过多进程使用了CPU的多核特性,而且这台计算机配置了4核的CPU
"""
import concurrent.futures
import math

PRIMES = [
    1116281,
    1297337,
    104395303,
    472882027,
    533000389,
    817504243,
    982451653,
    112272535095293,
    112582705942171,
    112272535095293,
    115280095190773,
    115797848077099,
    1099726899285419
] * 5


def is_prime(n):
    """判断素数"""
    if n % 2 == 0:
        return False

    sqrt_n = int(math.floor(math.sqrt(n)))
    for i in range(3, sqrt_n + 1, 2):
        if n % i == 0:
            return False
    return True


def main():
    """主函数"""
    with concurrent.futures.ProcessPoolExecutor() as executor:
        for number, prime in zip(PRIMES, executor.map(is_prime, PRIMES)):
            print('%d is prime: %s' % (number, prime))


if __name__ == '__main__':
    main()

说明:多线程和多进程的比较

以下情况需要使用多线程:

  1. 程序需要维护许多共享的状态(尤其是可变状态),Python中的列表、字典、集合都是线程安全的,所以使用线程而不是进程维护共享状态的代价相对较小。
  2. 程序会花费大量时间在I/O操作上,没有太多并行计算的需求且不需占用太多的内存。

以下情况需要使用多进程:

  1. 程序执行计算密集型任务(如:字节码操作、数据处理、科学计算)。
  2. 程序的输入可以并行的分成块,并且可以将运算结果合并。
  3. 程序在内存使用方面没有任何限制且不强依赖于I/O操作(如:读写文件、套接字等)。
  • 异步处理:从调度程序的任务队列中挑选任务,该调度程序以交叉的形式执行这些任务,我们并不能保证任务将以某种顺序去执行,因为执行顺序取决于队列中的一项任务是否愿意将CPU处理时间让位给另一项任务。异步任务通常通过多任务协作处理的方式来实现,由于执行时间和顺序的不确定,因此需要通过回调式编程或者future对象来获取任务执行的结果。Python 3通过asyncio模块和awaitasync关键字(在Python 3.7中正式被列为关键字)来支持异步处理。
"""
异步I/O - async / await
"""
import asyncio


def num_generator(m, n):
    """指定范围的数字生成器"""
    yield from range(m, n + 1)


async def prime_filter(m, n):
    """素数过滤器"""
    primes = []
    for i in num_generator(m, n):
        flag = True
        for j in range(2, int(i ** 0.5 + 1)):
            if i % j == 0:
                flag = False
                break
        if flag:
            print('Prime =>', i)
            primes.append(i)

        await asyncio.sleep(0.001)
    return tuple(primes)


async def square_mapper(m, n):
    """平方映射器"""
    squares = []
    for i in num_generator(m, n):
        print('Square =>', i * i)
        squares.append(i * i)

        await asyncio.sleep(0.001)
    return squares


def main():
    """主函数"""
    loop = asyncio.get_event_loop()
    future = asyncio.gather(prime_filter(2, 100), square_mapper(1, 100))
    future.add_done_callback(lambda x: print(x.result()))
    loop.run_until_complete(future)
    loop.close()


if __name__ == '__main__':
    main()

说明:上面的代码使用get_event_loop函数获得系统默认的事件循环,通过gather函数可以获得一个future对象,future对象的add_done_callback可以添加执行完成时的回调函数,loop对象的run_until_complete方法可以等待通过future对象获得协程执行结果。

Python中有一个名为aiohttp的三方库,它提供了异步的HTTP客户端和服务器,这个三方库可以跟asyncio模块一起工作,并提供了对Future对象的支持。Python 3.6中引入了async和await来定义异步执行的函数以及创建异步上下文,在Python 3.7中它们正式成为了关键字。下面的代码异步的从5个URL中获取页面并通过正则表达式的命名捕获组提取了网站的标题。

import asyncio
import re

import aiohttp

PATTERN = re.compile(r'\(?P.*)\<\/title\>')


async def fetch_page(session, url):
    async with session.get(url, ssl=False) as resp:
        return await resp.text()


async def show_title(url):
    async with aiohttp.ClientSession() as session:
        html = await fetch_page(session, url)
        print(PATTERN.search(html).group('title'))


def main():
    urls = ('https://www.python.org/',
            'https://git-scm.com/',
            'https://www.jd.com/',
            'https://www.taobao.com/',
            'https://www.douban.com/')
    loop = asyncio.get_event_loop()
    tasks = [show_title(url) for url in urls]
    loop.run_until_complete(asyncio.wait(tasks))
    loop.close()


if __name__ == '__main__':
    main()
</code></pre> 
 <blockquote> 
  <p>说明:<strong>异步I/O与多进程的比较</strong>。</p> 
  <p>当程序不需要真正的并发性或并行性,而是更多的依赖于异步处理和回调时,asyncio就是一种很好的选择。如果程序中有大量的等待与休眠时,也应该考虑asyncio,它很适合编写没有实时数据处理需求的Web应用服务器。</p> 
 </blockquote> 
 <p>Python还有很多用于处理并行任务的三方库,例如:joblib、PyMP等。实际开发中,要提升系统的可扩展性和并发性通常有垂直扩展(增加单个节点的处理能力)和水平扩展(将单个节点变成多个节点)两种做法。可以通过消息队列来实现应用程序的解耦合,消息队列相当于是多线程同步队列的扩展版本,不同机器上的应用程序相当于就是线程,而共享的分布式消息队列就是原来程序中的Queue。消息队列(面向消息的中间件)的最流行和最标准化的实现是AMQP(高级消息队列协议),AMQP源于金融行业,提供了排队、路由、可靠传输、安全等功能,最著名的实现包括:Apache的ActiveMQ、RabbitMQ等。</p> 
 <p>要实现任务的异步化,可以使用名为Celery的三方库。Celery是Python编写的分布式任务队列,它使用分布式消息进行工作,可以基于RabbitMQ或Redis来作为后端的消息代理。</p> 
</article>
                            </div>
                        </div>
                    </div>
                    <!--PC和WAP自适应版-->
                    <div id="SOHUCS" sid="1681069036164689920"></div>
                    <script type="text/javascript" src="/views/front/js/chanyan.js"></script>
                    <!-- 文章页-底部 动态广告位 -->
                    <div class="youdao-fixed-ad" id="detail_ad_bottom"></div>
                </div>
                <div class="col-md-3">
                    <div class="row" id="ad">
                        <!-- 文章页-右侧1 动态广告位 -->
                        <div id="right-1" class="col-lg-12 col-md-12 col-sm-4 col-xs-4 ad">
                            <div class="youdao-fixed-ad" id="detail_ad_1"> </div>
                        </div>
                        <!-- 文章页-右侧2 动态广告位 -->
                        <div id="right-2" class="col-lg-12 col-md-12 col-sm-4 col-xs-4 ad">
                            <div class="youdao-fixed-ad" id="detail_ad_2"></div>
                        </div>
                        <!-- 文章页-右侧3 动态广告位 -->
                        <div id="right-3" class="col-lg-12 col-md-12 col-sm-4 col-xs-4 ad">
                            <div class="youdao-fixed-ad" id="detail_ad_3"></div>
                        </div>
                    </div>
                </div>
            </div>
        </div>
    </div>
    <div class="container">
        <h4 class="pt20 mb15 mt0 border-top">你可能感兴趣的:(Python-100天(二)-Python语言进阶)</h4>
        <div id="paradigm-article-related">
            <div class="recommend-post mb30">
                <ul class="widget-links">
                    <li><a href="/article/1835514464028422144.htm"
                           title="情绪觉察日记第37天" target="_blank">情绪觉察日记第37天</a>
                        <span class="text-muted">露露_e800</span>

                        <div>今天是家庭关系规划师的第二阶最后一天,慧萍老师帮我做了个案,帮我处理了埋在心底好多年的一份恐惧,并给了我深深的力量!这几天出来学习,爸妈过来婆家帮我带小孩,妈妈出于爱帮我收拾东西,并跟我先生和婆婆产生矛盾,妈妈觉得他们没有照顾好我…。今晚回家见到妈妈,我很欣赏她并赞扬她,妈妈说今晚要跟我睡我说好,当我们俩躺在床上准备睡觉的时候,我握着妈妈的手对她说:妈妈这几天辛苦你了,你看你多利害把我们的家收拾得</div>
                    </li>
                    <li><a href="/article/1835513571501502464.htm"
                           title="2020-01-25" target="_blank">2020-01-25</a>
                        <span class="text-muted">晴岚85</span>

                        <div>郑海燕坚持分享590天2020.1.24在生活中只存在两个问题。一个问题是:你知道想要达成的目标是什么,但却不知道如何才能达成;另一个问题是:你不知道你的目标是什么。前一个是行动的问题,后一个是结果的问题。通过制定具体的下一步行动,可以解决不知道如何开始行动的问题。而通过去想象结果,对结果做预估,可以解决找不着目标的问题。对于所有吸引我们注意力,想要完成的任务,你可以先想象一下,预期的结果究竟是什</div>
                    </li>
                    <li><a href="/article/1835513440525971456.htm"
                           title="一百九十四章. 自相矛盾" target="_blank">一百九十四章. 自相矛盾</a>
                        <span class="text-muted">巨木擎天</span>

                        <div>唉!就这么一夜,林子感觉就像过了很多天似的,先是回了阳间家里,遇到了那么多不可思议的事情儿。特别是小伙伴们,第二次与自己见面时,僵硬的表情和恐怖的气氛,让自己如坐针毡,打从心眼里难受!还有东子,他现在还好吗?有没有被人欺负?护城河里的小鱼小虾们,还都在吗?水不会真的干枯了吧?那对相亲相爱漂亮的太平鸟儿,还好吧!春天了,到了做窝、下蛋、喂养小鸟宝宝的时候了,希望它们都能够平安啊!虽然没有看见家人,也</div>
                    </li>
                    <li><a href="/article/1835512809883004928.htm"
                           title="10月|愿你的青春不负梦想-读书笔记-01" target="_blank">10月|愿你的青春不负梦想-读书笔记-01</a>
                        <span class="text-muted">Tracy的小书斋</span>

                        <div>本书的作者是俞敏洪,大家都很熟悉他了吧。俞敏洪老师是我行业的领头羊吧,也是我事业上的偶像。本日摘录他书中第一章中的金句:『一个人如果什么目标都没有,就会浑浑噩噩,感觉生命中缺少能量。能给我们能量的,是对未来的期待。第一件事,我始终为了进步而努力。与其追寻全世界的骏马,不如种植丰美的草原,到时骏马自然会来。第二件事,我始终有阶段性的目标。什么东西能给我能量?答案是对未来的期待。』读到这里的时候,我便</div>
                    </li>
                    <li><a href="/article/1835512542735200256.htm"
                           title="C语言宏函数" target="_blank">C语言宏函数</a>
                        <span class="text-muted">南林yan</span>
<a class="tag" taget="_blank" href="/search/C%E8%AF%AD%E8%A8%80/1.htm">C语言</a><a class="tag" taget="_blank" href="/search/c%E8%AF%AD%E8%A8%80/1.htm">c语言</a>
                        <div>一、什么是宏函数?通过宏定义的函数是宏函数。如下,编译器在预处理阶段会将Add(x,y)替换为((x)*(y))#defineAdd(x,y)((x)*(y))#defineAdd(x,y)((x)*(y))intmain(){inta=10;intb=20;intd=10;intc=Add(a+d,b)*2;cout<<c<<endl;//800return0;}二、为什么要使用宏函数使用宏函数</div>
                    </li>
                    <li><a href="/article/1835512178023690240.htm"
                           title="谢谢你们,爱你们!" target="_blank">谢谢你们,爱你们!</a>
                        <span class="text-muted">鹿游儿</span>

                        <div>昨天家人去泡温泉,二个孩子也带着去,出发前一晚,匆匆下班,赶回家和孩子一起收拾。饭后,我拿出笔和本子(上次去澳门时做手帐的本子)写下了1\2\3\4\5\6\7\8\9,让后让小壹去思考,带什么出发去旅游呢?她在对应的数字旁边画上了,泳衣、泳圈、肖恩、内衣内裤、tapuy、拖鞋……画完后,就让她自己对着这个本子,将要带的,一一带上,没想到这次带的书还是这本《便便工厂》(晚上姑婆发照片过来,妹妹累得</div>
                    </li>
                    <li><a href="/article/1835510909070569472.htm"
                           title="瑶池防线" target="_blank">瑶池防线</a>
                        <span class="text-muted">谜影梦蝶</span>

                        <div>冥华虽然逃过了影梦的军队,但他是一个忠臣,他选择上报战况。败给影梦后成逃兵,高层亡尔还活着,七重天失守......随便一条,即可处死冥华。冥华自然是知道以仙界高层的习性此信一发自己必死无疑,但他还选择上报实情,因为责任。同样此信送到仙宫后,知道此事的人,大多数人都认定冥华要完了,所以上到仙界高层,下到扫大街的,包括冥华自己,全都准备好迎接冥华之死。如果仙界现在还属于两方之争的话,冥华必死无疑。然而</div>
                    </li>
                    <li><a href="/article/1835510656011431936.htm"
                           title="爬山后遗症" target="_blank">爬山后遗症</a>
                        <span class="text-muted">璃绛</span>

                        <div>爬山,攀登,一步一步走向制高点,是一种挑战。成功抵达是一种无法言语的快乐,在山顶吹吹风,看看风景,这是从未有过的体验。然而,爬山一时爽,下山腿打颤,颠簸的路,一路向下走,腿部力量不够,走起来抖到不行,停不下来了!第二天必定腿疼,浑身酸痛,坐立难安!</div>
                    </li>
                    <li><a href="/article/1835509898507546624.htm"
                           title="《策划经理回忆录之二》" target="_blank">《策划经理回忆录之二》</a>
                        <span class="text-muted">路基雅虎</span>

                        <div>话说三年变六年,飘了,飘了……眨眼,2013年5月,老吴回到了他的家乡——油城从新开启他的工作幻想症生涯。很庆幸,这是一家很有追求,同时敢于尝试的,且实力不容低调的新星房企——金源置业(前身泰源置业)更值得庆幸的是第一个盘就是油城十路的标杆之一:金源盛世。2013年5月,到2015年11月,两年的陪伴,迎来了一场大爆发。2000个筹,5万/筹,直接回笼1个亿!!!这……让我开始认真审视这座看似五线</div>
                    </li>
                    <li><a href="/article/1835509138126368768.htm"
                           title="30天风格练习-DAY2" target="_blank">30天风格练习-DAY2</a>
                        <span class="text-muted">黄希夷</span>

                        <div>Day2(重义)在一个周日/一周的最后一天,我来到位于市中心/市区繁华地带的一家购物中心/商场,中心内人很多/熙熙攘攘。我注意到/看见一个独行/孤身一人的年轻女孩/,留着一头引人注目/长过腰际的头发,上身穿一件暗红色/比正红色更深的衣服/穿在身体上的东西。走下扶梯的时候,她摔倒了/跌向地面,在她正要站起来/让身体离开地面的时候,过长/超过一般人长度的头发被支撑身体/躯干的手掌压/按在下面,她赶紧用</div>
                    </li>
                    <li><a href="/article/1835507739820912640.htm"
                           title="2018-07-23-催眠日作业-#不一样的31天#-66小鹿" target="_blank">2018-07-23-催眠日作业-#不一样的31天#-66小鹿</a>
                        <span class="text-muted">小鹿_33</span>

                        <div>预言日:人总是在逃避命运的路上,与之不期而遇。心理学上有个著名的名词,叫做自证预言;经济学上也有一个很著名的定律叫做,墨菲定律;在灵修派上,还有一个很著名的法则,叫做吸引力法则。这3个领域的词,虽然看起来不太一样,但是他们都在告诉人们一个现象:你越担心什么,就越有可能会发生什么。同样的道理,你越想得到什么,就应该要积极地去创造什么。无论是自证预言,墨菲定律还是吸引力法则,对人都有正反2个维度的影响</div>
                    </li>
                    <li><a href="/article/1835507358353158144.htm"
                           title="《大清方方案》| 第二话" target="_blank">《大清方方案》| 第二话</a>
                        <span class="text-muted">谁佐清欢</span>

                        <div>和珅究竟说了些什么?竟能令堂堂九五之尊龙颜失色!此处暂且按下不表;单说这位乾隆皇帝,果真不愧是康熙从小带过的,一旦决定了要做的事,便杀伐决断毫不含糊。他当即亲自拟旨,着令和珅为钦差大臣,全权负责处理方方事件,并钦赐尚方宝剑,遇急则三品以下官员可先斩后奏。和珅身负皇上重托,岂敢有半点怠慢,当夜即率领相关人等,马不停蹄杀奔江汉。这一路上,和珅的几位幕僚一直在商讨方方事件的处置方案。有位年轻幕僚建议快刀</div>
                    </li>
                    <li><a href="/article/1835507248395284480.htm"
                           title="【一起学Rust | 设计模式】习惯语法——使用借用类型作为参数、格式化拼接字符串、构造函数" target="_blank">【一起学Rust | 设计模式】习惯语法——使用借用类型作为参数、格式化拼接字符串、构造函数</a>
                        <span class="text-muted">广龙宇</span>
<a class="tag" taget="_blank" href="/search/%E4%B8%80%E8%B5%B7%E5%AD%A6Rust/1.htm">一起学Rust</a><a class="tag" taget="_blank" href="/search/%23/1.htm">#</a><a class="tag" taget="_blank" href="/search/Rust%E8%AE%BE%E8%AE%A1%E6%A8%A1%E5%BC%8F/1.htm">Rust设计模式</a><a class="tag" taget="_blank" href="/search/rust/1.htm">rust</a><a class="tag" taget="_blank" href="/search/%E8%AE%BE%E8%AE%A1%E6%A8%A1%E5%BC%8F/1.htm">设计模式</a><a class="tag" taget="_blank" href="/search/%E5%BC%80%E5%8F%91%E8%AF%AD%E8%A8%80/1.htm">开发语言</a>
                        <div>提示:文章写完后,目录可以自动生成,如何生成可参考右边的帮助文档文章目录前言一、使用借用类型作为参数二、格式化拼接字符串三、使用构造函数总结前言Rust不是传统的面向对象编程语言,它的所有特性,使其独一无二。因此,学习特定于Rust的设计模式是必要的。本系列文章为作者学习《Rust设计模式》的学习笔记以及自己的见解。因此,本系列文章的结构也与此书的结构相同(后续可能会调成结构),基本上分为三个部分</div>
                    </li>
                    <li><a href="/article/1835507105168191488.htm"
                           title="本周第二次约练" target="_blank">本周第二次约练</a>
                        <span class="text-muted">2cfbdfe28a51</span>

                        <div>中原焦点团队中24初26刘霞2021.12.3约练161次,分享第368天当事人虽然是带着问题来的,但是咨询过程中发现,她是经过自己不断地调整和努力才走到现在的,看到当事人的不容易,找到例外,发现资源,力量感也就随之而来。增强画面感,或者说重温,会给当事人带来更深刻的感受。</div>
                    </li>
                    <li><a href="/article/1835506721141911552.htm"
                           title="2022-07-08" target="_blank">2022-07-08</a>
                        <span class="text-muted">保利学府里李楚怡1307022</span>

                        <div>——保利碧桂园学府里——童梦奇趣【科学实验室】「7.9-7.10」✏玩出大智慧约99-144㎡二期全新升级力作</div>
                    </li>
                    <li><a href="/article/1835504817905168384.htm"
                           title="2019-12-22-22:30" target="_blank">2019-12-22-22:30</a>
                        <span class="text-muted">涓涓1016</span>

                        <div>今天是冬至,写下我的日更,是因为这两天的学习真的是能量的满满,让我看到了自己,未来另外一种可能性,也让我看到了这两年这几年的过程中我所接受那些痛苦的来源。一切的根源和痛苦都来自于人生,家庭,而你的原生家庭,你的爸爸和妈妈,是因为你这个灵魂在那一刻选择他们作为你的爸爸和妈妈来的,所以你得接受他,你得接纳他,他就是因为他的存在而给你的学习和成长带来这些痛苦,那其实是你必然要经历的这个过程,当你去接纳的</div>
                    </li>
                    <li><a href="/article/1835504723210366976.htm"
                           title="第四天旅游线路预览——从换乘中心到喀纳斯湖" target="_blank">第四天旅游线路预览——从换乘中心到喀纳斯湖</a>
                        <span class="text-muted">陟彼高冈yu</span>
<a class="tag" taget="_blank" href="/search/%E5%9F%BA%E4%BA%8EGoogle/1.htm">基于Google</a><a class="tag" taget="_blank" href="/search/earth/1.htm">earth</a><a class="tag" taget="_blank" href="/search/studio/1.htm">studio</a><a class="tag" taget="_blank" href="/search/%E7%9A%84%E6%97%85%E6%B8%B8%E8%A7%84%E5%88%92%E5%92%8C%E9%A2%84%E8%A7%88/1.htm">的旅游规划和预览</a><a class="tag" taget="_blank" href="/search/%E6%97%85%E6%B8%B8/1.htm">旅游</a>
                        <div>第四天:从贾登峪到喀纳斯风景区入口,晚上住宿贾登峪;换乘中心有4路车,喀纳斯①号车,去喀纳斯湖,路程时长约5分钟;将上面的的行程安排进行动态展示,具体步骤见”Googleearthstudio进行动态轨迹显示制作过程“、“Googleearthstudio入门教程”和“Googleearthstudio进阶教程“相关内容,得到行程如下所示:Day4-2-480p</div>
                    </li>
                    <li><a href="/article/1835504564879585280.htm"
                           title="直抒《紫罗兰永恒花园外传》" target="_blank">直抒《紫罗兰永恒花园外传》</a>
                        <span class="text-muted">雷姆的黑色童话</span>

                        <div>没看过《紫罗兰永恒花园》的我莫名的看完了《紫罗兰永恒花园外传》,又莫名的被故事中的姐妹之情狠狠地感动了的一把。感动何在:困苦中相依为命的姐妹二人被迫分离,用一个人的自由换取另一个人的幸福。之后,虽相隔不知几许依旧心心念念彼此牵挂。这种深深的姐妹情谊就是令我为之动容的所在。贝拉和泰勒分别影片开始,海天之间一个孩童凭栏眺望,手中拿着折旧的信纸。镜头一转,挑灯伏案的薇尔莉特正在打字机前奋笔疾书。这些片段</div>
                    </li>
                    <li><a href="/article/1835504470440636416.htm"
                           title="Goolge earth studio 进阶4——路径修改与平滑" target="_blank">Goolge earth studio 进阶4——路径修改与平滑</a>
                        <span class="text-muted">陟彼高冈yu</span>
<a class="tag" taget="_blank" href="/search/Google/1.htm">Google</a><a class="tag" taget="_blank" href="/search/earth/1.htm">earth</a><a class="tag" taget="_blank" href="/search/studio/1.htm">studio</a><a class="tag" taget="_blank" href="/search/%E8%BF%9B%E9%98%B6%E6%95%99%E7%A8%8B/1.htm">进阶教程</a><a class="tag" taget="_blank" href="/search/%E6%97%85%E6%B8%B8/1.htm">旅游</a>
                        <div>如果我们希望在大约中途时获得更多的城市鸟瞰视角。可以将相机拖动到这里并创建一个新的关键帧。camera_target_clip_7EarthStudio会自动平滑我们的路径,所以当我们通过这个关键帧时,不是一个生硬的角度,而是一个平滑的曲线。camera_target_clip_8路径上有贝塞尔控制手柄,允许我们调整路径的形状。右键单击,我们可以选择“平滑路径”,这是默认的自动平滑算法,或者我们可</div>
                    </li>
                    <li><a href="/article/1835503932999299072.htm"
                           title="相信相信的力量" target="_blank">相信相信的力量</a>
                        <span class="text-muted">孙丽_cdb3</span>

                        <div>孙丽中级十期坚持分享第345天有一个特别有哲理的故事:有一只老鹰下了蛋,这个蛋,不知怎的就滚到了鸡窝里去了,鸡也下了一窝蛋,然后鸡妈妈把这些蛋全都浮出来了,孵出来之后等小鸡长大一点了,就觉得鹰蛋孵出来的那只小鹰怪模怪样,这些小鸡都嘲笑它,真难看,真笨,丑死了,那只小鹰觉得自己真是谁也不像,真是不好看,后来鸡妈妈也不喜欢他,我怎么生出你这样的孩子来了?真烦人,后来这群小鸡和小鹰一起生活,有一天,老鹰</div>
                    </li>
                    <li><a href="/article/1835503548817829888.htm"
                           title="今天我破防了" target="_blank">今天我破防了</a>
                        <span class="text-muted">sin信仰</span>

                        <div>今天本来是大年初一,新年的第一天,应该是高高兴兴的一天,但是我怎么也高兴不起来。具体原因很简单,原本计划年后去县城找了一份会计的工作,被公公婆婆否定了,我心里立马就不舒服了,但是当时刚好肚子疼,我去了厕所,等我上完厕所,公公由于喝了酒还在那里和婆婆唠叨个没完。然后我就在心情极度压抑的情况下把午饭吃完的碗筷和锅给刷了。边刷碗筷和锅,边在那里难受,感觉自己在这个家里真的是过的憋屈死了,公婆不让我去上班</div>
                    </li>
                    <li><a href="/article/1835502451877310464.htm"
                           title="基于社交网络算法优化的二维最大熵图像分割" target="_blank">基于社交网络算法优化的二维最大熵图像分割</a>
                        <span class="text-muted">智能算法研学社(Jack旭)</span>
<a class="tag" taget="_blank" href="/search/%E6%99%BA%E8%83%BD%E4%BC%98%E5%8C%96%E7%AE%97%E6%B3%95%E5%BA%94%E7%94%A8/1.htm">智能优化算法应用</a><a class="tag" taget="_blank" href="/search/%E5%9B%BE%E5%83%8F%E5%88%86%E5%89%B2/1.htm">图像分割</a><a class="tag" taget="_blank" href="/search/%E7%AE%97%E6%B3%95/1.htm">算法</a><a class="tag" taget="_blank" href="/search/php/1.htm">php</a><a class="tag" taget="_blank" href="/search/%E5%BC%80%E5%8F%91%E8%AF%AD%E8%A8%80/1.htm">开发语言</a>
                        <div>智能优化算法应用:基于社交网络优化的二维最大熵图像阈值分割-附代码文章目录智能优化算法应用:基于社交网络优化的二维最大熵图像阈值分割-附代码1.前言2.二维最大熵阈值分割原理3.基于社交网络优化的多阈值分割4.算法结果:5.参考文献:6.Matlab代码摘要:本文介绍基于最大熵的图像分割,并且应用社交网络算法进行阈值寻优。1.前言阅读此文章前,请阅读《图像分割:直方图区域划分及信息统计介绍》htt</div>
                    </li>
                    <li><a href="/article/1835501774031646720.htm"
                           title="18-115 一切思考不能有效转化为行动,都TM是扯淡!" target="_blank">18-115 一切思考不能有效转化为行动,都TM是扯淡!</a>
                        <span class="text-muted">成长时间线</span>

                        <div>7月25号写了一篇关于为什么会断更如此严重的反思,然而,之后日更仅仅维持了一周,又出现了这次更严重的现象。从8月2号到昨天8月6号,5天!又是5天没有更文!虽然这次断更时间和上次一样,那为什么说这次更严重?因为上次之后就分析了问题的原因,以及应该如何解决,按理说应该会好转,然而,没过几天严重断更的现象再次出现,想想,经过反思,问题依然没有解决与改变,这让我有些担忧。到底是哪里出了问题,难道我就真的</div>
                    </li>
                    <li><a href="/article/1835501383751659520.htm"
                           title="《中华小厨师》单行VS爱藏:姜是老的辣,书是新的好" target="_blank">《中华小厨师》单行VS爱藏:姜是老的辣,书是新的好</a>
                        <span class="text-muted">cicoky</span>

                        <div>《汉书·郦食其传》有曰:“王者以民为天,而民以食为天。”自古以来,吃饱饭是每一个人的基本要求,而吃好饭却是每一个人的最终追求。于是,厨师这一职业孕育而生,其渊源之久,甚至可追溯到4000年前的奴隶时代。职业本身无贵贱,但职业能力却有高低之分。所以一家餐馆生意好不好,厨师的水平决定一切,而站在所有厨师顶端的就被称之为“特级厨师”。今天要说的就是一个关于“特级厨师刘昴星”的故事。连载历程1995年第4</div>
                    </li>
                    <li><a href="/article/1835499868454481920.htm"
                           title="读《人世间》有感" target="_blank">读《人世间》有感</a>
                        <span class="text-muted">一0一</span>

                        <div>这个寒假,就如同朋友圈中的一段话:一闭眼,一睁眼假期还有5天,在一闭眼一睁眼假期还有12天;再一闭眼一睁眼假期还有20天;不敢睡,不敢睡啊……受疫情影响,这个假期变得漫长又煎熬,我也无时无刻不关注着疫情的变化。当然这样的一个假期,我还真得要感谢周翔,因为他有个爱看书的习惯,所以家里有不少他看过的书,可以让我随意挑选,因此也让我的假期不至于那么无所事事。这次我选了一本梁晓声的《人世间》,作为一名语文</div>
                    </li>
                    <li><a href="/article/1835499109436452864.htm"
                           title="如果做到轻松在股市赚钱?只要坚持这三个原则。" target="_blank">如果做到轻松在股市赚钱?只要坚持这三个原则。</a>
                        <span class="text-muted">履霜之人</span>

                        <div>大A股里向来就有七亏二平一赚的说法,能赚钱的都是少数人。否则股市就成了慈善机构,人人都有钱赚,谁还要上班?所以说亏钱是正常的,或者说是应该的。那么那些赚钱的人又是如何做到的呢?普通人能不能找到捷径去分一杯羹呢?方法是有的,但要做到需要你有极高的自律。第一,控制仓位,散户最大的问题是追涨杀跌,只要涨起来,就把钱往股票上砸,然后被套,隔天跌的受不了,又一刀切,全部割肉。来来回回间,遍体鳞伤。所以散户首</div>
                    </li>
                    <li><a href="/article/1835498925755297792.htm"
                           title="DIV+CSS+JavaScript技术制作网页(旅游主题网页设计与制作)云南大理" target="_blank">DIV+CSS+JavaScript技术制作网页(旅游主题网页设计与制作)云南大理</a>
                        <span class="text-muted">STU学生网页设计</span>
<a class="tag" taget="_blank" href="/search/%E7%BD%91%E9%A1%B5%E8%AE%BE%E8%AE%A1/1.htm">网页设计</a><a class="tag" taget="_blank" href="/search/%E6%9C%9F%E6%9C%AB%E7%BD%91%E9%A1%B5%E4%BD%9C%E4%B8%9A/1.htm">期末网页作业</a><a class="tag" taget="_blank" href="/search/html%E9%9D%99%E6%80%81%E7%BD%91%E9%A1%B5/1.htm">html静态网页</a><a class="tag" taget="_blank" href="/search/html5%E6%9C%9F%E6%9C%AB%E5%A4%A7%E4%BD%9C%E4%B8%9A/1.htm">html5期末大作业</a><a class="tag" taget="_blank" href="/search/%E7%BD%91%E9%A1%B5%E8%AE%BE%E8%AE%A1/1.htm">网页设计</a><a class="tag" taget="_blank" href="/search/web%E5%A4%A7%E4%BD%9C%E4%B8%9A/1.htm">web大作业</a>
                        <div>️精彩专栏推荐作者主页:【进入主页—获取更多源码】web前端期末大作业:【HTML5网页期末作业(1000套)】程序员有趣的告白方式:【HTML七夕情人节表白网页制作(110套)】文章目录二、网站介绍三、网站效果▶️1.视频演示2.图片演示四、网站代码HTML结构代码CSS样式代码五、更多源码二、网站介绍网站布局方面:计划采用目前主流的、能兼容各大主流浏览器、显示效果稳定的浮动网页布局结构。网站程</div>
                    </li>
                    <li><a href="/article/1835498602294767616.htm"
                           title="特殊的拜年" target="_blank">特殊的拜年</a>
                        <span class="text-muted">飘雪的天堂</span>

                        <div>文/雪儿大年初一,家家户户没有了轰响的鞭炮声,大街上没有了人流涌动的喧闹,几乎看不到人影,变得冷冷清清。天刚亮不大会儿,村里的大喇叭响了起来:由于当前正值疾病高发期,流感流行的高峰期。同时,新型冠状病毒感染的肺炎进入第二波流行的上升期。为了自己和他人的健康安全着想,请大家尽量不要串门拜年,不要在街里走动。可以通过手机微信,视频,电话,信息拜年……今年的春节真是特别。禁止燃放鞭炮,烟花爆竹,禁止出村</div>
                    </li>
                    <li><a href="/article/1835497965330984960.htm"
                           title="398顺境,逆境" target="_blank">398顺境,逆境</a>
                        <span class="text-muted">戴骁勇</span>

                        <div>2018.11.27周二雾霾最近儿子进入了一段顺境期,今天表现尤其不错。今天的数学测试成绩喜人,没有出现以往的计算错误,整个卷面书写工整,附加题也在规定时间内完成且做对。为迎接体育测试的锻炼有了质的飞跃。坐位体前屈成绩突飞猛进,估测成绩能达到12cm,这和上次测试的零分来比,简直是逆袭。儿子还在不断锻炼和提升,唯恐到时候掉链子。跑步姿势在我的调教下,逐渐正规起来,速度随之也有了提升。今晚测试的50</div>
                    </li>
                    <li><a href="/article/1835497077891756032.htm"
                           title="想明白这个问题,你才能写下去" target="_blank">想明白这个问题,你才能写下去</a>
                        <span class="text-muted">文自拾</span>

                        <div>春节放假的时候,又有一天梦见她,第二天她冒着漫天大雪,傻傻地跑来见我。她说,见见傻傻的我,天很冷,心很暖。她回去后,我写了一篇文章,题目叫——从此梦中只有你。我们没在一起的很长一段时间里,她都在我的心底,一次次出现在我的梦里。我对她说,在一起之前,是胆小且闷骚,在一起之后,我变得不要脸了。不要脸的——去爱你。那文章没写完,火车上,给她看了。我有点小失望,花了好几个小时写,她分分钟就看完,很希望她逐</div>
                    </li>
                                <li><a href="/article/128.htm"
                                       title="scala的option和some" target="_blank">scala的option和some</a>
                                    <span class="text-muted">矮蛋蛋</span>
<a class="tag" taget="_blank" href="/search/%E7%BC%96%E7%A8%8B/1.htm">编程</a><a class="tag" taget="_blank" href="/search/scala/1.htm">scala</a>
                                    <div>原文地址: 
http://blog.sina.com.cn/s/blog_68af3f090100qkt8.html 
对于学习 Scala 的 Java™ 开发人员来说,对象是一个比较自然、简单的入口点。在 本系列 前几期文章中,我介绍了 Scala 中一些面向对象的编程方法,这些方法实际上与 Java 编程的区别不是很大。我还向您展示了 Scala 如何重新应用传统的面向对象概念,找到其缺点</div>
                                </li>
                                <li><a href="/article/255.htm"
                                       title="NullPointerException" target="_blank">NullPointerException</a>
                                    <span class="text-muted">Cb123456</span>
<a class="tag" taget="_blank" href="/search/android/1.htm">android</a><a class="tag" taget="_blank" href="/search/BaseAdapter/1.htm">BaseAdapter</a>
                                    <div>  
  java.lang.NullPointerException: Attempt to invoke virtual method 'int android.view.View.getImportantForAccessibility()' on a null object reference 
  
  出现以上异常.然后就在baidu上</div>
                                </li>
                                <li><a href="/article/382.htm"
                                       title="PHP使用文件和目录" target="_blank">PHP使用文件和目录</a>
                                    <span class="text-muted">天子之骄</span>
<a class="tag" taget="_blank" href="/search/php%E6%96%87%E4%BB%B6%E5%92%8C%E7%9B%AE%E5%BD%95/1.htm">php文件和目录</a><a class="tag" taget="_blank" href="/search/%E8%AF%BB%E5%8F%96%E5%92%8C%E5%86%99%E5%85%A5/1.htm">读取和写入</a><a class="tag" taget="_blank" href="/search/php%E9%AA%8C%E8%AF%81%E6%96%87%E4%BB%B6/1.htm">php验证文件</a><a class="tag" taget="_blank" href="/search/php%E9%94%81%E5%AE%9A%E6%96%87%E4%BB%B6/1.htm">php锁定文件</a>
                                    <div>PHP使用文件和目录 
1.使用include()包含文件 
(1):使用include()从一个被包含文档返回一个值 
(2):在控制结构中使用include() 
  
include_once()函数需要一个包含文件的路径,此外,第一次调用它的情况和include()一样,如果在脚本执行中再次对同一个文件调用,那么这个文件不会再次包含。 
  
在php.ini文件中设置</div>
                                </li>
                                <li><a href="/article/509.htm"
                                       title="SQL SELECT DISTINCT 语句" target="_blank">SQL SELECT DISTINCT 语句</a>
                                    <span class="text-muted">何必如此</span>
<a class="tag" taget="_blank" href="/search/sql/1.htm">sql</a>
                                    <div>SELECT DISTINCT 语句用于返回唯一不同的值。 
 
SQL SELECT DISTINCT 语句 
在表中,一个列可能会包含多个重复值,有时您也许希望仅仅列出不同(distinct)的值。 
 
DISTINCT 关键词用于返回唯一不同的值。 
 
SQL SELECT DISTINCT 语法 
 
SELECT DISTINCT column_name,column_name 
F</div>
                                </li>
                                <li><a href="/article/636.htm"
                                       title="java冒泡排序" target="_blank">java冒泡排序</a>
                                    <span class="text-muted">3213213333332132</span>
<a class="tag" taget="_blank" href="/search/java/1.htm">java</a><a class="tag" taget="_blank" href="/search/%E5%86%92%E6%B3%A1%E6%8E%92%E5%BA%8F/1.htm">冒泡排序</a>
                                    <div>package com.algorithm;

/**
 * @Description 冒泡
 * @author FuJianyong
 * 2015-1-22上午09:58:39
 */
public class MaoPao {
	public static void main(String[] args) {
		int[] mao = {17,50,26,18,9,10</div>
                                </li>
                                <li><a href="/article/763.htm"
                                       title="struts2.18 +json,struts2-json-plugin-2.1.8.1.jar配置及问题!" target="_blank">struts2.18 +json,struts2-json-plugin-2.1.8.1.jar配置及问题!</a>
                                    <span class="text-muted">7454103</span>
<a class="tag" taget="_blank" href="/search/DAO/1.htm">DAO</a><a class="tag" taget="_blank" href="/search/spring/1.htm">spring</a><a class="tag" taget="_blank" href="/search/Ajax/1.htm">Ajax</a><a class="tag" taget="_blank" href="/search/json/1.htm">json</a><a class="tag" taget="_blank" href="/search/qq/1.htm">qq</a>
                                    <div>struts2.18  出来有段时间了! (貌似是 稳定版) 
  
闲时研究下下!  貌似 sruts2 搭配 json 做 ajax 很吃香! 
  
实践了下下! 不当之处请绕过! 呵呵 
  
网上一大堆 struts2+json  不过大多的json 插件 都是 jsonplugin.34.jar  
  
strut</div>
                                </li>
                                <li><a href="/article/890.htm"
                                       title="struts2 数据标签说明" target="_blank">struts2 数据标签说明</a>
                                    <span class="text-muted">darkranger</span>
<a class="tag" taget="_blank" href="/search/jsp/1.htm">jsp</a><a class="tag" taget="_blank" href="/search/bean/1.htm">bean</a><a class="tag" taget="_blank" href="/search/struts/1.htm">struts</a><a class="tag" taget="_blank" href="/search/servlet/1.htm">servlet</a><a class="tag" taget="_blank" href="/search/Scheme/1.htm">Scheme</a>
                                    <div>数据标签主要用于提供各种数据访问相关的功能,包括显示一个Action里的属性,以及生成国际化输出等功能 
数据标签主要包括: 
action :该标签用于在JSP页面中直接调用一个Action,通过指定executeResult参数,还可将该Action的处理结果包含到本页面来。 
bean :该标签用于创建一个javabean实例。如果指定了id属性,则可以将创建的javabean实例放入Sta</div>
                                </li>
                                <li><a href="/article/1017.htm"
                                       title="链表.简单的链表节点构建" target="_blank">链表.简单的链表节点构建</a>
                                    <span class="text-muted">aijuans</span>
<a class="tag" taget="_blank" href="/search/%E7%BC%96%E7%A8%8B%E6%8A%80%E5%B7%A7/1.htm">编程技巧</a>
                                    <div>/*编程环境WIN-TC*/ #include "stdio.h" #include "conio.h" 
#define NODE(name, key_word, help) \  Node name[1]={{NULL, NULL, NULL, key_word, help}} 
typedef struct node {  &nbs</div>
                                </li>
                                <li><a href="/article/1144.htm"
                                       title="tomcat下jndi的三种配置方式" target="_blank">tomcat下jndi的三种配置方式</a>
                                    <span class="text-muted">avords</span>
<a class="tag" taget="_blank" href="/search/tomcat/1.htm">tomcat</a>
                                    <div>jndi(Java Naming and Directory Interface,Java命名和目录接口)是一组在Java应用中访问命名和目录服务的API。命名服务将名称和对象联系起来,使得我们可以用名称 
访问对象。目录服务是一种命名服务,在这种服务里,对象不但有名称,还有属性。 
         tomcat配置</div>
                                </li>
                                <li><a href="/article/1271.htm"
                                       title="关于敏捷的一些想法" target="_blank">关于敏捷的一些想法</a>
                                    <span class="text-muted">houxinyou</span>
<a class="tag" taget="_blank" href="/search/%E6%95%8F%E6%8D%B7/1.htm">敏捷</a>
                                    <div>从网上看到这样一句话:“敏捷开发的最重要目标就是:满足用户多变的需求,说白了就是最大程度的让客户满意。” 
感觉表达的不太清楚。 
感觉容易被人误解的地方主要在“用户多变的需求”上。 
第一种多变,实际上就是没有从根本上了解了用户的需求。用户的需求实际是稳定的,只是比较多,也比较混乱,用户一般只能了解自己的那一小部分,所以没有用户能清楚的表达出整体需求。而由于各种条件的,用户表达自己那一部分时也有</div>
                                </li>
                                <li><a href="/article/1398.htm"
                                       title="富养还是穷养,决定孩子的一生" target="_blank">富养还是穷养,决定孩子的一生</a>
                                    <span class="text-muted">bijian1013</span>
<a class="tag" taget="_blank" href="/search/%E6%95%99%E8%82%B2/1.htm">教育</a><a class="tag" taget="_blank" href="/search/%E4%BA%BA%E7%94%9F/1.htm">人生</a>
                                    <div>    是什么决定孩子未来物质能否丰盛?为什么说寒门很难出贵子,三代才能出贵族?真的是父母必须有钱,才能大概率保证孩子未来富有吗?-----作者:@李雪爱与自由
    事实并非由物质决定,而是由心灵决定。一朋友富有而且修养气质很好,兄弟姐妹也都如此。她的童年时代,物质上大家都很贫乏,但妈妈总是保持生活中的美感,时不时给孩子们带回一些美好小玩意,从来不对孩子传递生活艰辛、金钱来之不易、要懂得珍惜</div>
                                </li>
                                <li><a href="/article/1525.htm"
                                       title="oracle 日期时间格式转化" target="_blank">oracle 日期时间格式转化</a>
                                    <span class="text-muted">征客丶</span>
<a class="tag" taget="_blank" href="/search/oracle/1.htm">oracle</a>
                                    <div>oracle 系统时间有 SYSDATE 与 SYSTIMESTAMP; 
SYSDATE:不支持毫秒,取的是系统时间; 
SYSTIMESTAMP:支持毫秒,日期,时间是给时区转换的,秒和毫秒是取的系统的。 
 
日期转字符窜: 
一、不取毫秒: 
TO_CHAR(SYSDATE, 'YYYY-MM-DD HH24:MI:SS') 
简要说明, 
YYYY 年 
MM   月</div>
                                </li>
                                <li><a href="/article/1652.htm"
                                       title="【Scala六】分析Spark源代码总结的Scala语法四" target="_blank">【Scala六】分析Spark源代码总结的Scala语法四</a>
                                    <span class="text-muted">bit1129</span>
<a class="tag" taget="_blank" href="/search/scala/1.htm">scala</a>
                                    <div>1. apply语法 
  
FileShuffleBlockManager中定义的类ShuffleFileGroup,定义: 
  
private class ShuffleFileGroup(val shuffleId: Int, val fileId: Int, val files: Array[File]) {
  ...
  def apply(bucketId</div>
                                </li>
                                <li><a href="/article/1779.htm"
                                       title="Erlang中有意思的bug" target="_blank">Erlang中有意思的bug</a>
                                    <span class="text-muted">bookjovi</span>
<a class="tag" taget="_blank" href="/search/erlang/1.htm">erlang</a>
                                    <div>  
代码中常有一些很搞笑的bug,如下面的一行代码被调用两次(Erlang beam) 
  
commit f667e4a47b07b07ed035073b94d699ff5fe0ba9b
Author: Jovi Zhang <bookjovi@gmail.com>
Date:   Fri Dec 2 16:19:22 2011 +0100

    erts:</div>
                                </li>
                                <li><a href="/article/1906.htm"
                                       title="移位打印10进制数转16进制-2008-08-18" target="_blank">移位打印10进制数转16进制-2008-08-18</a>
                                    <span class="text-muted">ljy325</span>
<a class="tag" taget="_blank" href="/search/java/1.htm">java</a><a class="tag" taget="_blank" href="/search/%E5%9F%BA%E7%A1%80/1.htm">基础</a>
                                    <div>
/**

 * Description 移位打印10进制的16进制形式

 * Creation Date 15-08-2008 9:00

 * @author 卢俊宇

 * @version 1.0

 *

 */

public class PrintHex {

 

    // 备选字符

    static final char di</div>
                                </li>
                                <li><a href="/article/2033.htm"
                                       title="读《研磨设计模式》-代码笔记-组合模式" target="_blank">读《研磨设计模式》-代码笔记-组合模式</a>
                                    <span class="text-muted">bylijinnan</span>
<a class="tag" taget="_blank" href="/search/java/1.htm">java</a><a class="tag" taget="_blank" href="/search/%E8%AE%BE%E8%AE%A1%E6%A8%A1%E5%BC%8F/1.htm">设计模式</a>
                                    <div>声明: 本文只为方便我个人查阅和理解,详细的分析以及源代码请移步 原作者的博客http://chjavach.iteye.com/ 
 
 
 


import java.util.ArrayList;
import java.util.List;

abstract class Component {
	
	public abstract void printStruct(Str</div>
                                </li>
                                <li><a href="/article/2160.htm"
                                       title="利用cmd命令将.class文件打包成jar" target="_blank">利用cmd命令将.class文件打包成jar</a>
                                    <span class="text-muted">chenyu19891124</span>
<a class="tag" taget="_blank" href="/search/cmd/1.htm">cmd</a><a class="tag" taget="_blank" href="/search/jar/1.htm">jar</a>
                                    <div>cmd命令打jar是如下实现: 
在运行里输入cmd,利用cmd命令进入到本地的工作盘符。(如我的是D盘下的文件有此路径 D:\workspace\prpall\WEB-INF\classes) 
现在是想把D:\workspace\prpall\WEB-INF\classes路径下所有的文件打包成prpall.jar。然后继续如下操作: 
cd D: 回车 
cd workspace/prpal</div>
                                </li>
                                <li><a href="/article/2287.htm"
                                       title="[原创]JWFD v0.96 工作流系统二次开发包 for Eclipse 简要说明" target="_blank">[原创]JWFD v0.96 工作流系统二次开发包 for Eclipse 简要说明</a>
                                    <span class="text-muted">comsci</span>
<a class="tag" taget="_blank" href="/search/eclipse/1.htm">eclipse</a><a class="tag" taget="_blank" href="/search/%E8%AE%BE%E8%AE%A1%E6%A8%A1%E5%BC%8F/1.htm">设计模式</a><a class="tag" taget="_blank" href="/search/%E7%AE%97%E6%B3%95/1.htm">算法</a><a class="tag" taget="_blank" href="/search/%E5%B7%A5%E4%BD%9C/1.htm">工作</a><a class="tag" taget="_blank" href="/search/swing/1.htm">swing</a>
                                    <div>     
 
                  JWFD v0.96 工作流系统二次开发包 for Eclipse 简要说明 
 
    &nb</div>
                                </li>
                                <li><a href="/article/2414.htm"
                                       title="SecureCRT右键粘贴的设置" target="_blank">SecureCRT右键粘贴的设置</a>
                                    <span class="text-muted">daizj</span>
<a class="tag" taget="_blank" href="/search/secureCRT/1.htm">secureCRT</a><a class="tag" taget="_blank" href="/search/%E5%8F%B3%E9%94%AE/1.htm">右键</a><a class="tag" taget="_blank" href="/search/%E7%B2%98%E8%B4%B4/1.htm">粘贴</a>
                                    <div>一般都习惯鼠标右键自动粘贴的功能,对于SecureCRT6.7.5 ,这个功能也已经是默认配置了。 
老版本的SecureCRT其实也有这个功能,只是不是默认设置,很多人不知道罢了。 
 
菜单: 
Options->Global Options ...->Terminal 
 
右边有个Mouse的选项块。 
Copy on Select 
Paste on Right/Middle</div>
                                </li>
                                <li><a href="/article/2541.htm"
                                       title="Linux 软链接和硬链接" target="_blank">Linux 软链接和硬链接</a>
                                    <span class="text-muted">dongwei_6688</span>
<a class="tag" taget="_blank" href="/search/linux/1.htm">linux</a>
                                    <div>1.Linux链接概念Linux链接分两种,一种被称为硬链接(Hard Link),另一种被称为符号链接(Symbolic Link)。默认情况下,ln命令产生硬链接。 
【硬连接】硬连接指通过索引节点来进行连接。在Linux的文件系统中,保存在磁盘分区中的文件不管是什么类型都给它分配一个编号,称为索引节点号(Inode Index)。在Linux中,多个文件名指向同一索引节点是存在的。一般这种连</div>
                                </li>
                                <li><a href="/article/2668.htm"
                                       title="DIV底部自适应" target="_blank">DIV底部自适应</a>
                                    <span class="text-muted">dcj3sjt126com</span>
<a class="tag" taget="_blank" href="/search/JavaScript/1.htm">JavaScript</a>
                                    <div><!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml&q</div>
                                </li>
                                <li><a href="/article/2795.htm"
                                       title="Centos6.5使用yum安装mysql——快速上手必备" target="_blank">Centos6.5使用yum安装mysql——快速上手必备</a>
                                    <span class="text-muted">dcj3sjt126com</span>
<a class="tag" taget="_blank" href="/search/mysql/1.htm">mysql</a>
                                    <div>第1步、yum安装mysql
[root@stonex ~]#  yum -y install mysql-server
安装结果:
Installed:
    mysql-server.x86_64 0:5.1.73-3.el6_5                   &nb</div>
                                </li>
                                <li><a href="/article/2922.htm"
                                       title="如何调试JDK源码" target="_blank">如何调试JDK源码</a>
                                    <span class="text-muted">frank1234</span>
<a class="tag" taget="_blank" href="/search/jdk/1.htm">jdk</a>
                                    <div>相信各位小伙伴们跟我一样,想通过JDK源码来学习Java,比如collections包,java.util.concurrent包。 
 
可惜的是sun提供的jdk并不能查看运行中的局部变量,需要重新编译一下rt.jar。 
 
下面是编译jdk的具体步骤: 
        1.把C:\java\jdk1.6.0_26\sr</div>
                                </li>
                                <li><a href="/article/3049.htm"
                                       title="Maximal Rectangle" target="_blank">Maximal Rectangle</a>
                                    <span class="text-muted">hcx2013</span>
<a class="tag" taget="_blank" href="/search/max/1.htm">max</a>
                                    <div>Given a 2D binary matrix filled with 0's and 1's, find the largest rectangle containing all ones and return its area. 
  
public class Solution {
    public int maximalRectangle(char[][] matrix)</div>
                                </li>
                                <li><a href="/article/3176.htm"
                                       title="Spring MVC测试框架详解——服务端测试" target="_blank">Spring MVC测试框架详解——服务端测试</a>
                                    <span class="text-muted">jinnianshilongnian</span>
<a class="tag" taget="_blank" href="/search/spring+mvc+test/1.htm">spring mvc test</a>
                                    <div>随着RESTful Web Service的流行,测试对外的Service是否满足期望也变的必要的。从Spring 3.2开始Spring了Spring Web测试框架,如果版本低于3.2,请使用spring-test-mvc项目(合并到spring3.2中了)。 
  
Spring MVC测试框架提供了对服务器端和客户端(基于RestTemplate的客户端)提供了支持。 
&nbs</div>
                                </li>
                                <li><a href="/article/3303.htm"
                                       title="Linux64位操作系统(CentOS6.6)上如何编译hadoop2.4.0" target="_blank">Linux64位操作系统(CentOS6.6)上如何编译hadoop2.4.0</a>
                                    <span class="text-muted">liyong0802</span>
<a class="tag" taget="_blank" href="/search/hadoop/1.htm">hadoop</a>
                                    <div>一、准备编译软件 
  1.在官网下载jdk1.7、maven3.2.1、ant1.9.4,解压设置好环境变量就可以用。 
    环境变量设置如下: 
  
(1)执行vim /etc/profile
(2)在文件尾部加入:
   export JAVA_HOME=/home/spark/jdk1.7
   export MAVEN_HOME=/ho</div>
                                </li>
                                <li><a href="/article/3430.htm"
                                       title="StatusBar 字体白色" target="_blank">StatusBar 字体白色</a>
                                    <span class="text-muted">pangyulei</span>
<a class="tag" taget="_blank" href="/search/status/1.htm">status</a>
                                    <div>
[[UIApplication sharedApplication] setStatusBarStyle:UIStatusBarStyleLightContent];
/*you'll also need to set UIViewControllerBasedStatusBarAppearance to NO in the plist file if you use this method</div>
                                </li>
                                <li><a href="/article/3557.htm"
                                       title="如何分析Java虚拟机死锁" target="_blank">如何分析Java虚拟机死锁</a>
                                    <span class="text-muted">sesame</span>
<a class="tag" taget="_blank" href="/search/java/1.htm">java</a><a class="tag" taget="_blank" href="/search/thread/1.htm">thread</a><a class="tag" taget="_blank" href="/search/oracle/1.htm">oracle</a><a class="tag" taget="_blank" href="/search/%E8%99%9A%E6%8B%9F%E6%9C%BA/1.htm">虚拟机</a><a class="tag" taget="_blank" href="/search/jdbc/1.htm">jdbc</a>
                                    <div>英文资料:  
Thread Dump and Concurrency Locks  
  
Thread dumps are very useful for diagnosing synchronization related problems such as deadlocks on object monitors. Ctrl-\ on Solaris/Linux or Ctrl-B</div>
                                </li>
                                <li><a href="/article/3684.htm"
                                       title="位运算简介及实用技巧(一):基础篇" target="_blank">位运算简介及实用技巧(一):基础篇</a>
                                    <span class="text-muted">tw_wangzhengquan</span>
<a class="tag" taget="_blank" href="/search/%E4%BD%8D%E8%BF%90%E7%AE%97/1.htm">位运算</a>
                                    <div>http://www.matrix67.com/blog/archives/263 
   去年年底写的关于位运算的日志是这个Blog里少数大受欢迎的文章之一,很多人都希望我能不断完善那篇文章。后来我看到了不少其它的资料,学习到了更多关于位运算的知识,有了重新整理位运算技巧的想法。从今天起我就开始写这一系列位运算讲解文章,与其说是原来那篇文章的follow-up,不如说是一个r</div>
                                </li>
                                <li><a href="/article/3811.htm"
                                       title="jsearch的索引文件结构" target="_blank">jsearch的索引文件结构</a>
                                    <span class="text-muted">yangshangchuan</span>
<a class="tag" taget="_blank" href="/search/%E6%90%9C%E7%B4%A2%E5%BC%95%E6%93%8E/1.htm">搜索引擎</a><a class="tag" taget="_blank" href="/search/jsearch/1.htm">jsearch</a><a class="tag" taget="_blank" href="/search/%E5%85%A8%E6%96%87%E6%A3%80%E7%B4%A2/1.htm">全文检索</a><a class="tag" taget="_blank" href="/search/%E4%BF%A1%E6%81%AF%E6%A3%80%E7%B4%A2/1.htm">信息检索</a><a class="tag" taget="_blank" href="/search/word%E5%88%86%E8%AF%8D/1.htm">word分词</a>
                                    <div>jsearch是一个高性能的全文检索工具包,基于倒排索引,基于java8,类似于lucene,但更轻量级。 
  
jsearch的索引文件结构定义如下: 
    1、一个词的索引由=分割的三部分组成:        第一部分是词        第二部分是这个词在多少</div>
                                </li>
                </ul>
            </div>
        </div>
    </div>

<div>
    <div class="container">
        <div class="indexes">
            <strong>按字母分类:</strong>
            <a href="/tags/A/1.htm" target="_blank">A</a><a href="/tags/B/1.htm" target="_blank">B</a><a href="/tags/C/1.htm" target="_blank">C</a><a
                href="/tags/D/1.htm" target="_blank">D</a><a href="/tags/E/1.htm" target="_blank">E</a><a href="/tags/F/1.htm" target="_blank">F</a><a
                href="/tags/G/1.htm" target="_blank">G</a><a href="/tags/H/1.htm" target="_blank">H</a><a href="/tags/I/1.htm" target="_blank">I</a><a
                href="/tags/J/1.htm" target="_blank">J</a><a href="/tags/K/1.htm" target="_blank">K</a><a href="/tags/L/1.htm" target="_blank">L</a><a
                href="/tags/M/1.htm" target="_blank">M</a><a href="/tags/N/1.htm" target="_blank">N</a><a href="/tags/O/1.htm" target="_blank">O</a><a
                href="/tags/P/1.htm" target="_blank">P</a><a href="/tags/Q/1.htm" target="_blank">Q</a><a href="/tags/R/1.htm" target="_blank">R</a><a
                href="/tags/S/1.htm" target="_blank">S</a><a href="/tags/T/1.htm" target="_blank">T</a><a href="/tags/U/1.htm" target="_blank">U</a><a
                href="/tags/V/1.htm" target="_blank">V</a><a href="/tags/W/1.htm" target="_blank">W</a><a href="/tags/X/1.htm" target="_blank">X</a><a
                href="/tags/Y/1.htm" target="_blank">Y</a><a href="/tags/Z/1.htm" target="_blank">Z</a><a href="/tags/0/1.htm" target="_blank">其他</a>
        </div>
    </div>
</div>
<footer id="footer" class="mb30 mt30">
    <div class="container">
        <div class="footBglm">
            <a target="_blank" href="/">首页</a> -
            <a target="_blank" href="/custom/about.htm">关于我们</a> -
            <a target="_blank" href="/search/Java/1.htm">站内搜索</a> -
            <a target="_blank" href="/sitemap.txt">Sitemap</a> -
            <a target="_blank" href="/custom/delete.htm">侵权投诉</a>
        </div>
        <div class="copyright">版权所有 IT知识库 CopyRight © 2000-2050 E-COM-NET.COM , All Rights Reserved.
<!--            <a href="https://beian.miit.gov.cn/" rel="nofollow" target="_blank">京ICP备09083238号</a><br>-->
        </div>
    </div>
</footer>
<!-- 代码高亮 -->
<script type="text/javascript" src="/static/syntaxhighlighter/scripts/shCore.js"></script>
<script type="text/javascript" src="/static/syntaxhighlighter/scripts/shLegacy.js"></script>
<script type="text/javascript" src="/static/syntaxhighlighter/scripts/shAutoloader.js"></script>
<link type="text/css" rel="stylesheet" href="/static/syntaxhighlighter/styles/shCoreDefault.css"/>
<script type="text/javascript" src="/static/syntaxhighlighter/src/my_start_1.js"></script>





</body>

</html>