第二十一篇 java(2)- 集合框架

集合框架

java集合框架包括 Collection 和 Map 两种,Collection 存储着对象的集合,而 Map 存储着键值对(两个对象)的映射表。

Collection

Collection下包括Set、List、Queue,各自又包含了使用不同方式的实现。

Set

Set下包括TreeSet,HashSet,LinkedHashSet。其中TreeSet基于红黑树实现。

第十八篇 python(4)-多进程

协程、线程与进程

协程、线程和进程是计算机编程中常用的并发编程概念。总的来说,协程适合于高并发、I/O 密集型的场景,可以减少线程切换的开销;线程适合于 CPU 密集型和需要实时响应的任务;而进程则适合于独立性强、资源隔离要求高的任务。在实际应用中,通常会根据任务的特点和需求选择合适的并发编程模型。

协程

协程是一种程序组件,类似于线程,但其执行过程是可中断的。
在协程中,执行可以在特定的位置暂停,并在需要时恢复。
协程通常在单个线程中运行,因此不涉及线程切换的开销,可以有效地利用系统资源。

线程

线程是操作系统能够进行运算调度的最小单位。
一个进程中可以包含多个线程,它们共享进程的内存空间和其他资源。
多线程编程允许程序同时执行多个任务,提高了程序的并发性和响应性。
线程之间的切换开销相对较小,但线程间的共享资源需要进行同步,以避免竞态条件和死锁等问题

进程

进程是程序执行时的一个实例,每个进程都有自己独立的内存空间和系统资源。
进程间相互独立,各自拥有独立的地址空间和资源,彼此之间通信需要特殊的机制。
多进程编程可以充分利用多核处理器,但进程间的切换开销相对较大,因为需要切换地址空间和资源上下文。

python如何使用协程、线程与进程

在Python中,可以使用不同的工具来实现协程、线程和进程。
在Python中,协程通常使用 asyncio 库来实现。 线程可以使用内置的 threading 模块来实现。进程可以使用 multiprocessing 模块来实现。
需要注意的是,在Python中,由于全局解释器锁(GIL)的存在,多线程并不能有效利用多核处理器。因此,如果需要充分利用多核处理器,可以考虑使用多进程。而协程则是在单个线程中实现并发的一种方式,适合于I/O密集型任务。

第十六篇 python(3)-matplotlib绘图

安装

1
2
pip install matplotlib

简单例子

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
import matplotlib.pyplot as plt

# 数据
x = [1, 2, 3, 4, 5]
y = [2, 3, 5, 7, 11]

# 绘图
plt.plot(x, y)

# 添加标题和标签
plt.title('Simple Line Plot')
plt.xlabel('X-axis')
plt.ylabel('Y-axis')

# 显示图形
plt.show()

更多例子

多个子图

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
import matplotlib.pyplot as plt
import numpy as np

# 数据
x = np.linspace(0, 10, 100)
y1 = np.sin(x)
y2 = np.cos(x)

# 创建一个包含两个子图的图形
fig, (ax1, ax2) = plt.subplots(2, 1)

# 在第一个子图中绘制正弦函数
ax1.plot(x, y1, 'r-')
ax1.set_title('Sine Function')
ax1.set_xlabel('X-axis')
ax1.set_ylabel('Y-axis')

# 在第二个子图中绘制余弦函数
ax2.plot(x, y2, 'g--')
ax2.set_title('Cosine Function')
ax2.set_xlabel('X-axis')
ax2.set_ylabel('Y-axis')

# 设置图形的整体标题
plt.suptitle('Sine and Cosine Functions')

# 自定义图形的风格
plt.style.use('ggplot')

# 调整子图的间距
plt.tight_layout()

# 显示图形
plt.show()

第九篇 python(1)-语法进阶

yield

yield可以暂停一个函数的运行,返回值给函数调用者,并使得函数可以从上次离开的地方接着运行。通常我们可以借助yield来实现一个生成器。

生成器

生成器是一个可以产生一个序列的函数,调用生成器函数会产生一个生成器对象,并不会开始启动函数,只有当执行__next__()时函数才会执行。生成器时一个一次性操作,和我们常见的列表、字典等可以迭代的对象不同,列表等是可以无限次迭代的。

装饰器

python中函数是一等对象,所以函数可以像普通变量一样当作参数传给另一个函数的,装饰器可以在不改变另一个函数的情况下用来封装另一个函数以拓展这个被封装函数的功能,有了装饰器,我们就可以抽离出大量与函数功能本身无关的雷同代码到装饰器中并继续重用。

装饰器不仅可以是函数,也可以是类。使用类装饰器主要依靠类的__call__方法。我们可以直接定义一个装饰器函数或者装饰器类,但是有个缺点是原函数的元信息不见了,比如函数的docstring__name__都会发生改变,此时我们可以使用functools.wrapswraps本身也是一个装饰器,它能把原函数的元信息拷贝到装饰器里面的函数中。

第八篇 java(1)-面向对象

类与对象

类就是用户定义好的原型,可以通过类创建对象,类中定义好了一系列的属性或者是函数。对象是真正的实体。当为一个类创建了对象,也可以说是实例化了这个类,java中有几种创建类的方式。

当只是简单地声明一个类变量时,如Object a,不同于原始变量int、double等声明变量时就分配好了内存,这样的声明方式并没有创建好一个对象,需要通过new关键字来触发类构造器,并为这个对象分配好内存。所有类都至少有一个构造函数,如果没有定义,Java编译器会自动创建一个无参构造函数。这个构造器会调用其父类的无参构造函数。

封装、继承与多态

修饰符

在介绍封装、继承与多态之前,需要先了解java中的修饰符,修饰符有两类:

一类是控制访问权限的,一类是实现其他功能的。控制访问权限的修饰符有

1
2
3
4
5
6
7
8
// 以下为类修饰符
public --任何类均可访问。
default --没有指定修饰符时的默认修饰符,只有同一个包中的类可以访问。
// 以下为属性、方法修饰符
public --任何类均可访问。
private --只有声明的类中可以访问。
protected --只有同一个包中的类和其子类可以访问。
default --没有指定修饰符时的默认修饰符,只有同一个包中的类可以访问。

实现其他功能的修饰符有:

1
2
3
4
5
6
7
8
9
10
// 以下为类修饰符
final --此类不能被其他类继承。
abstract --抽象类,此类不能用来创建对象。
// 以下为属性、方法修饰符
final --属性、方法不能被重载。
static --属性、方法属于类而不是对象。
abstract -- 只能用在抽象类中的方法上。
transient -- 序列化对象时跳过此属性和方法。
synchronized -- 此方法一次只能被一个线程访问。
volatile --此属性的值不是线程内部缓存,而是从主内存中读取。

封装

封装可以将实现细节隐藏起来,其最主要的功能在于我们能修改自己的实现代码,而不用修改那些调用我们代码的程序片段。

继承

在继承中,先了解两个概念:父类和子类,父类就是被继承的类,子类就是继承其他类的类,在jva中,继承使用extends关键字或implements关键字。java中类的继承是单一继承,一个子类只能拥有一个父类。所有 Java 的类均是由java.lang.Object 类继承而来的。通过使用关键字 extends ,子类可以继承父类的除 private 属性外所有的属性。Implements 关键字在类继承接口的情况下使用,可以多继承接口。

重写(Override)与重载(Overload)

重写(Override)

重写是子类对父类的允许访问的方法的实现过程进行重新编写!返回值和形参都不能改变。

子类在声明变量时,可以使用父类类型,这是因为在编译阶段,只是检查参数的引用类型,然而在运行时,Java 虚拟机 (JVM) 指定对象的类型并且运行该对象的方法。需要注意的是构造方法不能被重写。需要在子类中调用父类的被重写方法时,要使用 super 关键字。

重载(Overload)

重载 (overloading) 是在一个类里面,方法名字相同,而参数不同。返回类型可以相同也可以不同。构造函数是可以重载的。

多态

通过继承、重写、重载可以以多种不同的方式实现某个操作,便可以实现多态。除此之外,java中还有接口和抽象类以实现多态。

接口

接口通常以interface来声明。一个实现接口的类,必须实现接口内所描述的所有方法,否则就必须声明为抽象类。