JavaSE

Java SE

java 语言概述

JDK和JRE的关系

jdk是软件开发包,包含了jre和编译器和调试器。jre是运行时库环境,包含了jvm和java类库

编译和运行命令

javac编译 java运行
什么是字节码,字节码的好处
jvm可以理解的 代码叫字节码,字节码由java文件编译而来,字节码文件叫做class文件,class文件被jvm class loader加载,然后由解释器解释为机器码并执行
编译型 解释型语言
编译型 :编译型语言 会通过编译器将源代码一次性翻译成可被该平台执行的机器码。一般情况下,编译语言的执行速度比较快,开发效率比较低。常见的编译性语言有 C、C++、Go、Rust 等等。
解释型 :解释型语言会通过解释器一句一句的将代码解释(interpret)为机器代码后再执行。解释型语言开发效率比较快,执行速度比较慢。常见的解释性语言有 Python、JavaScript、PHP 等等。
Java 既具有`编译型`语言的特征,也具有`解释型`语言的特征。因为 Java 程序要经过先编译,后解释两个步骤,由 Java 编写的程序需要先经过编译步骤,生成字节码(.class 文件),这种字节码必须由 Java 解释器来解释执行

基本语法

关键字

int float double  long short boolean char byte

package import 
interface abstract  implements extends class enum  (类 接口)
public protect private  
 void return synchronized 
const final static volatile transient 
new this super instanceof  

try catch finally throw throws assert  (异常)

for do while if else switch case default break continue (流程控制)
 

volatile说明
public int volatile number = 0;
线程对变量进行读写,会从进程堆空间中拷贝一份变量的副本到线程栈中,操作完毕之后回刷新到进程堆中
volatile的作用是:线程对副本变量进行修改后,其他线程能够立刻同步刷新最新的数值。这个就是可见性。
transient
private transient String passwd;
关闭序列化

运算符

运算符
	1-算法运算符
		+ - + - * / % (前)++ (后)++ (前)-- (后)-- + 
	2-赋值运算符
		=  +=  -=  *=  /=  %= 
	3-比较运算符
		==   !=   >    <    >=   <=    instanceof
	4-逻辑运算符
		&  &&   |   ||   !    ^
	5-位运算符
		<<    >>    >>>   &    |    ^    ~
	6-三元运算符
		(条件表达式)? 表达式1 : 表达式2
8种基本数据类型的定义
// int 4字节   float 4字节   double 8字节    long 8字节   short 2字节   boolean 1字节    char 2字节    byte 1字节 

public void e(){
        long a=200;//200是直接量,默认为int类型这里是自动转换为弄类型
         
        /*long b=100000000000;*/
        //100000000000是个整数直接量,默认应该为int类型,但是超出了int类型的取值范围
         
        long c=1000000000000L;
        //在整数直接量后面将了一个L,表示该直接量不再默认为int类型,为long类型,所以没错
         
        /*float d=34.3;*/
        //浮点型直接量默认为double,double类型大,所以不能直接转换为float
         
        float e=34.3f;
        //在浮点数直接量后面加上一个f,表示该直接量不再默认为double,为float类型
        byte a=100;
        short b=200;
        char c=100;//注意char类型是一种特殊的int类型,可以不用写成单引号括起来的
         
        /*byte d=128;直接量128超出了byte类型的取值范围*/
         
        /*char e=-1;直接量-1不在char类型的取值范围内*/
    }
基本数据类型的自动转换 (低类型的向高类型的转换 )

在这里插入图片描述

自动转换:低类型的向高类型的转换
强制转换:高类型的向底类型转换,但可能会数据溢出或者精度丢失

流程控制

流程控制
	顺序结构
	分支结构
		if-else if - ... - else
		switch - case
		嵌套分支结构
	循环结构
		for(;;){ }
		while( ){ }
		do{ }while( )
		嵌套循环结构
	关键字:break、continue

数组

数组的定义

数据类型[] 数组名=new 数据类型[数组的长度]
数据类型[] 变量名称 = {字面值1,字面值2,字面值3…};
int[] arr = new int[10];
int[] arr = {1,2,3};

数组的遍历

通过下标遍历
 char[] chars = new char[26];
 for( int i = 0; i < chars.length; i++) 
 {
     chars[i] = (char)('A' + i); //'A' + i 是int , 需要强制转换
 }

 //循环输出
 System.out.println("===chars数组===");
 for( int i = 0; i < chars.length; i++) {//循环26次
     System.out.print(chars[i] + " ");
 }

通过foreach遍历
char[] chars = new char[26];
 for (char x: chars) {
     
 }
 
IntStream.range(0, 100).forEach(obj -> System.out.println(obj));

数组的操作

反转
//反转数组
    public  static void reverse(int[] arr){
        for (int start=0,end=arr.length-1;start<=end;start++,end--){
            int temp=arr[start];
            arr[start]=arr[end];
            arr[end]=temp;
        }
    }

Arrays工具类


//导包
import java.util.Arrays;
 
public class ArraysTest{
    public static void main(String[] args){
        //1.boolean equals(int[] a,int[] b):判断两个数组是否相等。
		int[] arr1 = new int[]{1,2,3,4};
		int[] arr2 = new int[]{1,3,2,4};
		boolean isEquals = Arrays.equals(arr1, arr2);
		
		//2.String toString(int[] a):输出数组信息。
		Arrays.toString(arr1);
		
		//3.void fill(int[] a,int val):将指定值填充到数组之中。
		Arrays.fill(arr1, 10);
 
		//4.void sort(int[] a):对数组进行排序。
		Arrays.sort(arr2);
		
		//5.int binarySearch(int[] a,int key):查找指定元素,使用二分法进行查找
		int[] arr3 = new int[]{-98,-34,2,34,54,66,79,105,210,333};
		int index = Arrays.binarySearch(arr3, 210); //返回值为负代表数组中没有该元素,返回值为正代表数组中该元素的索引值
    }
}

面向对象

类与对象

构造方法
1.与类同名
2.new 后边是构造方法
3.每个类中都有一个默认的不显示的无参构造器
4.我们的构造器是没有返回值的
5.我们的类当中是有一个或一个以上的构造函数
6.构造方法修饰符仅仅只有public private ,其他的例如任何修饰符都不能对其使用

构造器是一个创建对象时被自动调用的特殊方法,为的是初始化。构造器的名称应与类的名称一致。
当创建一个个对象时,系统会该对象的属性默认初始化,基本类型属性的值为0(数值类型),false(布尔类型),把所有的引用类型设置为null
构造器可以改变这种默认的初始化。

类的内部成员

类的内部成员
java中类的成员
    属性、方法、构造器、代码块、内部类
成员变量(属性)
    1.实例变量【String id、private String colorType】
    2.类变量/静态变量【private static String depart】加static
    3.常量【final String design="yang"】加final
    4.静态常量 [final static design="yang"] 加final static
成员方法(方法)
    1.实例方法 [public void test(){}]
    2.类方法 [public static void test(){}]

面向对象三大特征

概念
面向对象的三大特征主要为:封装、继承、多态

封装是指的是类的内部信息进行隐藏 私有化,,只能通过方法对封装的内容进行访问,提高了代码的安全性

继承是指子类继承父类的属性(实例属性 静态属性)和方法(实例方法 静态方法),提高了代码的复用性和逻辑性。

多态指的是类与类的关系,多态必备三要素:继承、重写、父类引用子类对象。对于方法来说,非静态方法和静态方法遵循编译看左边,运行看右边,对于属性来说是编译看左边,运行看左边
继承
继承
1.子类可以继承父类的属性(``实例变量,静态变量``)和方法(``实例方法和静态方法``),但不能继承构造方法和代码块和内部类
2.子类不可以重写父类的静态方法
3.子类重写父类属性会`隐藏`从父类继承的`属性`,可以通过super关键字调用
4.子类重写父类方法会`覆盖`(擦除重写)从父类继承的`方法`,可以通过super关键字调用
5.子类可以单继承多实现
6.子类构造方法会调用父类默认不显示的构造方法

修饰符对继承的影响:
子类可以继承父类public protected default(父子都在同一个包)修饰的属性和方法,但不能继承private修饰的
抽象类
抽象类
1.抽象类中可以写普通方法和抽象方法,抽象方法只能存在于抽象类中
2.抽象方法没有方法体
3.子类重写抽象父类时,必须重写抽象父类所有的抽象方法
4.abstract 关键字只能用于普通方法,不能用于 static 方法或者构造方法中
5.抽象类中可以书写实例方法
接口
接口
1.public 修饰的接口,允许任何类使用;没有指定 public 的接口,其访问将局限于所属的包。
2.方法的声明不需要显示的修饰符。在接口中声明的方法,将隐式地具有public abstract修饰符。
3.在 Java 接口中声明的变量其实都是常量,接口中的变量声明,将隐式地声明为 public、static 和 final,即常量,所以接口中定义的变量必须初始化
4.接口可以多继承接口,但不能实现父接口(类是单继承,多实现)。子接口可以对父接口的常量进行重写(会导致父类的常量被隐藏)
重载或重写

/*
重载的定义(Overload)
    1.同一个类中
    2.多个方法,它们功能类似,只有参数不同
    3.不能通过访问权限、返回类型、抛出的异常进行重载
    (1) 子类继承了父类的方法,子类也可以重载继承下来的方法
*/



/*
重写的定义(Override)
    0.用于子类在继承父类时,重写(重新实现)父类中的方法
    1.重写方法的`参数列表`必须完全与被重写的方法的相同(或参数为继承关系),否则不能称其为重写而是重载.
    2.重写方法的`访问修饰符`一定要大于等于被重写方法的访问修饰符(public>protected>default>private)
    3.重写的方法的`返回值`必须和被重写的方法的返回一致
    4.重写的方法所抛出的`异常`必须和被重写方法的所抛出的异常一致,或者是其子类
    5.被重写的方法不能为`private`,否则在其子类中只是新定义了一个方法,并没有对其进行重写。
    6.静态方法不能被重写为非静态的方法(会编译出错)
*/

重写和重载的最主要区别是 : 重写是方法名和参数和返回值和修饰符都一样,重载是只有参数不一样

多态
多态的实现方式:
1.重写: Java 重写(Override)与重载(Overload)。
2.接口 接口就是一些方法特征的集合,接口和抽象方法的关系是has关系,抽象类和抽象方法的关系是is关系
3.抽象方法 

设计模式

设计模式六大原则
开闭原则:对修改关闭,对扩展开放
里氏替换原则:任何基类出现的地方,子类一定可以出现,里氏替换是对开闭原则的补充
依赖倒转原则:针对接口编程,功能应该依赖于抽象而不是具体类
接口隔离原则 :接口功能尽量细化,降低接口偶合度
迪米特法则:类与类之间尽量少互相作用,只需要知道其他类提供的public方法就行
合成复用原则:尽量使用合成聚合关系,而不是使用继承

简单理解:在设计新功能时,尽量使用接口,接口功能尽量单一,子类可以多实现接口。在新增加功能的时候,不要去修改原来的功能,应该是去实现原来设计的接口和抽象类来拓展功能。并且应该少用继承,多用聚合关系

聚合关系:
(比如用户的扩展信息类,不应该用继承。而是把用户类做为扩展类的字段)
一些设计模式
单例模式:某个类只能生成一个实例,类似一些工具类
工厂模式:就是建立一个工厂类,对实现了同一接口的一些类进行实例的创建,体现在SqlSessionFactory
代理模式:创建一个代理类以控制外部对内部对象的访问限制。体现在aop上面
责任链模式:就是对某个对象的链式处理,使多个处理者不必耦合在一起。体现在实体类的setter方法上
迭代器模式:提供一组遍历聚合对象的接口,使用者无需关注内部细节。util包下面有对迭代器的实现
装饰器模式:java io 。

java常用类

java.lang.Object

java.lang.Object
	它是所有类的根父类
		1、它当中声明的方法,在所有引用类型中都有
		2、所有类创建对象,都会调用它的无参构造
		3、它的变量可以指向任意类型的对象(多态引用)
	常见的方法
		1、getClass()
			返回某个对象的运行时类型
		2、equals(Object obj)
			判断两个对象的值是否相等,返回true和false
		3、hashCode()
			在某个对象用于散列数据结构的key的时候,比如hashmap hashtable hashset,则需要重写hashCode()。返回一串哈希值
		4、toString()
			返回对象的字符串表示形式
			
为什么重写equlas就必须重写hashcode
根据自反性 对称性 传递性:两个对象相等hash值一定相等,所以重写equlas就必须重写hashcode

Collections

        // 排序
        Collections.sort(list);
        // 洗牌
        Collections.shuffle(list);
        // 转换为不可变集合 (继续对原始的可变List进行增删是可以的,并且,会直接影响到封装后的“不可变”List)
        List<String> immutable = Collections.unmodifiableList(list);
        // 变为线程安全的List
        List<String> threadSafetyList = Collections.synchronizedList(list);
        // 变为线程安全的Set
        List<String> threadSafetySet = Collections.synchronizedList(list);
        // 变为线程安全的Map
        Map<String, String> threadSafetyMap = Collections.synchronizedMap(map);

Arrays

Arrays.asList(1,2,3,4);
Arrays.binarySearch(T[] a, T key);  // 二分查找法,返回找到的index
Arrays.copyTo(T[] original, T newLength);	// 复制数组,返回新的数组
Arrays.deepEquals(Object[] a1, Object[] a2);	// 深度比较

集合框架

集合框架图

在这里插入图片描述
![在这里插入图片描述](https://img-blog.csdnimg.cn/8030ba4baba7467597582b63e991be06.png
在这里插入图片描述

接口概述

1	Collection 接口
Collection 是最基本的集合接口,一个 Collection 代表一组 Object,即 Collection 的元素, Java不提供直接继承自Collection的类,只提供继承于的子接口(如List和set)。
Collection 接口存储一组不唯一,无序的对象。

2	List 接口
List接口是一个有序的 Collection,使用此接口能够精确的控制每个元素插入的位置,能够通过索引(元素在List中位置,类似于数组的下标)来访问List中的元素,第一个元素的索引为 0,而且允许有相同的元素。
List 接口存储一组不唯一,有序(插入顺序)的对象。

3	Set
Set 具有与 Collection 完全一样的接口,只是行为上不同,Set 不保存重复的元素。
Set 接口存储一组唯一,无序的对象。

4	SortedSet
继承于Set保存有序的集合。

5	Map
Map 接口存储一组键值对象,提供key(键)到value(值)的映射。

6	Map.Entry
描述在一个Map中的一个元素(键/值对)。是一个 Map 的内部接口。

7	SortedMap
继承于 Map,使 Key 保持在升序排列。

集合实现类

LinkedList
该类实现了List接口,允许有null(空)元素。主要用于创建链表数据结构,该类没有同步方法,如果多个线程同时访问一个List,则必须自己实现访问同步,解决方法就是在创建List时候构造一个同步的List。例如:

List list=Collections.synchronizedList(newLinkedList(...));
LinkedList 查找效率低。

ArrayList
该类也是实现了List的接口,实现了可变大小的数组,随机访问和遍历元素时,提供更好的性能。
该类也是非同步的,在多线程的情况下不要使用。ArrayList 增长当前长度的50%,插入删除效率低。

HashSet
该类实现了Set接口,不允许出现重复元素,不保证集合中元素的顺序,允许包含值为null的元素,但最多只能一个。自定义元素对象需要重写equals hashcode 

HashMap
HashMap 是一个散列表,它存储的内容是键值对(key-value)映射。
该类实现了Map接口,根据键的HashCode值存储数据,具有很快的访问速度,最多允许一条记录的键为null,不支持线程同步。

TreeSet
TreeSet 是一个有序的集合,它的作用是提供有序的Set集合。自定义元素对象需要重写compareTo

加密签名

加密


加密
摘要算法 就是hash算法包括 md5 sha1 sha256 sha512
加密算法 分为对称(AES DES) 和非对称(RSA)
签名算法 私钥签名-公钥验签

签名算法和加密算法的区别
数字签名使用的是发送方的密钥对,发送方用自己的私有密钥进行加密,接收方用发送方的公开密钥进行解密,这是一个一对多的关系,任何拥有发送方公开密钥的人都可以验证数字签名的正确性;
数字加密则使用的是接收方的密钥对,这是多对一的关系,任何知道接收方公开密钥的人都可以向接收方发送加密信息,只有唯一拥有接收方私有密钥的人才能对信息解密

数字证书
摘要算法用来确保数据没有被篡改,非对称加密算法(RSA)可以对数据进行加解密,签名算法可以确保数据完整性和抗否认性,把这些算法集合到一起,并搞一套完善的标准,这就是数字证书。

JavaIo

什么是IO

从数据传输方式
可以将 IO 类分为: 
字节流, 字节流的单个字节是8个位
字符流, 字符流的一个字符包含多个字节,具体每个字符是多少个字节要看编码方式。是utf-8 还是utf-16 utf-32

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

举例
以 InputStream 为例 
	InputStream 是抽象组件; 
	FileInputStream 是 InputStream 的子类,属于具体组件,提供了字节流的输入操作; 
	FilterInputStream 属于抽象装饰者,装饰者用于装饰组件,为组件提供额外的功能。例如 BufferedInputStream 为 FileInputStream 提供缓存的功能。

在这里插入图片描述
DataInputStream 装饰者提供了对更多数据类型进行输入的操作,比如 int、double 等基本类型。

javaio 用了什么设计模式
装饰者模式: 所谓装饰,就是把这个装饰者套在被装饰者之上,从而动态扩展被装饰者的功能

使用

文件读取
        Path path = Paths.get("src/myio/file.txt");
        byte[] data = Files.readAllBytes(path);         // 读取字节
        List<String> lines = Files.readAllLines(path);  // 读取字符

并发

多线程

线程的三种实现方式
实现 Runnable 接口; 
实现 Callable 接口;
继承 Thread 类。
实现 Runnable 和 Callable 接口的类只能当做一个可以在线程中运行的任务,不是真正意义上的线程,因此最后还需要通过 Thread 来启动
线程状态

在这里插入图片描述

新建(New) 
 	创建后尚未启动。 
可运行(Runnable) 
 	可能正在运行,也可能正在等待 CPU 时间片。 
阻塞(Blocking) 
	线程等待获取一个排它锁,如果其他线程释放了锁就有可能结束此状态。 
无限期等待(Waiting) 
	等待其它线程显式地唤醒,否则不会被分配 CPU 时间片
	>进入此状态
		没有设置 Timeout 参数的 Object.wait() 方法
		没有设置 Timeout 参数的 Thread.join() 方法
	>退出此状态
		其他线程调用Object.notify() / Object.notifyAll()
		被调用的线程执行完毕
限期等待(Timed Waiting)
	无需等待其它线程显式地唤醒,在一定时间之后会被系统自动唤醒。
	> 进入此状态
		Thread.sleep() 方法
	> 退出此状态
		时间结束
死亡(Terminated)
	可以是线程结束任务之后自己结束,或者产生了异常而结束
线程的中断方式
通过调用一个线程的 interrupt() 来中断该线程,如果该线程处于阻塞、限期等待或者无限期等待状态,
那么就会抛出 InterruptedException,从而提前结束该线程。但是不能中断 I/O 阻塞和 synchronized 锁阻塞。
线程直接协作方式?
join() 
在线程中调用另一个线程的 join() 方法,会将当前线程挂起,直到目标线程结束。 

锁机制

概念
乐观锁 & 悲观锁  (这两种锁是一种抽象概念)

乐观锁:乐观锁认为一个线程去拿数据的时候不会有其他线程对数据进行更改,所以不会上锁。
	实现方式:CAS机制、版本号机制
悲观锁:悲观锁认为一个线程去拿数据时一定会有其他线程对数据进行更改。
	所以一个线程在拿数据的时候都会顺便加锁,这样别的线程此时想拿这个数据就会阻塞。
	比如Java里面的synchronized关键字的实现就是悲观锁。
	实现方式:就是加锁。

独占锁和共享锁:
	独占锁和共享锁,这也是两种抽象的概念。
	独占锁:一个线程独占
	共享锁:所有线程同时获取

	独占锁的具体实现是synchronized,ReentrantLock,WriteLock
	共享锁的具体实现是ReadLock
synchornized锁和Lock锁的比较
(0)可重入锁
可重入 所谓重入锁,指的是以线程为单位,当一个线程获取对象锁之后,这个线程可以再次获取本对象上的锁,而其他的线程是不可以的。
synchronized和ReentrantLock都是可重入锁
(1)可中断锁
响应中断的锁,Lock是可中断锁(体现在lockInterruptibly()方法),synchronized不是。如果线程A正在执行锁中代码,
线程B正在等待获取该锁。时间太长,线程B不想等了,可以让它中断自己。
(2)公平锁
尽量以请求锁的顺序获取锁。比如同时有多个线程在等待一个锁,当锁被释放后,等待时间最长的获取该锁,跟京牌司法拍卖一个道理。
非公平锁可能会导致有些线程永远得不到锁,synchronized是非公平锁,ReentrantLock是公平锁。
(3)读写锁
读写锁将对一个资源(如文件)的访问分为2个锁,一个读锁,一个写锁;读写锁使得多个线程的读操作可以并发进行,不需同步。
而写操作就得需要同步,提高了效率ReadWriteLock就是读写锁,是一个接口,ReentrantReadWriteLock实现了这个接口。
可通过readLock()获取读锁,writeLock()获取写锁
(4)绑定多个条件
一个ReentrantLock可以绑定多个Condition对象,仅需多次调用new Condition()即可;而在synchronized中锁锁对象的wait()、
notify()/notifyAll()可以实现一个隐含的条件,如果要和多余的条件关联,就不得不额外的增加一个锁。

(1)synchronized和Lock都是可重入锁,前者是jvm中使用monitorenter(1个)和monitorexit(2个)来
实现同步且其中阻塞和唤醒是wait和notify,后者是juc包中的lock层次使用,依赖于AQS来实现加锁和解锁;
(2)synchronized是非公平锁,ReentrantLock可以设置公平锁或者非公平锁;
(3)synchronized是不可中断且无法获取锁状态,后者是可中断lockInterruptibly方法,同时也可获取锁的状态isLocked();
(4)synchronized是不能精准唤醒的,ReentrantLock是可以依赖于Condition对象设置条件进行精准唤醒;
(5)synchronized是jdk提供的关键字,Lock是普通的java类(接口),前者可锁方法或代码块,后者只能锁代码块;
(6)synchronized是不会产生死锁,lock使用lock()方法和unlock()方法成对使用,否则产生死锁;

java锁机制

锁的状态
java里引入了4种锁的状态:无锁、偏向锁、轻量级锁和重量级锁,它会随着多线程的竞争情况逐渐升级,但不能降级
synchronized
synchronized的三种用法
 // 方法锁:
public synchronized String getTask() {	
	
}
// 对象锁
synchronized (this) {     
}

// 类锁
synchronized (Task.class) {
}
Lock

注意点

java包装类型的常量池

Java 基本类型的包装类的大部分都实现了常量池技术,即 Byte,Short,Integer,Long,Character,Boolean;前面 4 种包装类默认创建了数值[-128,127] 的相应类型的缓存数据,Character创建了数值在[0,127]范围的缓存数据,Boolean 直接返回True Or False。如果超出对应范围仍然会去创建新的对象。

比较

 == 的作用:
  基本类型:比较的就是值是否相同
  引用类型:比较的就是地址值是否相同
equals 的作用:
  引用类型:默认情况下,比较的是地址值,重写该方法后比较对象的成员变量值是否相同
		int i = 1;
        int b = 1;
        System.out.println(i == b);
        Integer c = 127;
        Integer d = 127;
        System.out.println(c == d);

java的参数传递方式

java只有值传递和指针传递,但指针传递其实也是值传递。没有引用传递。值传递就是形参对实参的一个拷贝,主调函数的值直接复制到被调函数栈帧中

classpath搜索路径

现在我们假设classpath是.;C:\work\project1\bin;C:\shared,当JVM在加载abc.xyz.Hello这个类时,会依次查找:

<当前目录>\abc\xyz\Hello.class
C:\work\project1\bin\abc\xyz\Hello.class
C:\shared\abc\xyz\Hello.class
java -classpath .;C:\work\project1\bin;C:\shared abc.xyz.Hello
更好的做法是,不要设置classpath!默认的当前目录.对于绝大多数情况都够用了

同步和异步

同步和异步描述的是线程之间的关系
比如同步:用户线程发起一个read调用,需要等待内核线程完成工作并将数据拷贝到用户地址空间,期间用户线程需要一直等待无法处理其他任务
异步是指:用户线程发起read调用之后无须等待,立刻去处理其他任务。内核线程准备好数据之后发送信号通知用户线程处理

阻塞和非阻塞

阻塞和非阻塞描述的是线程的状态
比如阻塞:在线程发起一个read调用后,线程会被挂起,一直处于等待中,直到数据返回
非阻塞:是说线程发起调用之后,不需要因为调用而被挂起,会立即返回,但是需要定时轮询查看结果

epoll为什么比select更优秀

在这里插入图片描述

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值