CD-Python-JY-1809班项目阶段教学内容
开篇 - 就业形势分析
-
就业方向
- Python后端开发工程师(Python基础、Django、Flask、Tornado、Sanic、RESTful、MySQL、Redis、MongoDB、ElasticSearch/Solr)
- Web应用服务器 / 游戏后端服务器 / 移动端数据接口 / 系统支撑平台
- Python爬虫开发工程师(Python基础、常用标准库和三方库、Scrapy/PySpider、Selenium/Appium、Redis、MySQL/MongoDB、前端相关知识、HTTP(S)、TCP/IP、Charles/Fiddler/Wireshark)
- Python量化交易开发工程师(扎实的Python功底、数据结构和算法、金融知识、数字货币)
- Python数据分析工程师(Python基础、NumPy/SciPy、Pandas、Matplotlib、机器学习算法)
- Python自动化测试工程师(Python基础、软件测试基础、Linux、Shell、Selenium / Robot Framework、JMeter / LoadRunner / QTP、CI)
- Python自动化运维工程师(Python基础、Linux、Shell、Docker、paramiko、Fabric、Ansible、Saltstack、Puppet、PlayBook、Zabbix)
- Python云平台开发工程师(扎实的Python功底、OpenStack、CloudStack、Ovirt、KVM、微服务架构、Docker、K8S)
- Python后端开发工程师(Python基础、Django、Flask、Tornado、Sanic、RESTful、MySQL、Redis、MongoDB、ElasticSearch/Solr)
-
面试加分项
有自己的Github开源项目和博客。
有分布式项目/微服务架构相关经验。(Nginx、LVS、Keepalived、Zookeeper、Docker)
有项目性能调优和安全相关经验。(AB、WebBench、SysBench、JMeter、LoadRunner、QTP)
有使用行业工具和中间件的经验。(Redis、FastDFS、RabbitMQ、Zabbix、Ansible、Nagios、ElasticSearch/Solr)
熟悉前端开发相关的知识。(jQuery、Bootstrap、Vue.js、AngularJS、React)
有其他语言开发经验(项目技术栈迁移能力)。(Java、C/C++)
-
有大数据开发相关经验。(HDFS、YARN、MapReduce、HBase、Hive、Mahout、Pig、Spark、ZooKeeper)
[图片上传失败...(image-cc06ef-1558321309426)]
第01-03天:白板编程练习
所谓白板编程练习就是在纸上写代码,这个是大多数面试的必要环节,也是最容易被忽略的东西。下面罗列的内容是面试的笔试环节中出现频率较高的问题,同时对相关知识点进行了梳理。
-
数据结构和算法
算法:解决问题的方法和步骤
评价算法的好坏:渐近时间复杂度和渐近空间复杂度。
-
渐近时间复杂度的大O标记:
- - 常量时间复杂度 - 布隆过滤器 / 哈希存储
- - 对数时间复杂度 - 折半查找(二分查找)
- - 线性时间复杂度 - 顺序查找 / 桶排序
- - 对数线性时间复杂度 - 高级排序算法(归并排序、快速排序)
- - 平方时间复杂度 - 简单排序算法(选择排序、插入排序、冒泡排序)
- - 立方时间复杂度 - Floyd算法 / 矩阵乘法运算
- - 几何级数时间复杂度 - 汉诺塔
- - 阶乘时间复杂度 - 旅行经销商问题 - NP
[图片上传失败...(image-baa54a-1558321309426)]
[图片上传失败...(image-146654-1558321309426)]
-
排序算法(选择、冒泡和归并)和查找算法(顺序和折半)
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 = [] index, 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
-
使用生成式(推导式)语法生成列表、集合和字典。
例子1:将一个句子中每个单词放到列表中且每个单词首字母大写。
sentence = 'i love this world' [x.capitalize() for x in sentence.split()]
例子2:用字典中股票价格大于100元的股票构造一个新的字典。
prices = { 'AAPL': 191.88, 'GOOG': 1186.96, 'IBM': 149.24, 'ORCL': 48.44, 'ACN': 166.89, 'FB': 208.09, 'SYMC': 21.29 } prices2 = {key: value for key, value in prices.items() if value > 100} print(prices2)
例子3:嵌套的列表 - 通过列表保存多个学生多门课程的成绩。
names = ['关羽', '张飞', '赵云', '马超', '黄忠'] courses = ['语文', '数学', '英语'] # 录入五个学生三门课程的成绩 # 错误的做法 - 参考http://pythontutor.com/visualize.html#mode=edit # scores = [[0] * len(courses)] * len(names) # 正确的做法 scores = [[0] * 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模块下的高性能容器
- deque:与list类似,但底层基于双向链表实现。当需要在中间或头部插入元素时,deque比list快得多;当需要进行随机访问时,deque比list要慢。
- defaultdict:与dict类似,但是可以为新的键指定默认值的创建工厂,避免编写额外的代码来初始化键值对,比dict的setdefault方法更为高效。
- namedtuple:与元组类似,但是可以为每个成员指定名字。
from collections import namedtuple Card = namedtuple('Card', ['suite', 'face']) card = Card('红桃', 5) print(card.suite, card.face)
""" 找出序列中出现次数最多的元素 - Counter类 """ 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))
""" 可以指定元素顺序的字典 - OrderedDict """ from collections import OrderedDict fruits = {'banana': 3, 'apple': 4, 'pear': 1, 'orange': 2} print(OrderedDict(sorted(fruits.items(), key=lambda x: x[0]))) print(OrderedDict(sorted(fruits.items(), key=lambda x: x[1]))) print(OrderedDict(sorted(fruits.items(), key=lambda x: len(x[0]))))
-
常用算法:
- 穷举法 - 又称为暴力破解法,对所有的可能性进行验证,直到找到正确答案。
- 贪婪法 - 在对问题求解时,总是做出在当前看来是最好的选择,不追求最优解,快速找到满意解。
- 分治法 - 把一个复杂的问题分成两个或更多的相同或相似的子问题,再把子问题分成更小的子问题,直到可以直接求解的程度,最后将子问题的解进行合并得到原问题的解。
- 回溯法 - 回溯法又称为试探法,按选优条件向前搜索,当搜索到某一步发现原先选择并不优或达不到目标时,就退回一步重新选择。
- 动态规划 - 基本思想也是将待求解问题分解成若干个子问题,先求解并保存这些子问题的解,避免产生大量的重复运算。
穷举法例子:百钱百鸡和五人分鱼。
# 公鸡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
贪婪法例子:假设小偷有一个背包,最多能装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]
""" Python中的functools模块有一个lru_cache装饰器,也可以做类似的事情 如果愿意也可以自己写一个类似的装饰器来做同样的事情,大家可以尝试一下 """ from functools import lru_cache @lru_cache(maxsize=None) def fib(num): if num in (1, 2): return 1 return fib(num - 1) + fib(num - 2) # 查看缓存命中次数 # CacheInfo(hits=237, misses=120, maxsize=None, currsize=120) fib.cache_info()
动态规划例子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()
-
函数的使用方式
-
将函数视为“一等公民”
- 函数可以赋值给变量
- 函数可以作为函数的参数
- 函数可以作为函数的返回值
-
高阶函数的用法(
filter
、map
以及它们的替代品)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
函数)例子:一行代码实现从m到n的整数()求和。
(lambda m, n: functools.reduce(int.__add__, range(m, n + 1)))(1, 100)
例子:一行代码实现求阶乘。
(lambda num: functools.reduce(int.__mul__, range(1, num + 1), 1))(5)
-
闭包和作用域问题
Python搜索变量的LEGB顺序(LocalEmbeddedGlobalBuilt-in)
-
global
和nonlocal
关键字的作用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 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 emp_types = {'M': Manager, 'P': Programmer, 'S': Salesman} class EmployeeFactory(object): """创建员工的工厂(工厂模式 - 通过工厂实现对象使用者和对象之间的解耦合)""" @staticmethod def create(emp_type, *args, **kwargs): """创建员工""" emp = None if emp_type in emp_types: emp = emp_types[emp_type](*args, **kwargs) return emp
if __name__ == '__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()))
-
类与类之间的关系
- is-a关系:继承
- has-a关系:关联 / 聚合 / 合成
- use-a关系:依赖
-
对象的复制(深复制/深拷贝/深度克隆和浅复制/浅拷贝/影子克隆)
from copy import copy, deepcopy items0 = [1, [2, 3], [[4, 5, 6], [7, 8, 9]]] # 看看下面这些输出前后两个值是否相等 items1 = items0 print(id(items0), id(items1)) items2 = items1[:] print(id(items1), id(items2)) print(id(items1[0]), id(items2[0])) print(id(items1[1]), id(items2[1])) print(id(items1[2][0]), id(items2[2][0])) print('-' * 25) items3 = copy(items1) print(id(items1), id(items3)) print(id(items1[0]), id(items3[0])) print(id(items1[1]), id(items3[1])) print(id(items1[2][0]), id(items3[2][0])) print('-' * 25) items4 = deepcopy(items1) print(id(items1), id(items4)) print(id(items1[0]), id(items4[0])) print(id(items1[1]), id(items4[1])) print(id(items1[2][0]), id(items4[2][0]))
-
垃圾回收、循环引用和弱引用
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 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()
说明:多线程和多进程的比较。
以下情况需要使用多线程:
- 程序需要维护许多共享的状态(尤其是可变状态),Python中的列表、字典、集合都是线程安全的,所以使用线程而不是进程维护共享状态的代价相对较小。
- 程序会花费大量时间在I/O操作上,没有太多并行计算的需求且不需占用太多的内存。
以下情况需要使用多进程:
- 程序执行计算密集型任务(如:字节码操作、数据处理、科学计算)。
- 程序的输入可以并行的分成块,并且可以将运算结果合并。
- 程序在内存使用方面没有任何限制且不强依赖于I/O操作(如:读写文件、套接字等)。
-
异步处理:从调度程序的任务队列中挑选任务,该调度程序以交叉的形式执行这些任务,我们并不能保证任务将以某种顺序去执行,因为执行顺序取决于队列中的一项任务是否愿意将CPU处理时间让位给另一项任务。异步任务通常通过多任务协作处理的方式来实现,由于执行时间和顺序的不确定,因此需要通过回调式编程或者
future
对象来获取任务执行的结果。Python 3通过asyncio
模块和await
和async
关键字(在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是Python编写的分布式任务队列,它使用分布式消息进行工作,可以基于RabbitMQ或Redis来作为后端的消息代理,这个内容我们会在项目中讲到。</p> </li> </ul> </li> </ol> <h3>第04天:团队开发和项目选题</h3> <ol> <li> <p>软件过程模型</p> <ul> <li> <p>经典过程模型(瀑布模型)</p> <ul> <li>可行性分析(研究做还是不做),输出《可行性分析报告》。</li> <li>需求分析(研究做什么),输出《需求规格说明书》和产品界面原型图。</li> <li>概要设计和详细设计,输出概念模型图、物理模型图、类图、时序图等。</li> <li>编码 / 测试。</li> <li>上线 / 维护。</li> </ul> </li> <li> <p>敏捷开发(Scrum)</p> <ul> <li>产品的Backlog(用户故事、产品原型)。</li> <li>计划会议(评估、预算、进度)。</li> <li>日常开发(站立会议、番茄工作法、结对编程、测试先行、代码重构……)。</li> <li>修复bug(问题描述、重现步骤、测试人员、被指派人)。</li> <li>评审会议(Showcase)。</li> <li>回顾会议(当前周期做得好和不好的地方)。</li> </ul> <blockquote> <p>补充:敏捷软件开发宣言</p> <ul> <li> <strong>个体和互动</strong> 高于 流程和工具</li> <li> <strong>工作的软件</strong> 高于 详尽的文档</li> <li> <strong>客户合作</strong> 高于 合同谈判</li> <li> <strong>响应变化</strong> 高于 遵循计划</li> </ul> </blockquote> </li> </ul> <p>[图片上传失败...(image-af7c78-1558321309426)]</p> <blockquote> <p>角色:产品所有者(决定做什么,能对需求拍板的人)、团队负责人(解决各种问题,专注如何更好的工作,屏蔽外部对开发团队的影响)、开发团队(项目执行人员,具体指开发人员和测试人员)</p> <p>准备工作:商业案例和资金、合同、憧憬、初始产品需求、初始发布计划、入股、组建团队</p> <p>敏捷团队通常人数为8-10人。</p> <p>工作量估算:将开发任务量化,包括原型、Logo设计、UI设计、前端开发等,尽量把每个工作分解到最小任务量,最小任务量标准为工作时间不能超过两天,然后估算总体项目时间。把每个任务都贴在白板上面,白板上分三部分:to do(待完成)、in progress(进行中)和done(已完成)。</p> </blockquote> </li> <li> <p>项目团队组建</p> <ul> <li> <p>团队的构成和角色</p> <p>[图片上传失败...(image-65edd-1558321309426)]</p> </li> <li> <p>编程规范和代码审查(flake8、pylint)</p> <p>[图片上传失败...(image-2c20d-1558321309426)]</p> </li> <li><p>Python中的一些“惯例”(请参考《Python惯例-如何编写Pythonic的代码》)</p></li> <li> <p>影响代码可读性的原因:</p> <ul> <li>代码注释太少或者没有注释</li> <li>代码破坏了语言的最佳实践</li> <li>反模式编程(意大利面代码、复制-黏贴编程、自负编程、……)</li> </ul> </li> </ul> </li> <li> <p>团队开发工具介绍</p> <ul> <li>版本控制:Git、Mercury</li> <li>缺陷管理:Gitlab、Redmine </li> <li>敏捷闭环工具:禅道、JIRA </li> <li>持续集成:Jenkins、Travis-CI </li> </ul> <p>请参考《团队项目开发》。</p> </li> </ol> <h4>项目选题和理解业务</h4> <ol> <li> <p>选题范围设定</p> <ul> <li><p>CMS(用户端):新闻聚合网站、问答/分享社区、影评/书评网站等。</p></li> <li><p>MIS(用户端+管理端):KMS、KPI考核系统、HRS、CRM系统、供应链系统、仓储管理系统等。</p></li> <li><p>App后台(管理端+数据接口):二手交易类、报刊杂志类、小众电商类、新闻资讯类、旅游类、社交类、阅读类等。</p></li> <li><p>其他类型:自身行业背景和工作经验、业务容易理解和把控。</p></li> </ul> </li> <li> <p>需求理解、模块划分和任务分配</p> <ul> <li>需求理解:头脑风暴和竞品分析。</li> <li>模块划分:画思维导图(XMind),每个模块是一个枝节点,每个具体的功能是一个叶节点(用动词表述),需要确保每个叶节点无法再生出新节点,确定每个叶子节点的重要性、优先级和工作量。</li> <li>任务分配:由项目负责人根据上面的指标为每个团队成员分配任务。</li> </ul> <p>[图片上传失败...(image-c02b5b-1558321309426)]</p> </li> <li> <p>制定项目进度表(每日更新)</p> <table> <thead> <tr> <th>模块</th> <th>功能</th> <th>人员</th> <th>状态</th> <th>完成</th> <th>工时</th> <th>计划开始</th> <th>实际开始</th> <th>计划结束</th> <th>实际结束</th> <th>备注</th> </tr> </thead> <tbody> <tr> <td>评论</td> <td>添加评论</td> <td>王大锤</td> <td>正在进行</td> <td>50%</td> <td>4</td> <td>2018/8/7</td> <td></td> <td>2018/8/7</td> <td></td> <td></td> </tr> <tr> <td></td> <td>删除评论</td> <td>王大锤</td> <td>等待</td> <td>0%</td> <td>2</td> <td>2018/8/7</td> <td></td> <td>2018/8/7</td> <td></td> <td></td> </tr> <tr> <td></td> <td>查看评论</td> <td>白元芳</td> <td>正在进行</td> <td>20%</td> <td>4</td> <td>2018/8/7</td> <td></td> <td>2018/8/7</td> <td></td> <td>需要进行代码审查</td> </tr> <tr> <td></td> <td>评论投票</td> <td>白元芳</td> <td>等待</td> <td>0%</td> <td>4</td> <td>2018/8/8</td> <td></td> <td>2018/8/8</td> <td></td> <td></td> </tr> </tbody> </table> </li> </ol> <h3>第05天:数据库设计和OOAD</h3> <h4>概念模型和正向工程</h4> <ol> <li> <p>UML(统一建模语言)的类图</p> <p>[图片上传失败...(image-5a8dcf-1558321309426)]</p> </li> <li> <p>通过模型创建表(正向工程)</p> <pre><code class="Shell">python manage.py makemigrations app python manage.py migrate </code></pre> </li> </ol> <h4>物理模型和反向工程</h4> <ol> <li> <p>PowerDesigner</p> <p>[图片上传失败...(image-bab72e-1558321309426)]</p> </li> <li> <p>通过数据表创建模型(反向工程)</p> <pre><code class="Shell">python manage.py inspectdb > app/models.py </code></pre> </li> </ol> <h3>第06-10天:使用Django开发项目</h3> <blockquote> <p>说明:具体内容请参考《Django知识点概述》</p> </blockquote> <h4>项目开发中的公共问题</h4> <ol> <li>数据库的配置(多数据库、主从复制、数据库路由)</li> <li>缓存的配置(分区缓存、键设置、超时设置、主从复制、故障恢复(哨兵))</li> <li>日志的配置</li> <li>分析和调试(Django-Debug-ToolBar)</li> <li>好用的Python模块(日期计算、图像处理、数据加密、三方API)</li> </ol> <h4>REST API设计</h4> <ol> <li>RESTful架构 <ul> <li>理解RESTful架构</li> <li>RESTful API设计指南</li> <li>RESTful API最佳实践</li> </ul> </li> <li>API接口文档的撰写(《网络API接口设计》) <ul> <li>RAP2</li> <li>YAPI</li> </ul> </li> <li> django-REST-framework的应用</li> </ol> <h4>项目中的重点难点剖析</h4> <ol> <li>使用缓存缓解数据库压力 - Redis</li> <li>使用消息队列做解耦合和削峰 - Celery + RabbitMQ</li> </ol> <h3>第11-12天:测试和部署</h3> <h4>单元测试</h4> <ol> <li>测试的种类</li> <li>编写单元测试(unittest、pytest、nose2、tox、ddt、……)</li> <li>测试覆盖率(coverage)</li> </ol> <h4>项目部署</h4> <blockquote> <p>说明:请参考《项目部署上线指南》。</p> </blockquote> <ol> <li>部署前的准备工作 <ul> <li>关键设置(SECRET_KEY / DEBUG / ALLOWED_HOSTS / 缓存 / 数据库)</li> <li>HTTPS / CSRF_COOKIE_SECUR / SESSION_COOKIE_SECURE</li> <li>日志相关配置</li> </ul> </li> <li>Linux常用命令回顾</li> <li>Linux常用服务的安装和配置</li> <li>uWSGI/Gunicorn和Nginx的使用 <ul> <li>Gunicorn和uWSGI的比较 <ul> <li>对于不需要大量定制化的简单应用程序,Gunicorn是一个不错的选择,uWSGI的学习曲线比Gunicorn要陡峭得多,Gunicorn的默认参数就已经能够适应大多数应用程序。</li> <li>uWSGI支持异构部署。</li> <li>由于Nginx本身支持uWSGI,在线上一般都将Nginx和uWSGI捆绑在一起部署,而且uWSGI属于功能齐全且高度定制的WSGI中间件。</li> <li>在性能上,Gunicorn和uWSGI其实表现相当。</li> </ul> </li> </ul> </li> <li>虚拟化技术(Docker)</li> </ol> <h4>性能测试</h4> <blockquote> <p>说明:具体内容请参考《Django知识点概述》。</p> </blockquote> <ol> <li>AB的使用</li> <li>SQLslap的使用</li> <li>sysbench的使用</li> </ol> <h4>自动化测试</h4> <ol> <li>使用Shell和Python进行自动化测试</li> <li>使用Selenium实现自动化测试 <ul> <li>Selenium IDE</li> <li>Selenium WebDriver</li> <li>Selenium Remote Control</li> </ul> </li> <li>测试工具Robot Framework介绍</li> </ol> <h4>项目性能调优</h4> <ol> <li>数据库服务器性能调优 - 请参考《MySQL相关知识》 <ul> <li>软硬件优化</li> <li>SQL优化</li> <li>架构优化 <ul> <li>分库分表</li> <li>主从复制,读写分离</li> <li>集群架构</li> </ul> </li> </ul> </li> <li>Web服务器性能优化 <ul> <li>Nginx负载均衡配置</li> <li>Keepalived实现高可用</li> </ul> </li> <li>代码性能调优 <ul> <li>多线程</li> <li>异步化</li> </ul> </li> <li>静态资源访问优化 <ul> <li>云存储</li> <li>CDN</li> </ul> </li> </ol> <h3>结束:项目答辩和简历指导</h3> <ol> <li>Showcase</li> <li>简历指导</li> <li>面试话术</li> </ol> </article> </div> </div> </div> <!--PC和WAP自适应版--> <div id="SOHUCS" sid="1690077523578269696"></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">你可能感兴趣的:(数据结构 各种查找算法)</h4> <div id="paradigm-article-related"> <div class="recommend-post mb30"> <ul class="widget-links"> <li><a href="/article/1896276312079790080.htm" title="论文阅读笔记2" target="_blank">论文阅读笔记2</a> <span class="text-muted">sixfrogs</span> <a class="tag" taget="_blank" href="/search/%E8%AE%BA%E6%96%87%E9%98%85%E8%AF%BB%E7%AC%94%E8%AE%B0/1.htm">论文阅读笔记</a><a class="tag" taget="_blank" href="/search/%E8%AE%BA%E6%96%87%E9%98%85%E8%AF%BB/1.htm">论文阅读</a><a class="tag" taget="_blank" href="/search/cnn/1.htm">cnn</a> <div>OptimizingMemoryEfficiencyforDeepConvolutionalNeuralNetworksonGPUs1论文简介作者研究了CNN各层的访存效率,并揭示了数据结构和访存模式对CNN的性能影响。并提出了优化方法。2方法介绍2.1Benchmarks数据集:MNIST,CIFAR,ImageNetCNN:AlexNet,ZFNet,VGG2.2实验设置CPU:IntelXe</div> </li> <li><a href="/article/1896270511218946048.htm" title="Lua:Lua函数设计与实现_2024-07-14_15-37-17.Tex" target="_blank">Lua:Lua函数设计与实现_2024-07-14_15-37-17.Tex</a> <span class="text-muted">chenjj4003</span> <a class="tag" taget="_blank" href="/search/%E6%B8%B8%E6%88%8F%E5%BC%80%E5%8F%912/1.htm">游戏开发2</a><a class="tag" taget="_blank" href="/search/lua/1.htm">lua</a><a class="tag" taget="_blank" href="/search/%E5%BC%80%E5%8F%91%E8%AF%AD%E8%A8%80/1.htm">开发语言</a><a class="tag" taget="_blank" href="/search/kotlin/1.htm">kotlin</a><a class="tag" taget="_blank" href="/search/%E7%BD%91%E7%BB%9C/1.htm">网络</a><a class="tag" taget="_blank" href="/search/android/1.htm">android</a><a class="tag" taget="_blank" href="/search/%E5%BE%AE%E4%BF%A1/1.htm">微信</a> <div>Lua:Lua函数设计与实现Lua函数基础函数定义与调用在Lua中,函数是一等公民,这意味着它们可以被赋值给变量、存储在数据结构中、作为参数传递给其他函数,甚至可以作为返回值。函数定义使用function关键字,后跟函数名和参数列表,然后是函数体,最后以end结束。--定义一个函数,计算两个数的和functionsum(a,b)returna+bend--调用函数localresult=sum(5</div> </li> <li><a href="/article/1896270132410380288.htm" title="Anaconda 创建环境" target="_blank">Anaconda 创建环境</a> <span class="text-muted">aitie1479</span> <a class="tag" taget="_blank" href="/search/python/1.htm">python</a> <div>2019-03-2517:10:51Anaconda给不同的项目创建不同的环境真的非常重要,最近在使用flask的时候在base环境中安装flask-bootstrap,竟然将我原本的py3.7的conda直接删除,完全降到了py2。最后只能重新安装anaconda。这个事件给我一个启示就是尽量不要在初始环境中安装各种包,而是使用anaconda的环境,来给不同的项目分配各自的环境。Anacond</div> </li> <li><a href="/article/1896264330630983680.htm" title="LangChain学习笔记" target="_blank">LangChain学习笔记</a> <span class="text-muted">xiaomu_347</span> <a class="tag" taget="_blank" href="/search/LLM%E2%80%94%E2%80%94AIGC/1.htm">LLM——AIGC</a><a class="tag" taget="_blank" href="/search/%E5%AD%A6%E4%B9%A0/1.htm">学习</a><a class="tag" taget="_blank" href="/search/%E7%AC%94%E8%AE%B0/1.htm">笔记</a> <div>LangChain是一个用来开发大型语言模型(LLM)应用的框架,为了简化构建基于LLM的应用,它能够为开发LLM应用带来如下能力:根据给定的Prompt方便构建上下文,并连接到LLM,得到更加符合查询的回答结果在构建整个基于LLM的应用提供各种工具,如各种模块(Modules)、LCEL、LangGraph等提供工具支持,使用户自己的LLM应用从原型版本到上线到生产环境过程中,一站式的调试、测试</div> </li> <li><a href="/article/1896262184338518016.htm" title="LangChain解锁LLM大语言模型的结构化输出能力:调用 with_structured_output() 方法" target="_blank">LangChain解锁LLM大语言模型的结构化输出能力:调用 with_structured_output() 方法</a> <span class="text-muted">晨欣</span> <a class="tag" taget="_blank" href="/search/langchain/1.htm">langchain</a><a class="tag" taget="_blank" href="/search/%E8%AF%AD%E8%A8%80%E6%A8%A1%E5%9E%8B/1.htm">语言模型</a><a class="tag" taget="_blank" href="/search/%E4%BA%BA%E5%B7%A5%E6%99%BA%E8%83%BD/1.htm">人工智能</a> <div>什么是LLM的结构化输出能力?在一些工业级LLM应用或比较复杂的LLM应用编排环节,我们需要用LLM的输出作为下一环节的输入,而这个过程往往对LLM输出的格式有一定要求,比如JSON、XML、YAML、CSV、Markdown表格和HTML等比较常见的格式。因此我们需要通过各种方式手段让LLM具备符合我们期望的结构化输出能力,即模型能够按照用户指定的格式或规则生成内容(而不仅仅是自由形式的文本)的</div> </li> <li><a href="/article/1896233685754114048.htm" title="FastAdmin 与其他后台框架的对比分析" target="_blank">FastAdmin 与其他后台框架的对比分析</a> <span class="text-muted">奥顺</span> <a class="tag" taget="_blank" href="/search/php/1.htm">php</a><a class="tag" taget="_blank" href="/search/sqlite/1.htm">sqlite</a><a class="tag" taget="_blank" href="/search/%E6%95%B0%E6%8D%AE%E5%BA%93/1.htm">数据库</a> <div>FastAdmin与其他后台框架的对比分析引言在现代Web开发中,后台管理系统是支持各种应用程序的核心部分。随着需求的多样化,许多后台框架应运而生。本文将对FastAdmin与其他常见后台框架(如DjangoAdmin、LaravelNova、AdminLTE)进行对比分析,以帮助开发者选择合适的工具。FastAdmin简介FastAdmin是一个基于ThinkPHP框架的后台管理系统,提供了快速</div> </li> <li><a href="/article/1896222204018880512.htm" title="代码随想录刷题day34|(二叉树篇)二叉树的递归遍历" target="_blank">代码随想录刷题day34|(二叉树篇)二叉树的递归遍历</a> <span class="text-muted">花鱼白羊</span> <a class="tag" taget="_blank" href="/search/%E6%88%91%E7%88%B1%E7%AE%97%E6%B3%95%EF%BC%81%E6%88%91%E7%88%B1%E5%88%B7%E9%A2%98%EF%BC%81/1.htm">我爱算法!我爱刷题!</a><a class="tag" taget="_blank" href="/search/%E7%AE%97%E6%B3%95/1.htm">算法</a> <div>目录一、二叉树理论基础二、递归遍历思路三、相关算法题目四、总结一、二叉树理论基础二叉树是一种基本数据结构,TreeMap和TreeSet的底层实现使用了红黑树;基础知识详见:代码随想录(programmercarl.com)1.二叉树的种类:完全二叉树、平衡二叉搜索树、满二叉树、二叉搜索树2.二叉树的遍历方式:深度优先遍历(前序遍历、中序遍历、后序遍历)、广度优先遍历(层次遍历)3.二叉树的存储方</div> </li> <li><a href="/article/1896210741011214336.htm" title="IoT嵌入式硬件--晶振" target="_blank">IoT嵌入式硬件--晶振</a> <span class="text-muted">「已注销」</span> <a class="tag" taget="_blank" href="/search/%E5%8D%95%E7%89%87%E6%9C%BA/1.htm">单片机</a><a class="tag" taget="_blank" href="/search/%E5%B5%8C%E5%85%A5%E5%BC%8F/1.htm">嵌入式</a><a class="tag" taget="_blank" href="/search/%E4%BA%BA%E5%B7%A5%E6%99%BA%E8%83%BD/1.htm">人工智能</a><a class="tag" taget="_blank" href="/search/fpga/1.htm">fpga</a><a class="tag" taget="_blank" href="/search/%E4%BC%A0%E6%84%9F%E5%99%A8/1.htm">传感器</a> <div>“在很多的IoT硬件电路里面都能看到晶振的身影,各种不同频率的,不同封装的,有高精度的,也有普通的,他们都有着共同的作用,那就是为不同的MCU或者电路提供所需要的时钟频率。本文就晶振的原理以及基本应用和选型做一个详细解说”01—晶振概述每个硬件系统里基本都有晶振,全称是叫晶体振荡器,在包含MCU的硬件电路里作用非常大,它结合MCU内部的晶振起振电路,产生MCU所必须的时钟频率,MCU的一切指令的执</div> </li> <li><a href="/article/1896209221519732736.htm" title="StrokesPlus【电脑鼠标键盘手势软件】v0.5.8.0 中文绿色便携版" target="_blank">StrokesPlus【电脑鼠标键盘手势软件】v0.5.8.0 中文绿色便携版</a> <span class="text-muted">有过~</span> <a class="tag" taget="_blank" href="/search/%E7%94%B5%E8%84%91%E8%BD%AF%E4%BB%B6/1.htm">电脑软件</a><a class="tag" taget="_blank" href="/search/%E8%AE%A1%E7%AE%97%E6%9C%BA%E5%A4%96%E8%AE%BE/1.htm">计算机外设</a> <div>前言StrokesPlus.net是一个超方便的手势识别软件,它能帮你用手势来代替鼠标和键盘操作。用起来既简单又灵活,功能还特别强大。操作起来非常简单,它有好多实用的功能,比如智能识别你写的字、设定手势操作的区域、模拟鼠标的各种动作、运行脚本、响应窗口事件、模拟按键、设置快捷键、录制宏,还有支持插件等等。有了它,你就可以轻松实现各种鼠标宏和复杂的鼠标操作啦。而且,你还可以给它分配快捷键,创建一个忽</div> </li> <li><a href="/article/1896207832886341632.htm" title="C#如何对button按钮实现进度条功能" target="_blank">C#如何对button按钮实现进度条功能</a> <span class="text-muted">凌晓峰</span> <a class="tag" taget="_blank" href="/search/C%23/1.htm">C#</a><a class="tag" taget="_blank" href="/search/c%23/1.htm">c#</a><a class="tag" taget="_blank" href="/search/windows/1.htm">windows</a><a class="tag" taget="_blank" href="/search/%E6%8C%89%E9%92%AE%E8%BF%9B%E5%BA%A6%E6%9D%A1/1.htm">按钮进度条</a><a class="tag" taget="_blank" href="/search/button%E5%AE%9E%E7%8E%B0%E8%BF%9B%E5%BA%A6%E6%9D%A1/1.htm">button实现进度条</a><a class="tag" taget="_blank" href="/search/button%E8%BF%9B%E5%BA%A6%E6%9D%A1/1.htm">button进度条</a> <div>C#如何对button按钮实现进度条功能一.单线程进度条二.多线程进度条三.使用委托和invoke方法跨线程UIl控制来实现进度条四.使用异步委托执行线程来完成进度条五.使用Async,await完成进度条在编写WinForm程序时,我们有很多时候需要用到进度条,下面我来分享一下我在处理进度条时所采用的各种方法。创建一个Winform窗体应用项目。添加一个新的窗体(progressForm.cs)</div> </li> <li><a href="/article/1896207077353779200.htm" title="redis 快速入门" target="_blank">redis 快速入门</a> <span class="text-muted">栀夏613</span> <a class="tag" taget="_blank" href="/search/%E6%95%B0%E6%8D%AE%E5%BA%93/1.htm">数据库</a><a class="tag" taget="_blank" href="/search/redis/1.htm">redis</a><a class="tag" taget="_blank" href="/search/%E6%95%B0%E6%8D%AE%E5%BA%93/1.htm">数据库</a><a class="tag" taget="_blank" href="/search/%E7%BC%93%E5%AD%98/1.htm">缓存</a> <div>目录数据库的分类NoSQL非结构化认识redis特征安装redis单机安装Docker安装redis的基本配置启动redis关闭redisredis开机自启redis客户端redis数据结构介绍基本类型String的基础操作List基本操作Set基本操作SortedSet基本操作Hash基本操作redis通用命令key的层级格式数据库的分类关系型数据库结构化数据表中存储的数据格式是一样的数据与数据</div> </li> <li><a href="/article/1896206194083688448.htm" title="二叉树的类型定义与基本操作" target="_blank">二叉树的类型定义与基本操作</a> <span class="text-muted">S01d13r</span> <a class="tag" taget="_blank" href="/search/%E7%AC%94%E8%AE%B0/1.htm">笔记</a> <div>二叉树的类型定义与基本操作树结构是一类重要的非线性数据结构,在客观世界中广泛存在。树在计算机领域中也得到了广泛的应用,尤以二叉树最为常用。本文重点讨论二叉树的基本操作。1.二叉树的类型定义二叉树通常由三个域组成:数据域、左孩子指针域和右孩子指针域。其类型定义为:typedefstructBiNode{chardata;//数据域structBiNode*lchild,*rchild;//左右孩子指</div> </li> <li><a href="/article/1896195861910712320.htm" title="Java数据结构第十六期:走进二叉树的奇妙世界(五)" target="_blank">Java数据结构第十六期:走进二叉树的奇妙世界(五)</a> <span class="text-muted">手握风云-</span> <a class="tag" taget="_blank" href="/search/Java%E6%95%B0%E6%8D%AE%E7%BB%93%E6%9E%84%E7%A7%98%E7%B1%8D/1.htm">Java数据结构秘籍</a><a class="tag" taget="_blank" href="/search/%E6%95%B0%E6%8D%AE%E7%BB%93%E6%9E%84/1.htm">数据结构</a> <div>专栏:Java数据结构秘籍个人主页:手握风云目录一、非递归实现遍历二叉树1.1.二叉树的前序遍历1.2.二叉树的中序遍历1.3.二叉树的后序遍历一、非递归实现遍历二叉树1.1.二叉树的前序遍历我们这里要使用栈来进行实现。我们反向思考一下为什么不使用队列?如下图,前序遍历肯定是先将根结点放进去,如果是队列,根结点先进先出,然后怎么去遍历右子树呢,就无法打印的顺序了。我们定义一个引用cur,只要cur</div> </li> <li><a href="/article/1896195862724407296.htm" title="如何学习训练大模型——100条建议(附详细说明)_如何训练自己的大模型_大模型如何训练" target="_blank">如何学习训练大模型——100条建议(附详细说明)_如何训练自己的大模型_大模型如何训练</a> <span class="text-muted">大耳朵爱学习</span> <a class="tag" taget="_blank" href="/search/%E4%BA%BA%E5%B7%A5%E6%99%BA%E8%83%BD/1.htm">人工智能</a><a class="tag" taget="_blank" href="/search/%E8%AF%AD%E8%A8%80%E6%A8%A1%E5%9E%8B/1.htm">语言模型</a><a class="tag" taget="_blank" href="/search/%E4%BA%A7%E5%93%81%E7%BB%8F%E7%90%86/1.htm">产品经理</a><a class="tag" taget="_blank" href="/search/%E5%A4%A7%E6%A8%A1%E5%9E%8B/1.htm">大模型</a><a class="tag" taget="_blank" href="/search/AI%E5%A4%A7%E6%A8%A1%E5%9E%8B/1.htm">AI大模型</a> <div>摘要:通过深入了解本文中的这些细节,并在实际项目中应用相关知识,将能够更好地理解和利用大模型的潜力,不仅在学术研究中,也在工程实践中。通过不断探索新方法、参与项目和保持热情,并将其应用于各种领域,从自然语言处理到计算机视觉和自动驾驶。通过不断学习、实践和探索,可以不断提升自己在深度学习领域的技能和洞察力,同时也能为社会和行业带来创新和改进。从小规模的项目和模型开始,逐渐迭代和扩展到更大的模型,逐步</div> </li> <li><a href="/article/1896195276788527104.htm" title="HarmonyOS Next 应用开发实战:构建高性能动画组件(ArkTS深度解析)" target="_blank">HarmonyOS Next 应用开发实战:构建高性能动画组件(ArkTS深度解析)</a> <span class="text-muted"></span> <a class="tag" taget="_blank" href="/search/%E5%89%8D%E7%AB%AF/1.htm">前端</a> <div>第一章案例背景与技术选型###1.1项目需求分析本案例将实现一个复杂的粒子动画登录界面,包含以下核心功能:1.动态粒子背景:300+粒子按流体力学规律运动2.智能输入框:输入时触发粒子聚散动画3.登录按钮:3D翻转交互动效4.性能优化:确保60fps流畅运行1.2技术方案设计采用ArkTS实现以下技术组合:typescript//粒子对象数据结构classParticle{x:number=0y:</div> </li> <li><a href="/article/1896183628606533632.htm" title="【C# 数据结构】队列 FIFO" target="_blank">【C# 数据结构】队列 FIFO</a> <span class="text-muted">code bean</span> <a class="tag" taget="_blank" href="/search/C%23%E6%95%B0%E6%8D%AE%E7%BB%93%E6%9E%84/1.htm">C#数据结构</a><a class="tag" taget="_blank" href="/search/c%23/1.htm">c#</a><a class="tag" taget="_blank" href="/search/%E6%95%B0%E6%8D%AE%E7%BB%93%E6%9E%84/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>目录队列的概念FIFO(First-In,First-Out)`Queue`的工作原理:示例:解释:小结:环形队列1.**FIFO?**2.**环形缓冲队列如何实现FIFO?**关键概念:3.**环形缓冲队列的工作过程**假设:操作步骤:4.**具体例子**初始状态:操作1:入队数据`A`操作2:入队数据`B`操作3:出队操作4:入队数据`C`,`D`,`E`操作5:出队操作6:入队数据`F`操作</div> </li> <li><a href="/article/1896182368658583552.htm" title="C++数据结构之数组(详解)" target="_blank">C++数据结构之数组(详解)</a> <span class="text-muted">画个逗号给明天"</span> <a class="tag" taget="_blank" href="/search/C%2B%2B%E5%B8%B8%E7%94%A8%E6%95%B0%E6%8D%AE%E7%BB%93%E6%9E%84/1.htm">C++常用数据结构</a><a class="tag" taget="_blank" href="/search/%E6%95%B0%E6%8D%AE%E7%BB%93%E6%9E%84/1.htm">数据结构</a><a class="tag" taget="_blank" href="/search/c%2B%2B/1.htm">c++</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.介绍在C++中,数组是一种基本的数据结构,用于存储相同类型的元素的集合。数组的元素在内存中是连续存储的,可以通过索引访问。下面将详细介绍C++数组的相关内容。2.数组的定义数组的定义需要指定元素的类型和数组的大小。typearrayName[arraySize];type:数组元素的类型(如int、char)等。arrayName:数组的名称。arraySize:数组的大小(必须是常量表达式)</div> </li> <li><a href="/article/1896168992901492736.htm" title="Pulsar官方文档学习笔记——架构概览" target="_blank">Pulsar官方文档学习笔记——架构概览</a> <span class="text-muted">咚伢</span> <a class="tag" taget="_blank" href="/search/%E5%AD%A6%E4%B9%A0/1.htm">学习</a><a class="tag" taget="_blank" href="/search/%E7%AC%94%E8%AE%B0/1.htm">笔记</a><a class="tag" taget="_blank" href="/search/%E6%9E%B6%E6%9E%84/1.htm">架构</a><a class="tag" taget="_blank" href="/search/%E4%BA%91%E5%8E%9F%E7%94%9F/1.htm">云原生</a><a class="tag" taget="_blank" href="/search/zookeeper/1.htm">zookeeper</a><a class="tag" taget="_blank" href="/search/%E5%88%86%E5%B8%83%E5%BC%8F/1.htm">分布式</a> <div>架构概览在最高配置下,pulsar服务应该由一个或多个pulsar集群组成。一个pulsar集群可以包括如下组件一个或多个broker。broker会将生产者的消息分派给消费者。与pulsar配置存储通信来协调各种任务。将消息存储在BookKeeper实例中(也可以叫bookie)。并且依赖zk集群执行一些特定的任务一个BookKeeper集群,由多个bookies组成。可以持久化消息(企业级分布</div> </li> <li><a href="/article/1896165081268416512.htm" title="Windows Server 2016-Windows控制台的新增功能" target="_blank">Windows Server 2016-Windows控制台的新增功能</a> <span class="text-muted">weixin_34377065</span> <div>控制台主机(支持所有字符模式的应用程序的基础代码,包括Windows命令提示符、WindowsPowerShell提示符等)已通过几种方式进行更新,以添加各种新功能。控制新功能新功能为默认启用,但可以通过"属性"界面(主要是在"选项"选项卡上)或使用这些注册表项(所有表项都是HKEY_CURRENT_USER\Console下的DWORD值)打开和关闭每个新功能或恢复到以前的控制台主机:注册表项说</div> </li> <li><a href="/article/1896156513928540160.htm" title="算法与数据结构(二叉树中的最大路径和)" target="_blank">算法与数据结构(二叉树中的最大路径和)</a> <span class="text-muted">a_j58</span> <a class="tag" taget="_blank" href="/search/%E6%95%B0%E6%8D%AE%E7%BB%93%E6%9E%84/1.htm">数据结构</a> <div>题目思路这道题我们可以考虑用递归来解决。首先设计一个maxPath函数用来递归计算二叉树中一个节点的最大贡献值,具体来说,就是以该节点为根节点的子树中寻找以该节点为起点的一条路径,使得该路径上的节点值之和最大。如果该节点为空,则最大贡献值为0。如果非空,最大贡献值就等于节点值与其子节点中的最大贡献值之和过程分析假设二叉树如下递归步骤:1.节点20:左子树:空,leftGain=0。右子树:空,ri</div> </li> <li><a href="/article/1896150589918736384.htm" title="C语言排序算法" target="_blank">C语言排序算法</a> <span class="text-muted">只有月亮知道</span> <a class="tag" taget="_blank" href="/search/%E6%8E%92%E5%BA%8F%E7%AE%97%E6%B3%95/1.htm">排序算法</a><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/%E7%AE%97%E6%B3%95/1.htm">算法</a> <div>这篇文章总结一下C语言数据结构中常见的几种排序算法。1.直接插入排序直接插入排序的算法思想是,从第二个元素开始,逐个将元素插入到已排序部分。对于每个待插入元素,从后向前扫描已排序部分,找到合适的位置并插入voidInsertSort(int*a,intn){for(inti=1;i=0)//挨个遍历判断大小{if(temp1){gap/=2;//当gap为1时,就为直接插入排序for(inti=0</div> </li> <li><a href="/article/1896144918829658112.htm" title="fluent-ffmpeg 依赖详解" target="_blank">fluent-ffmpeg 依赖详解</a> <span class="text-muted">yqcoder</span> <a class="tag" taget="_blank" href="/search/ffmpeg/1.htm">ffmpeg</a> <div>fluent-ffmpeg是一个用于在Node.js环境中与FFmpeg进行交互的强大库,它提供了流畅的API来执行各种音视频处理任务,如转码、剪辑、合并等。一、安装npminstallfluent-ffmpeg二、基本使用要使用fluent-ffmpeg,首先需要确保系统中已经安装了FFmpeg,或者使用ffmpeg-static等库提供静态的FFmpeg二进制文件。如下,展示如何将视频文件转换</div> </li> <li><a href="/article/1896125501865521152.htm" title="一篇文章搞懂C#中的泛型类/泛型方法/泛型接口" target="_blank">一篇文章搞懂C#中的泛型类/泛型方法/泛型接口</a> <span class="text-muted">方程式sunny</span> <a class="tag" taget="_blank" href="/search/C%23/1.htm">C#</a><a class="tag" taget="_blank" href="/search/c%23/1.htm">c#</a> <div>一篇文章搞懂C#中的泛型类/泛型方法/泛型接口链接:源码提起泛型类,很多人就头疼,我也头疼。在C#中这个概念很重要,重要的向定义一个int数值类型一样,但是这个内容又不像if···else那样容易理解。我花费了两天的时间,把整个知识点梳理了一遍,希望讲清楚,也当给自己做个笔记。泛型类(GenericClasses)泛型类是一种可以处理多种数据类型的数据结构或算法模板。它允许在定义类时使用一个或多个</div> </li> <li><a href="/article/1896109607030419456.htm" title="浅谈sql注入(2)" target="_blank">浅谈sql注入(2)</a> <span class="text-muted">CQMXYZ</span> <a class="tag" taget="_blank" href="/search/sql/1.htm">sql</a><a class="tag" taget="_blank" href="/search/%E6%95%B0%E6%8D%AE%E5%BA%93/1.htm">数据库</a><a class="tag" taget="_blank" href="/search/%E5%AE%89%E5%85%A8/1.htm">安全</a> <div>上次谈到了简单的几何不怎么存在了的sql注入漏洞,但是注入过程却是最为宝贵的,之后各种各样的sql注入都是根据这个改造的,现在,我们来谈谈一些注入方法吧。(上次忘说了万能钥匙or1=1)首先就是报错注入,其原理就是利用updatexml、extractvalue等一些函数的报错机制,在报错信息里回显相关数据。可以看到,这种注入适于只显示报错而不现实正确信息的注入漏洞,所以,这同样可以用盲注解决。我</div> </li> <li><a href="/article/1896106699094290432.htm" title="Java里的ArrayList和LinkedList有什么区别?" target="_blank">Java里的ArrayList和LinkedList有什么区别?</a> <span class="text-muted">java1234_小锋</span> <a class="tag" taget="_blank" href="/search/java/1.htm">java</a><a class="tag" taget="_blank" href="/search/java/1.htm">java</a><a class="tag" taget="_blank" href="/search/%E5%BC%80%E5%8F%91%E8%AF%AD%E8%A8%80/1.htm">开发语言</a> <div>大家好,我是锋哥。今天分享关于【Java里的ArrayList和LinkedList有什么区别?】面试题。希望对大家有帮助;Java里的ArrayList和LinkedList有什么区别?1000道互联网大厂Java工程师精选面试题-Java资源分享网ArrayList和LinkedList都是Java集合框架中的常用数据结构,它们都实现了List接口,但在底层实现、性能表现和使用场景上有显著区别</div> </li> <li><a href="/article/1896100390278066176.htm" title="BMC基础知识" target="_blank">BMC基础知识</a> <span class="text-muted">Boston_Chen</span> <a class="tag" taget="_blank" href="/search/%E7%AC%94%E8%AE%B0/1.htm">笔记</a> <div>介绍BMC之前需要了解一个概念,平台管理(platformmanagement)。平台管理表示的是一系列的监视和控制功能,操作的对象是系统硬件。比如通过监视系统的温度,电压,风扇、电源等等,并做相应的调节工作,以保证系统处于健康的状态。如果系统真的不正常了,可以通过复位的方式来重新启动系统。同时平台管理还负责记录各种硬件的信息和日志记录,用于提示用户和后续问题的定位。上述功能可以集成到一个控制器上</div> </li> <li><a href="/article/1896097991459139584.htm" title="PHP到底是如何和服务器各个硬件进行交互的?使用场景是什么?底层原理是什么?" target="_blank">PHP到底是如何和服务器各个硬件进行交互的?使用场景是什么?底层原理是什么?</a> <span class="text-muted">快点好好学习吧</span> <a class="tag" taget="_blank" href="/search/PHP/1.htm">PHP</a><a class="tag" taget="_blank" href="/search/php/1.htm">php</a> <div>PHP是一种服务器端脚本语言,主要用于Web开发。它通过与服务器硬件和操作系统交互来完成各种任务。1.PHP如何与服务器硬件进行交互?(1)通过操作系统PHP本身并不直接与硬件交互,而是通过操作系统的接口(如系统调用、API)间接访问硬件资源。操作系统负责管理硬件资源(如CPU、内存、硬盘、网络设备),PHP通过调用操作系统的功能来使用这些资源。(2)通过扩展模块PHP提供了大量的扩展模块(如My</div> </li> <li><a href="/article/1896097734096646144.htm" title="Qt Http文件下载功能实现" target="_blank">Qt Http文件下载功能实现</a> <span class="text-muted">秋の水</span> <a class="tag" taget="_blank" href="/search/C%2B%2B/1.htm">C++</a><a class="tag" taget="_blank" href="/search/Qt/1.htm">Qt</a><a class="tag" taget="_blank" href="/search/Widget/1.htm">Widget</a><a class="tag" taget="_blank" href="/search/qt/1.htm">qt</a><a class="tag" taget="_blank" href="/search/http/1.htm">http</a><a class="tag" taget="_blank" href="/search/c%2B%2B/1.htm">c++</a> <div>最近工作中有个通过Http下载文件的需求,于是参考Qt的官方例程,做了个工具类。可灵活应用于各种Qt项目。文章末尾贴出代码和注释。1,基础知识1.1QNetworkAccessManager网络访问API是围绕一个QNetworkAccessManager对象构建的,该对象包含它发送的请求的通用配置和设置。它包含代理和缓存配置,以及与此类问题相关的信号,以及可用于监控网络操作进度的回复信号。一个Q</div> </li> <li><a href="/article/1896096848905564160.htm" title="13个优秀的AI人工智能工具软件导航网站推荐" target="_blank">13个优秀的AI人工智能工具软件导航网站推荐</a> <span class="text-muted">m0_68282957</span> <a class="tag" taget="_blank" href="/search/%E4%BA%BA%E5%B7%A5%E6%99%BA%E8%83%BD/1.htm">人工智能</a><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/%E7%99%BE%E5%BA%A6/1.htm">百度</a> <div>人工智能(AI)是现在科技领域的热门话题,它不仅改变了我们的生活方式,也催生了许多创新的工具和应用。AI工具可以帮助我们完成各种任务,如绘画、编程、视频制作、语音合成等,让我们的工作和娱乐更加高效和有趣。但是,面对琳琅满目的AI工具,你是否感到困惑和无从下手?你是否想要找到一个方便快捷的方式,来了解和使用各种AI工具?本文就来为大家推荐几个优秀的AI工具导航网站,让你一站式地发现和体验最新最实用的</div> </li> <li><a href="/article/1896087392595537920.htm" title="深度学习框架之主流学习框架" target="_blank">深度学习框架之主流学习框架</a> <span class="text-muted">uu1224</span> <a class="tag" taget="_blank" href="/search/%E6%B7%B1%E5%BA%A6%E5%AD%A6%E4%B9%A0/1.htm">深度学习</a><a class="tag" taget="_blank" href="/search/%E5%AD%A6%E4%B9%A0/1.htm">学习</a><a class="tag" taget="_blank" href="/search/%E4%BA%BA%E5%B7%A5%E6%99%BA%E8%83%BD/1.htm">人工智能</a><a class="tag" taget="_blank" href="/search/%E6%9C%BA%E5%99%A8%E5%AD%A6%E4%B9%A0/1.htm">机器学习</a><a class="tag" taget="_blank" href="/search/%E7%A5%9E%E7%BB%8F%E7%BD%91%E7%BB%9C/1.htm">神经网络</a> <div>深度学习框架是一类专门设计用来简化和加速神经网络模型开发过程的软件工具。它们提供了构建、训练和部署神经网络所需的各种功能和库。以下是一些主流的深度学习框架及其特点:TensorFlow:由Google开发,是一个广泛使用的开源深度学习框架。它以强大的图计算模型和分布式计算能力著称,并且通过高级API如Keras,为用户提供了易于上手的开发体验。PyTorch:由Facebook开发,以其动态计算图</div> </li> <li><a href="/article/87.htm" title="面向对象面向过程" target="_blank">面向对象面向过程</a> <span class="text-muted">3213213333332132</span> <a class="tag" taget="_blank" href="/search/java/1.htm">java</a> <div>面向对象:把要完成的一件事,通过对象间的协作实现。 面向过程:把要完成的一件事,通过循序依次调用各个模块实现。 我把大象装进冰箱这件事为例,用面向对象和面向过程实现,都是用java代码完成。 1、面向对象 package bigDemo.ObjectOriented; /** * 大象类 * * @Description * @author FuJian</div> </li> <li><a href="/article/214.htm" title="Java Hotspot: Remove the Permanent Generation" target="_blank">Java Hotspot: Remove the Permanent Generation</a> <span class="text-muted">bookjovi</span> <a class="tag" taget="_blank" href="/search/HotSpot/1.htm">HotSpot</a> <div> openjdk上关于hotspot将移除永久带的描述非常详细,http://openjdk.java.net/jeps/122 JEP 122: Remove the Permanent Generation Author Jon Masamitsu Organization Oracle Created 2010/8/15 Updated 2011/</div> </li> <li><a href="/article/341.htm" title="正则表达式向前查找向后查找,环绕或零宽断言" target="_blank">正则表达式向前查找向后查找,环绕或零宽断言</a> <span class="text-muted">dcj3sjt126com</span> <a class="tag" taget="_blank" href="/search/%E6%AD%A3%E5%88%99%E8%A1%A8%E8%BE%BE%E5%BC%8F/1.htm">正则表达式</a> <div>向前查找和向后查找 1. 向前查找:根据要匹配的字符序列后面存在一个特定的字符序列(肯定式向前查找)或不存在一个特定的序列(否定式向前查找)来决定是否匹配。.NET将向前查找称之为零宽度向前查找断言。 对于向前查找,出现在指定项之后的字符序列不会被正则表达式引擎返回。 2. 向后查找:一个要匹配的字符序列前面有或者没有指定的</div> </li> <li><a href="/article/468.htm" title="BaseDao" target="_blank">BaseDao</a> <span class="text-muted">171815164</span> <a class="tag" taget="_blank" href="/search/seda/1.htm">seda</a> <div> import java.sql.Connection; import java.sql.DriverManager; import java.sql.SQLException; import java.sql.PreparedStatement; import java.sql.ResultSet; public class BaseDao { public Conn</div> </li> <li><a href="/article/595.htm" title="Ant标签详解--Java命令" target="_blank">Ant标签详解--Java命令</a> <span class="text-muted">g21121</span> <a class="tag" taget="_blank" href="/search/Java%E5%91%BD%E4%BB%A4/1.htm">Java命令</a> <div> 这一篇主要介绍与java相关标签的使用 终于开始重头戏了,Java部分是我们关注的重点也是项目中用处最多的部分。 1</div> </li> <li><a href="/article/722.htm" title="[简单]代码片段_电梯数字排列" target="_blank">[简单]代码片段_电梯数字排列</a> <span class="text-muted">53873039oycg</span> <a class="tag" taget="_blank" href="/search/%E4%BB%A3%E7%A0%81/1.htm">代码</a> <div> 今天看电梯数字排列是9 18 26这样呈倒N排列的,写了个类似的打印例子,如下: import java.util.Arrays; public class 电梯数字排列_S3_Test { public static void main(S</div> </li> <li><a href="/article/849.htm" title="Hessian原理" target="_blank">Hessian原理</a> <span class="text-muted">云端月影</span> <a class="tag" taget="_blank" href="/search/hessian%E5%8E%9F%E7%90%86/1.htm">hessian原理</a> <div>Hessian 原理分析 一. 远程通讯协议的基本原理 网络通信需要做的就是将流从一台计算机传输到另外一台计算机,基于传输协议和网络 IO 来实现,其中传输协议比较出名的有 http 、 tcp 、 udp 等等, http 、 tcp 、 udp 都是在基于 Socket 概念上为某类应用场景而扩展出的传输协</div> </li> <li><a href="/article/976.htm" title="区分Activity的四种加载模式----以及Intent的setFlags" target="_blank">区分Activity的四种加载模式----以及Intent的setFlags</a> <span class="text-muted">aijuans</span> <a class="tag" taget="_blank" href="/search/android/1.htm">android</a> <div> 在多Activity开发中,有可能是自己应用之间的Activity跳转,或者夹带其他应用的可复用Activity。可能会希望跳转到原来某个Activity实例,而不是产生大量重复的Activity。 这需要为Activity配置特定的加载模式,而不是使用默认的加载模式。 加载模式分类及在哪里配置 Activity有四种加载模式: standard singleTop</div> </li> <li><a href="/article/1103.htm" title="hibernate几个核心API及其查询分析" target="_blank">hibernate几个核心API及其查询分析</a> <span class="text-muted">antonyup_2006</span> <a class="tag" taget="_blank" href="/search/html/1.htm">html</a><a class="tag" taget="_blank" href="/search/.net/1.htm">.net</a><a class="tag" taget="_blank" href="/search/Hibernate/1.htm">Hibernate</a><a class="tag" taget="_blank" href="/search/xml/1.htm">xml</a><a class="tag" taget="_blank" href="/search/%E9%85%8D%E7%BD%AE%E7%AE%A1%E7%90%86/1.htm">配置管理</a> <div>(一) org.hibernate.cfg.Configuration类 读取配置文件并创建唯一的SessionFactory对象.(一般,程序初始化hibernate时创建.) Configuration co</div> </li> <li><a href="/article/1230.htm" title="PL/SQL的流程控制" target="_blank">PL/SQL的流程控制</a> <span class="text-muted">百合不是茶</span> <a class="tag" taget="_blank" href="/search/oracle/1.htm">oracle</a><a class="tag" taget="_blank" href="/search/PL%2FSQL%E7%BC%96%E7%A8%8B/1.htm">PL/SQL编程</a><a class="tag" taget="_blank" href="/search/%E5%BE%AA%E7%8E%AF%E6%8E%A7%E5%88%B6/1.htm">循环控制</a> <div>PL/SQL也是一门高级语言,所以流程控制是必须要有的,oracle数据库的pl/sql比sqlserver数据库要难,很多pl/sql中有的sqlserver里面没有 流程控制; 分支语句 if 条件 then 结果 else 结果 end if ; 条件语句 case when 条件 then 结果; 循环语句 loop </div> </li> <li><a href="/article/1357.htm" title="强大的Mockito测试框架" target="_blank">强大的Mockito测试框架</a> <span class="text-muted">bijian1013</span> <a class="tag" taget="_blank" href="/search/mockito/1.htm">mockito</a><a class="tag" taget="_blank" href="/search/%E5%8D%95%E5%85%83%E6%B5%8B%E8%AF%95/1.htm">单元测试</a> <div>一.自动生成Mock类 在需要Mock的属性上标记@Mock注解,然后@RunWith中配置Mockito的TestRunner或者在setUp()方法中显示调用MockitoAnnotations.initMocks(this);生成Mock类即可。二.自动注入Mock类到被测试类 &nbs</div> </li> <li><a href="/article/1484.htm" title="精通Oracle10编程SQL(11)开发子程序" target="_blank">精通Oracle10编程SQL(11)开发子程序</a> <span class="text-muted">bijian1013</span> <a class="tag" taget="_blank" href="/search/oracle/1.htm">oracle</a><a class="tag" taget="_blank" href="/search/%E6%95%B0%E6%8D%AE%E5%BA%93/1.htm">数据库</a><a class="tag" taget="_blank" href="/search/plsql/1.htm">plsql</a> <div>/* *开发子程序 */ --子程序目是指被命名的PL/SQL块,这种块可以带有参数,可以在不同应用程序中多次调用 --PL/SQL有两种类型的子程序:过程和函数 --开发过程 --建立过程:不带任何参数 CREATE OR REPLACE PROCEDURE out_time IS BEGIN DBMS_OUTPUT.put_line(systimestamp); E</div> </li> <li><a href="/article/1611.htm" title="【EhCache一】EhCache版Hello World" target="_blank">【EhCache一】EhCache版Hello World</a> <span class="text-muted">bit1129</span> <a class="tag" taget="_blank" href="/search/Hello+world/1.htm">Hello world</a> <div>本篇是EhCache系列的第一篇,总体介绍使用EhCache缓存进行CRUD的API的基本使用,更细节的内容包括EhCache源代码和设计、实现原理在接下来的文章中进行介绍 环境准备 1.新建Maven项目 2.添加EhCache的Maven依赖 <dependency> <groupId>ne</div> </li> <li><a href="/article/1738.htm" title="学习EJB3基础知识笔记" target="_blank">学习EJB3基础知识笔记</a> <span class="text-muted">白糖_</span> <a class="tag" taget="_blank" href="/search/bean/1.htm">bean</a><a class="tag" taget="_blank" href="/search/Hibernate/1.htm">Hibernate</a><a class="tag" taget="_blank" href="/search/jboss/1.htm">jboss</a><a class="tag" taget="_blank" href="/search/webservice/1.htm">webservice</a><a class="tag" taget="_blank" href="/search/ejb/1.htm">ejb</a> <div>最近项目进入系统测试阶段,全赖袁大虾领导有力,保持一周零bug记录,这也让自己腾出不少时间补充知识。花了两天时间把“传智播客EJB3.0”看完了,EJB基本的知识也有些了解,在这记录下EJB的部分知识,以供自己以后复习使用。 EJB是sun的服务器端组件模型,最大的用处是部署分布式应用程序。EJB (Enterprise JavaBean)是J2EE的一部分,定义了一个用于开发基</div> </li> <li><a href="/article/1865.htm" title="angular.bootstrap" target="_blank">angular.bootstrap</a> <span class="text-muted">boyitech</span> <a class="tag" taget="_blank" href="/search/AngularJS/1.htm">AngularJS</a><a class="tag" taget="_blank" href="/search/AngularJS+API/1.htm">AngularJS API</a><a class="tag" taget="_blank" href="/search/angular%E4%B8%AD%E6%96%87api/1.htm">angular中文api</a> <div>angular.bootstrap 描述: 手动初始化angular。 这个函数会自动检测创建的module有没有被加载多次,如果有则会在浏览器的控制台打出警告日志,并且不会再次加载。这样可以避免在程序运行过程中许多奇怪的问题发生。 使用方法: angular .</div> </li> <li><a href="/article/1992.htm" title="java-谷歌面试题-给定一个固定长度的数组,将递增整数序列写入这个数组。当写到数组尾部时,返回数组开始重新写,并覆盖先前写过的数" target="_blank">java-谷歌面试题-给定一个固定长度的数组,将递增整数序列写入这个数组。当写到数组尾部时,返回数组开始重新写,并覆盖先前写过的数</a> <span class="text-muted">bylijinnan</span> <a class="tag" taget="_blank" href="/search/java/1.htm">java</a> <div> public class SearchInShiftedArray { /** * 题目:给定一个固定长度的数组,将递增整数序列写入这个数组。当写到数组尾部时,返回数组开始重新写,并覆盖先前写过的数。 * 请在这个特殊数组中找出给定的整数。 * 解答: * 其实就是“旋转数组”。旋转数组的最小元素见http://bylijinnan.iteye.com/bl</div> </li> <li><a href="/article/2119.htm" title="天使还是魔鬼?都是我们制造" target="_blank">天使还是魔鬼?都是我们制造</a> <span class="text-muted">ducklsl</span> <a class="tag" taget="_blank" href="/search/%E7%94%9F%E6%B4%BB/1.htm">生活</a><a class="tag" taget="_blank" href="/search/%E6%95%99%E8%82%B2/1.htm">教育</a><a class="tag" taget="_blank" href="/search/%E6%83%85%E6%84%9F/1.htm">情感</a> <div>----------------------------剧透请原谅,有兴趣的朋友可以自己看看电影,互相讨论哦!!! 从厦门回来的动车上,无意中瞟到了书中推荐的几部关于儿童的电影。当然,这几部电影可能会另大家失望,并不是类似小鬼当家的电影,而是关于“坏小孩”的电影! 自己挑了两部先看了看,但是发现看完之后,心里久久不能平</div> </li> <li><a href="/article/2246.htm" title="[机器智能与生物]研究生物智能的问题" target="_blank">[机器智能与生物]研究生物智能的问题</a> <span class="text-muted">comsci</span> <a class="tag" taget="_blank" href="/search/%E7%94%9F%E7%89%A9/1.htm">生物</a> <div> 我想,人的神经网络和苍蝇的神经网络,并没有本质的区别...就是大规模拓扑系统和中小规模拓扑分析的区别.... 但是,如果去研究活体人类的神经网络和脑系统,可能会受到一些法律和道德方面的限制,而且研究结果也不一定可靠,那么希望从事生物神经网络研究的朋友,不如把</div> </li> <li><a href="/article/2373.htm" title="获取Android Device的信息" target="_blank">获取Android Device的信息</a> <span class="text-muted">dai_lm</span> <a class="tag" taget="_blank" href="/search/android/1.htm">android</a> <div> String phoneInfo = "PRODUCT: " + android.os.Build.PRODUCT; phoneInfo += ", CPU_ABI: " + android.os.Build.CPU_ABI; phoneInfo += ", TAGS: " + android.os.Build.TAGS; ph</div> </li> <li><a href="/article/2500.htm" title="最佳字符串匹配算法(Damerau-Levenshtein距离算法)的Java实现" target="_blank">最佳字符串匹配算法(Damerau-Levenshtein距离算法)的Java实现</a> <span class="text-muted">datamachine</span> <a class="tag" taget="_blank" href="/search/java/1.htm">java</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%AD%97%E7%AC%A6%E4%B8%B2%E5%8C%B9%E9%85%8D/1.htm">字符串匹配</a> <div>原文:http://www.javacodegeeks.com/2013/11/java-implementation-of-optimal-string-alignment.html------------------------------------------------------------------------------------------------------------</div> </li> <li><a href="/article/2627.htm" title="小学5年级英语单词背诵第一课" target="_blank">小学5年级英语单词背诵第一课</a> <span class="text-muted">dcj3sjt126com</span> <a class="tag" taget="_blank" href="/search/english/1.htm">english</a><a class="tag" taget="_blank" href="/search/word/1.htm">word</a> <div>long 长的 show 给...看,出示 mouth 口,嘴 write 写 use 用,使用 take 拿,带来 hand 手 clever 聪明的 often 经常 wash 洗 slow 慢的 house 房子 water 水 clean 清洁的 supper 晚餐 out 在外 face 脸,</div> </li> <li><a href="/article/2754.htm" title="macvim的使用实战" target="_blank">macvim的使用实战</a> <span class="text-muted">dcj3sjt126com</span> <a class="tag" taget="_blank" href="/search/mac/1.htm">mac</a><a class="tag" taget="_blank" href="/search/vim/1.htm">vim</a> <div>macvim用的是mac里面的vim, 只不过是一个GUI的APP, 相当于一个壳 1. 下载macvim https://code.google.com/p/macvim/ 2. 了解macvim :h vim的使用帮助信息 :h macvim </div> </li> <li><a href="/article/2881.htm" title="java二分法查找" target="_blank">java二分法查找</a> <span class="text-muted">蕃薯耀</span> <a class="tag" taget="_blank" href="/search/java%E4%BA%8C%E5%88%86%E6%B3%95%E6%9F%A5%E6%89%BE/1.htm">java二分法查找</a><a class="tag" taget="_blank" href="/search/%E4%BA%8C%E5%88%86%E6%B3%95/1.htm">二分法</a><a class="tag" taget="_blank" href="/search/java%E4%BA%8C%E5%88%86%E6%B3%95/1.htm">java二分法</a> <div>java二分法查找 >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> 蕃薯耀 2015年6月23日 11:40:03 星期二 http:/</div> </li> <li><a href="/article/3008.htm" title="Spring Cache注解+Memcached" target="_blank">Spring Cache注解+Memcached</a> <span class="text-muted">hanqunfeng</span> <a class="tag" taget="_blank" href="/search/spring/1.htm">spring</a><a class="tag" taget="_blank" href="/search/memcached/1.htm">memcached</a> <div>Spring3.1 Cache注解 依赖jar包: <!-- simple-spring-memcached --> <dependency> <groupId>com.google.code.simple-spring-memcached</groupId> <artifactId>simple-s</div> </li> <li><a href="/article/3135.htm" title="apache commons io包快速入门" target="_blank">apache commons io包快速入门</a> <span class="text-muted">jackyrong</span> <a class="tag" taget="_blank" href="/search/apache+commons/1.htm">apache commons</a> <div>原文参考 http://www.javacodegeeks.com/2014/10/apache-commons-io-tutorial.html Apache Commons IO 包绝对是好东西,地址在http://commons.apache.org/proper/commons-io/,下面用例子分别介绍: 1) 工具类 2</div> </li> <li><a href="/article/3262.htm" title="如何学习编程" target="_blank">如何学习编程</a> <span class="text-muted">lampcy</span> <a class="tag" taget="_blank" href="/search/java/1.htm">java</a><a class="tag" taget="_blank" href="/search/%E7%BC%96%E7%A8%8B/1.htm">编程</a><a class="tag" taget="_blank" href="/search/C%2B%2B/1.htm">C++</a><a class="tag" taget="_blank" href="/search/c/1.htm">c</a> <div>首先,我想说一下学习思想.学编程其实跟网络游戏有着类似的效果.开始的时候,你会对那些代码,函数等产生很大的兴趣,尤其是刚接触编程的人,刚学习第一种语言的人.可是,当你一步步深入的时候,你会发现你没有了以前那种斗志.就好象你在玩韩国泡菜网游似的,玩到一定程度,每天就是练级练级,完全是一个想冲到高级别的意志力在支持着你.而学编程就更难了,学了两个月后,总是觉得你好象全都学会了,却又什么都做不了,又没有</div> </li> <li><a href="/article/3389.htm" title="架构师之spring-----spring3.0新特性的bean加载控制@DependsOn和@Lazy" target="_blank">架构师之spring-----spring3.0新特性的bean加载控制@DependsOn和@Lazy</a> <span class="text-muted">nannan408</span> <a class="tag" taget="_blank" href="/search/Spring3/1.htm">Spring3</a> <div>1.前言。 如题。 2.描述。 @DependsOn用于强制初始化其他Bean。可以修饰Bean类或方法,使用该Annotation时可以指定一个字符串数组作为参数,每个数组元素对应于一个强制初始化的Bean。 @DependsOn({"steelAxe","abc"}) @Comp</div> </li> <li><a href="/article/3516.htm" title="Spring4+quartz2的配置和代码方式调度" target="_blank">Spring4+quartz2的配置和代码方式调度</a> <span class="text-muted">Everyday都不同</span> <a class="tag" taget="_blank" href="/search/%E4%BB%A3%E7%A0%81/1.htm">代码</a><a class="tag" taget="_blank" href="/search/%E9%85%8D%E7%BD%AE/1.htm">配置</a><a class="tag" taget="_blank" href="/search/spring4/1.htm">spring4</a><a class="tag" taget="_blank" href="/search/quartz2.x/1.htm">quartz2.x</a><a class="tag" taget="_blank" href="/search/%E5%AE%9A%E6%97%B6%E4%BB%BB%E5%8A%A1/1.htm">定时任务</a> <div>前言:这些天简直被quartz虐哭。。因为quartz 2.x版本相比quartz1.x版本的API改动太多,所以,只好自己去查阅底层API…… quartz定时任务必须搞清楚几个概念: JobDetail——处理类 Trigger——触发器,指定触发时间,必须要有JobDetail属性,即触发对象 Scheduler——调度器,组织处理类和触发器,配置方式一般只需指定触发</div> </li> <li><a href="/article/3643.htm" title="Hibernate入门" target="_blank">Hibernate入门</a> <span class="text-muted">tntxia</span> <a class="tag" taget="_blank" href="/search/Hibernate/1.htm">Hibernate</a> <div> 前言 使用面向对象的语言和关系型的数据库,开发起来很繁琐,费时。由于现在流行的数据库都不面向对象。Hibernate 是一个Java的ORM(Object/Relational Mapping)解决方案。 Hibernte不仅关心把Java对象对应到数据库的表中,而且提供了请求和检索的方法。简化了手工进行JDBC操作的流程。 如</div> </li> <li><a href="/article/3770.htm" title="Math类" target="_blank">Math类</a> <span class="text-muted">xiaoxing598</span> <a class="tag" taget="_blank" href="/search/Math/1.htm">Math</a> <div>一、Java中的数字(Math)类是final类,不可继承。 1、常数 PI:double圆周率 E:double自然对数 2、截取(注意方法的返回类型) double ceil(double d) 返回不小于d的最小整数 double floor(double d) 返回不大于d的整最大数 int round(float f) 返回四舍五入后的整数 long round</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>
-