目录

 

背景

jdk9新特性

目录结构的改变

模块化系统

要解决的问题

概念

实现目标

示例

jShell命令

多版本兼容jar包

接口中的私有方法

钻石操作符(泛型)的升级

 try语句的升级

下划线命名标识符的限制

String存储结构的变化

快速创建只读集合

增强的流api

takeWhile

dropWhile

of()方法和ofNullable()方法

iterator()重载方法

Optional类中的stream()方法

多分辨率图像api

全新的http客户端api

被废弃的api

智能java编译工具sjavac

统一的jvm日志系统

javadoc的H5支持

js的Nashorn引擎升级

动态编译器

总结

jdk11新特性

局部变量自动类型推断

String类新增方法

Optional方法增强

transferTo()方法

移除和废弃的一些内容

更简化的编译运行程序

Unicode10

新增的Epsilon收集器

ZGC

完全支持linux容器(包括docker)

G1的完全并行GC

免费的低耗能分析(Low-Overhead Heap Profiling)

新的加密算法

Flight Recorder

jdk12新特性

新的Shenandoah(雪兰多)收集器

微基准表达式

switch表达式

JVM常量api

只保留一个AArch64实现

默认类数据共享归档文件

可中止的G1混合收集器

G1及时返回未使用的已分配内存

String中新增的方法

transform()方法

indent()方法

Files中新增的方法——mismatch()

其他新增项

jdk13新特性

动态CDS档案

ZGC:提交未使用的堆内存

重新实现旧版套接字api

switch表达式中引入yield

文本块

新增项

总结

jdk14新特性

instanceof省去了强制类型转换的过程

更详细的空指针异常

Record数据结构

jdk12/13中的switch表达式正式转正

增强版的文本块

弃用Parallel Scavenge和Serial Old的GC组合

windows和mac上可用ZGC

结语


背景

熬夜看完谢菲联3:1战胜热刺,曼城4:0横扫已经提前夺冠的红军,醒来又是无聊的一天........

jdk9新特性

目录结构的改变

jdk8及以前的目录结构如下所示(MemoryAnalyzer是我后来加的,不属于原有的结构)

jdk9的目录结构如下图所示,其中jre目录是后来加的,也就是原有jdk9目录不包含jre

模块化系统

要解决的问题

jre的膨胀和臃肿(每次JVM启动时,由于要加载rt.jar,所以要至少加载30~60MB的内存);不同版本的类库交叉依赖;每个公共类可以被类路径下任何其他的公共类所访问到,会导致使用并不像开放的api;类路径可能重复等

概念

模块实际上就是包外面再包一层,来管理包,使代码更安全

我们可以使用jlink工具,定制运行时环境

实现目标

模块独立、化繁为简

减少内存开销;只加载必要jdk模块,简化类库和大型应用的开发维护;改进java SE,使其适应不同大小的计算设备;改进安全性

示例

1)、创建项目,基于jdk9

2)、构建两个模块,demo0和demo1,。demo1中引用demo0中的bean类

3)、点击Project Structure->Modules,把两个模块和项目的语言等级都设置成9,并把src目录标记为源目录

4)、点击设置->构建、执行、部署->编译器->java编译器,把三个部分的字节码版本也都设置成9

5)、在demo0的源目录下创建module-info.java文件,声明要导出的包

 

内容如下

module demo0 {exports com.szc.bean; // 导出包
}

6)、在demo1的源目录下也创建module-info.java文件,声明要引用的模块

内容如下

module demo1 {requires demo0;
}

然后就可以在demo1中使用demo0中导出包的内容了

import com.szc.bean.Person;public class ModuleTest {public static void main(String[] args) {Person p = new Person("szc", 23);}
}

而没有暴露的包,里面的类就不能被引用,例如下图中entity包下的User类

在demo1中强行使用会报错

7)、我们当然也可以使用第三方的模块,比如java.logging,在demo1中的module-info.java引入此包即可

module demo1 {requires demo0;requires java.logging;
}

然后,就能使用了

import com.szc.bean.Person;import java.util.logging.Logger;public class ModuleTest {private static final Logger sLOGGER = Logger.getLogger("szc");public static void main(String[] args) {Person p = new Person("szc", 23);sLOGGER.info(p.toString());}
}

运行输出如下

jShell命令

提供类似python、scala的repl交互式编程环境

我们可以进行输出语句、定义变量等操作

也可以定义方法,并调用

以及方法的重载

还可以导包,显示导入的包

 

我们按/+tab可以显示所有可用的命令

其中/list可以显示输入历史

/edit可以调出编辑面板

面板中三个按钮自然表示取消、提交和退出编辑面板

jshell中没有受检异常,也就是自行捕获编译期异常

最后,ctrl-c退出,或者/exit退出

多版本兼容jar包

此机制可以让我们创建仅在某个版本的java环境中的class版本,也可以让class的后期版本直接覆盖前期版本

接口中的私有方法

jdk7中只能声明全局常量和抽象方法

interface IMyInterface {public void test0();
}

jdk8中的接口可以有具体的静态方法和默认方法

interface IMyInterface {public static void test1 () {System.out.println("静态方法");}default void test2() { // 可以被实现类覆写System.out.println("默认方法");}public void test0();
}

jdk9中的接口甚至私有方法都能有方法体,而jdk8及以前接口方法都是公有的

interface IMyInterface {private void test() {System.out.println("接口中的私有方法");}public static void test1 () {System.out.println("静态方法");}default void test2() {System.out.println("默认方法");}public void test0();
}

钻石操作符(泛型)的升级

创建泛型类对象时,可以覆写其中的方法

Set<String> set = new HashSet<>(){@Overridepublic boolean add(String s) {return super.add(s + "..");}
};

测试代码

public class DiamondOperatorTest {public static void main(String[] args) {new DiamondOperatorTest().test();;}public void test() {Set<String> set = new HashSet<>(){@Overridepublic boolean add(String s) {return super.add(s + "..");}};set.add("1");set.add("2");set.add("3");set.add("4");for (String s : set) {System.out.println(s);}}
}

输出如下

 try语句的升级

传统的异常捕获语句如下所示,以流为例

public static void main(String[] args) {InputStreamReader reader = null;try {reader = new InputStreamReader(System.in);reader.read();} catch (IOException e) {e.printStackTrace();} finally {if (reader != null) {try {reader.close();} catch (IOException e) {e.printStackTrace();}}}
}

jdk8中可以在try后面跟一对()内进行变量的实例化,然后就不用写finally了,JVM会自行释放资源

public static void main(String[] args) {try (InputStreamReader reader = new InputStreamReader(System.in)) {reader.read();} catch (IOException e) {e.printStackTrace();}
}

jdk9中,()内的变量可以在外面实例化了,相关资源还是由JVM释放,但此时()内的变量自行成为final变量,不可再修改

public static void main(String[] args) {InputStreamReader reader = new InputStreamReader(System.in);try (reader) {reader.read();} catch (IOException e) {e.printStackTrace();}
}

如果有多个要捕获异常的资源,那么在()里用;隔开即可

public static void main(String[] args) {InputStreamReader reader = new InputStreamReader(System.in);InputStreamReader reader0 = new InputStreamReader(System.in);try (reader; reader0) {reader.read();} catch (IOException e) {e.printStackTrace();}
}

下划线命名标识符的限制

jdk9中不能使用_做为标识符名了

public static void main(String[] args) {String _ = "szc"; // 编译报错
}

String存储结构的变化

jdk8及以前,String使用char[]存放字符串

jdk9中就换成了字节数组

这么做的原因,是因为char数组使用两个字节存放一个字符,而占用堆空间的绝大多数对象都是String对象,绝大多数String存储的是拉丁字符,这些拉丁字符只使用1个字节就足够存放,所以jdk9中String对象使用了byte数组存放字符串。

jdk9把utf-16字符数组换成了字节数组,外加一个编码域,用来表示此字符串应该用什么编码规则编解码。如果编码域指定的编码是latin-1/ISO-8859-1,那么就是用一个字节表示一个字符;如果指定的编码是utf-16,就用两个字节表示一个字符

 

StringBuilder和StringBuffer的父类AbstractStringBuilder也应用了这一变化,使用字节数组存储字符串

快速创建只读集合

过去创建只读集合,需要调用Collections中的unmodifiableCollection方法

List<String> list = new ArrayList<>();list.add("1");
list.add("2");
list.add("3");Collection<String> strings = Collections.unmodifiableCollection(list);

上面的strings对象就是只读的,不能修改或添加数据

现在,可以直接调用具体的unmodifiable+集合名方法来创建具体的只读集合

List<Integer> integers = Collections.unmodifiableList(Arrays.asList(1, 2, 3));

下面是创建只读映射的方法

Map<Object, Object> map = Collections.unmodifiableMap(new HashMap<>() {{ // 插入代码块,插入键值对put("a", 1);put("b", 2);put("c", 3);}
});map.forEach((k, v) -> System.out.println(k + "-" + v));

上面的代码可以简化成of方法的调用

List<Integer> integers = List.of(1, 2, 3);Map<Object, Object> map = Map.of("a", 1, "b", 2, "c", 3); // 入参顺序:k1, v1, k2, v2...Map<String, Integer> map1 = Map.ofEntries(Map.entry("a", 1), Map.entry("b", 2), Map.entry("c", 3)); // 传入一个个键值对entry对象map.forEach((k, v) -> System.out.println(k + "-" + v));

其中的integers和map对象就都是只读的

增强的流api

takeWhile

读取,直到遇见不符合条件的元素

List<Integer> list = Arrays.asList(11, 32, 44, 29, 52, 72, 82, 64, 4, 19);
list.stream().takeWhile(integer -> integer < 50).forEach(System.out::println);

输出如下,不会输出后面的4和19

dropWhile

作用和takeWhile互补,一直不读取,直到遇见不符合条件的元素

List<Integer> list = Arrays.asList(11, 32, 44, 29, 52, 72, 82, 64, 4, 19);
list.stream().dropWhile(x -> x < 50).forEach(System.out::println);

输出如下

of()方法和ofNullable()方法

of()可以创建含有一个null对象的流

Stream.of(1, 2, 4, null).forEach(System.out::println);

输出如下

ofNullable()可以创建只有一个null对象的流

Stream.ofNullable(null).forEach(System.out::println);

什么也不会输出,ofNullable()方法也可以传入非空对象

System.out.println(".................");
Stream.ofNullable(null).forEach(System.out::println);
System.out.println(".................");
Stream.ofNullable(2).forEach(System.out::println);

输出如下

iterator()重载方法

通过iterate()的第二个参数控制迭代进行的条件

Stream.iterate(0, x -> x < 5, x -> x + 1).forEach(System.out::println);

以上代码类似于

for (int i = 0; i < 5; i++) {System.out.println(i);
}

输出结果

Optional类中的stream()方法

Optional.ofNullable(list).stream().forEach(System.out::println);

输出如下

如果要对Optional类的stream对象进行铺平的话,可以调用flatMap()方法

Optional.ofNullable(list).stream().flatMap(x -> x.stream()).forEach(System.out::println);

输出如下

多分辨率图像api

在mac上,jdk已经支持视网膜显示,但jdk8及以前并不支持windows和linux上的多分辨率显示

jdk9使用了比现在更先进的api:Direct2D for Windows和GTK+,而不是Xlib for Linux,支持图形、窗口和文本的自动缩放;而且提供了处理多分辨率图像的能力,适配不同的DPI。

全新的http客户端api

2015年的http2允许服务器主动push(推送)数据,也就是可以发送比客户端请求更多的数据

使用示例

public class HttpClient2Test {public static void main(String[] args) throws IOException, InterruptedException {HttpClient client = HttpClient.newHttpClient();HttpRequest request = HttpRequest.newBuilder(URI.create("http://www.baidu.com")).GET().build();HttpResponse<String> response = client.send(request, HttpResponse.BodyHandler.asString());System.out.println(response.statusCode());System.out.println(response.version().name());System.out.println(response.body());}
}

在module-info.java中引用httpclient

requires jdk.incubator.httpclient;

被废弃的api

主要是Applet和appletviewer的api都被标记为废弃,因为主流浏览器已经取消了对java浏览器插件的支持,H5的出现更是加速了java浏览器插件的灭亡,我们可以使用java Web Start来代替applet,以实现从浏览器启动或安装应用程序

智能java编译工具sjavac

sjavac第一个阶段用于提升多核处理器下的编译速度,第二阶段使其成为默认的编译工具,并且能够编译运行低版本的java代码

统一的jvm日志系统

对所有jvm组件引入一个单一的日志系统,从而让这些组件支持细粒度的和易配置的jvm日志,避免碎片化。

javadoc的H5支持

jdk9中javadoc的输出,符合兼容H5标准,主要多了一个search功能

js的Nashorn引擎升级

Nashorn让java中嵌入js,并提供js解释引擎。jdk9中包含了一个用来解析Nashorn的ECMAScript语法树的api,这使得IDE和服务端不需要Nashorn的内部类,就能解析ECMAScrpit代码

动态编译器

引入AOT(Ahead Of  Time),这个功能使得java应用在JVM启动前,就被编译成二进制代码。此功能在jdk9中处于实验阶段,稳定版要到jdk10中发布

总结

jdk9中还看不到的功能:

1)、标准化的和轻量级的json api

2)、新的货币api

展望:

1)、传统的大型企业或互联网应用,正在被云端、容器化应用、模块化微服务甚至Faassuotidai

2)、java标榜面向对象,现在却毫不顾忌地加入面向接口编程思想,又加入匿名对象的概念,这都是对传统面向对象的冲击

3)、java需要在新的计算场景下,改进开发效率

jdk11新特性

局部变量自动类型推断

public class Main {public static void main(String[] args) {var s = "s";System.out.println(s.getClass().getCanonicalName()); // java.lang.String}
}

自动类型推断必须使用var,类型推断后,类型就不能变了

//        s = 1; // 不可再赋予新的类型s = "a"; // ok

var不是一个关键字

        int var = 1;

var变量必须赋初值

//        var b; // 必须赋初值

类属性不能用var

public class Main {
//    private var x = 1; // 类成员变量不能使用var
}

可用于lambda表达式

List.of(1, 2, 4, 5, 3).stream().map((var x) -> x + "_").forEach(System.out::println);

以及函数式接口

Consumer<String> consumer = (var t) -> System.out.println(t.toUpperCase());
consumer.accept("ss"); // SS

也可用于给参数加注解

Consumer<String> consumer = (@Deprecated var t) -> System.out.println(t.toUpperCase());

以下方式就不对了

// Consumer<String> consumer = (@Deprecated t) -> System.out.println(t.toUpperCase()); // 注解后面不能直接跟变量名

String类新增方法

判断是否是空白字符串

String s1 = "\t \n";
System.out.println(s1.isBlank()); // 判断是否为空白 true

去除首尾空白

s1 = "\t sss\n";
System.out.println(s1.trim().length()); // 去除首尾空白,可以去除全角空格
System.out.println(s1.strip().length()); // 去除首尾空白,但不能去除全角空格
System.out.println(s1.stripLeading()); // 去除头部空白
System.out.println(s1.stripTrailing()); // 去除尾部空白

以上代码输出如下

4
3
ssssss

lines()方法可以对字符串每一行进行流式处理

"asc\nccc\nwww".lines().map(str -> str.toUpperCase()).forEach(System.out::println);

输出如下

ASC
CCC
WWW

repeat()方法重复此字符串

System.out.println("a".repeat(5)); // aaaaa

Optional方法增强

增加了对空值的处理

System.out.println(Optional.ofNullable(null).orElse("b")); // 如果为空,返回"b"
System.out.println(Optional.ofNullable(null).orElseGet(() -> "b")); // 也可以使用函数式接口实现orElse()
System.out.println(Optional.ofNullable(null).orElseThrow()); // 如果为空,排除异常

以上代码输出如下

b
b
Exception in thread "main" java.util.NoSuchElementException: No value presentat java.base/java.util.Optional.orElseThrow(Optional.java:382)at com.szc.Main.main(Main.java:42)

transferTo()方法

文件输出可以直接调用inputStream的transferTo()方法,将输入流中数据直接复制刷写到输出流中

try (var inputStream = new FileInputStream("D:/test.jar");var outputStream = new FileOutputStream("test2.jar")) {inputStream.transferTo(outputStream);
} catch (Exception e) {e.printStackTrace();
}

移除和废弃的一些内容

移除的:com.sun.awt.AWTUtilities、sum.misc.Unsafe.defineClass(被java.lang.invoke.MethodHandles.Lookup.defineClass替代)、Thread.destroy()、Thread.stop(Throwable)、sun.nio.disableSystemWideOverlappingFileLockCheck属性、sun.locale.formatasdefault属性、jdk.snmp模块、javafx模块、javaMissionControl等

JavaEE和CORBA模块,比如java.xml部分、java.corba、java.transaction、java.activation等模块,但是新增了java.transaction.xa模块

 

废弃的:-XX:+AggressiveOpts、-XX:UnlockCommercialFeatures、-XX:+LogCommercialFeatures

Nashorn js引擎,可以考虑使用GraalVM

pack200和unpack200,这是以前压缩jar包的工具,现在被废弃了

更简化的编译运行程序

如果java文件里没有使用别的文件里的自定义类,那么就可以直接使用java就可以编译运行java文件,也不会输出class文件

如果有两个main方法,就只会执行第一个

class A
{public static void main(String[] args) {System.out.println("aaa");}
}public class Test
{public static void main(String[] args) {System.out.println("bbb");}
}

输出如下

Unicode10

Unicode10加入了8518个字符,4个脚本和56个新的emoji表情符号

新增的Epsilon收集器

这是一个处理内存分配但不负责内存回收的GC,堆内存用完,JVM即刻退出。关于垃圾回收和垃圾回收器,以及GC参数设置,请参见文章JVM学习之垃圾回收和垃圾回收器,文章最后也提到了EpsilonGC、ZGC、雪兰多GC等新的垃圾回收器。

如果启用了Epsilon收集器,System.gc()的调用就没有了意义。

启用Epsilon方法:-XX:+UnlockExperimentalVMOptions -XX:+UseEpsilonGC

测试代码如下,配置参数:-Xms10m -Xmx10m -XX:+UnlockExperimentalVMOptions -XX:+UseEpsilonGC

package com.szc;import java.util.ArrayList;
import java.util.List;public class Main {public static void main(String[] args) {List<Test> tests = new ArrayList<>();int count = 0;while (true) {tests.add(new Test());count++;if (count == 500) {tests.clear();}}}
}class Test {@Overrideprotected void finalize() throws Throwable {System.out.println("finalize..");}
}

输出如下

D:\develop\jdk\jdk-11.0.7\bin\java.exe -Xms10m -Xmx10m -XX:+UnlockExperimentalVMOptions -XX:+UseEpsilonGC "-javaagent:D:\develop\IntelliJ IDEA Community Edition 2019.1.3\lib\idea_rt.jar=52381:D:\develop\IntelliJ IDEA Community Edition 2019.1.3\bin" -Dfile.encoding=UTF-8 -classpath D:\develop\ideaWorkspace\JDK11Test\target\classes com.szc.MainTerminating due to java.lang.OutOfMemoryError: Java heap spaceProcess finished with exit code 3

而去掉EpsilonGC之后的输出如下所示

 可见尽管tests.clear()调用之后原有的500个对象成为了垃圾对象,但堆爆满时依旧没有发生GC去回收任何对象

 

EpsilonGC主要用途如下:

性能测试(过滤GC引起的性能消耗,相当于控制变量)、内存压力测试(看看不回收的情况下,到底能不能消耗指定大小的内存)、执行非常短的任务(GC反而是浪费时间)、VM接口测试、延迟吞吐量的改进等实验性质的调优

ZGC

低延迟的ZGC,不管堆内存多大,都能使得STW时间不会超过10ms;和现有的G1相比,应用吞吐能力的下降不会超过15%

ZGC是一个并发、基于区域(region)、标记压缩算法的GC,只有根结点扫描阶段会发生STW,因此停顿时间不会随着堆内存的增长和存活对象的增长而增长

启用ZGC的方法:-XX:+UnlockExperimentalVMOptions -XX:+UseZGC

目前ZGC只能用于64位的linux操作系统下

完全支持linux容器(包括docker)

jdk11以前的java应用程序在docker中运行的性能会下降,但现在此问题在容器控制组(cgroups)的帮助下得以解决,使JVM和docker配合得更加默契

G1的完全并行GC

jdk11升级了G1,使我们可以免费享受彻底并行的Full GC,快速的卡表扫描

免费的低耗能分析(Low-Overhead Heap Profiling)

通过JVMTI的SampledObjectAlloc回调提供一个低开销的堆分析方式

新的加密算法

用ChaCha20和Poly1305两种更加高效安全的加密算法,代替RC4、新的默认跟权限证书集,跟随最新的HTTPS安全协议TLS1.3

Flight Recorder

用来记录java程序的运行,现在从商业版中开源出来了。

有两种使用方式:程序开始前,添加-XX:StartFilghtRecording参数;也可以在程序启动后,通过jcmd命令启动jfr

D:\develop\jdk\jdk-11.0.7\bin>jcmd 20412 JFR.start
20412:
Started recording 1. No limit specified, using maxsize=250MB as default.Use jcmd 20412 JFR.dump name=1 filename=FILEPATH to copy recording data to file.D:\develop\jdk\jdk-11.0.7\bin>jcmd 20412 JFR.dump name=1 filename=out.jfr
20412:
Dumped recording "1", 359.5 kB written to:C:\Users\songzeceng\AppData\Local\JetBrains\IdeaIC2020.1\compile-server\out.jfrD:\develop\jdk\jdk-11.0.7\bin>jcmd 20412 JFR.stop name=1
20412:
Stopped recording "1".

其中的20412是待测的java程序进程号,输出的文件路径可知是C:\Users\songzeceng\AppData\Local\JetBrains\IdeaIC2020.1\compile-server\out.jfr,但这是二进制文件,基本看不了

在jdk12及以后,才有了jfr命令可以查看jfr文件,例如查看CPU加载信息

D:\develop\jdk\jdk-12\bin>jfr print --events  CPULoad C:\Users\songzeceng\AppData\Local\JetBrains\IdeaIC2020.1\compile-server\out.jfr
jdk.CPULoad {startTime = 00:55:26.793jvmUser = 6.37%jvmSystem = 0.70%machineTotal = 10.31%
}jdk.CPULoad {startTime = 00:55:27.798jvmUser = 0.00%jvmSystem = 0.13%machineTotal = 4.57%
}jdk.CPULoad {startTime = 00:55:28.796jvmUser = 0.00%jvmSystem = 0.13%machineTotal = 4.91%
}jdk.CPULoad {startTime = 00:55:29.798jvmUser = 0.00%jvmSystem = 0.13%machineTotal = 4.05%
}jdk.CPULoad {startTime = 00:55:30.803jvmUser = 0.13%jvmSystem = 0.13%machineTotal = 2.99%
}jdk.CPULoad {startTime = 00:55:31.804jvmUser = 0.00%jvmSystem = 0.26%machineTotal = 4.36%
}jdk.CPULoad {startTime = 00:55:32.804jvmUser = 0.13%jvmSystem = 0.13%machineTotal = 6.71%
}jdk.CPULoad {startTime = 00:55:33.807jvmUser = 0.00%jvmSystem = 0.26%machineTotal = 4.66%
}jdk.CPULoad {startTime = 00:55:34.814jvmUser = 0.00%jvmSystem = 0.26%machineTotal = 4.82%
}jdk.CPULoad {startTime = 00:55:35.829jvmUser = 0.00%jvmSystem = 0.39%machineTotal = 5.01%
}jdk.CPULoad {startTime = 00:55:36.821jvmUser = 0.00%jvmSystem = 0.26%machineTotal = 4.54%
}jdk.CPULoad {startTime = 00:55:37.822jvmUser = 0.00%jvmSystem = 0.26%machineTotal = 4.29%
}jdk.CPULoad {startTime = 00:55:38.841jvmUser = 0.00%jvmSystem = 0.38%machineTotal = 4.26%
}jdk.CPULoad {startTime = 00:55:39.824jvmUser = 0.00%jvmSystem = 0.26%machineTotal = 3.85%
}jdk.CPULoad {startTime = 00:55:40.832jvmUser = 0.00%jvmSystem = 0.26%machineTotal = 8.03%
}jdk.CPULoad {startTime = 00:55:41.835jvmUser = 0.00%jvmSystem = 0.26%machineTotal = 4.34%
}jdk.CPULoad {startTime = 00:55:42.854jvmUser = 0.00%jvmSystem = 0.38%machineTotal = 5.35%
}jdk.CPULoad {startTime = 00:55:43.839jvmUser = 0.00%jvmSystem = 0.26%machineTotal = 3.89%
}jdk.CPULoad {startTime = 00:55:44.843jvmUser = 0.00%jvmSystem = 0.26%machineTotal = 3.99%
}jdk.CPULoad {startTime = 00:55:45.845jvmUser = 0.00%jvmSystem = 0.39%machineTotal = 5.01%
}jdk.CPULoad {startTime = 00:55:46.846jvmUser = 0.13%jvmSystem = 0.00%machineTotal = 6.59%
}jdk.CPULoad {startTime = 00:55:47.844jvmUser = 0.00%jvmSystem = 0.13%machineTotal = 2.83%
}jdk.CPULoad {startTime = 00:55:48.843jvmUser = 0.00%jvmSystem = 0.13%machineTotal = 3.45%
}jdk.CPULoad {startTime = 00:55:49.845jvmUser = 0.00%jvmSystem = 0.13%machineTotal = 3.61%
}jdk.CPULoad {startTime = 00:55:50.848jvmUser = 0.00%jvmSystem = 0.26%machineTotal = 3.40%
}jdk.CPULoad {startTime = 00:55:51.852jvmUser = 0.00%jvmSystem = 0.26%machineTotal = 3.73%
}jdk.CPULoad {startTime = 00:55:52.869jvmUser = 0.00%jvmSystem = 0.38%machineTotal = 4.37%
}jdk.CPULoad {startTime = 00:55:53.855jvmUser = 0.00%jvmSystem = 0.26%machineTotal = 5.43%
}jdk.CPULoad {startTime = 00:55:54.859jvmUser = 0.00%jvmSystem = 0.13%machineTotal = 7.28%
}jdk.CPULoad {startTime = 00:55:55.858jvmUser = 0.00%jvmSystem = 0.13%machineTotal = 7.23%
}jdk.CPULoad {startTime = 00:55:56.885jvmUser = 0.00%jvmSystem = 0.38%machineTotal = 9.12%
}jdk.CPULoad {startTime = 00:55:57.865jvmUser = 0.00%jvmSystem = 0.27%machineTotal = 3.01%
}jdk.CPULoad {startTime = 00:55:58.865jvmUser = 0.00%jvmSystem = 0.26%machineTotal = 4.01%
}jdk.CPULoad {startTime = 00:55:59.885jvmUser = 0.00%jvmSystem = 0.38%machineTotal = 4.91%
}jdk.CPULoad {startTime = 00:56:00.875jvmUser = 0.00%jvmSystem = 0.26%machineTotal = 10.92%
}jdk.CPULoad {startTime = 00:56:01.872jvmUser = 0.00%jvmSystem = 0.26%machineTotal = 15.21%
}jdk.CPULoad {startTime = 00:56:02.874jvmUser = 0.13%jvmSystem = 0.00%machineTotal = 5.43%
}jdk.CPULoad {startTime = 00:56:03.875jvmUser = 0.00%jvmSystem = 0.13%machineTotal = 5.02%
}jdk.CPULoad {startTime = 00:56:04.875jvmUser = 0.00%jvmSystem = 0.13%machineTotal = 8.98%
}jdk.CPULoad {startTime = 00:56:05.880jvmUser = 0.00%jvmSystem = 0.26%machineTotal = 3.93%
}jdk.CPULoad {startTime = 00:56:06.881jvmUser = 0.00%jvmSystem = 0.26%machineTotal = 4.36%
}jdk.CPULoad {startTime = 00:56:07.882jvmUser = 0.00%jvmSystem = 0.26%machineTotal = 2.74%
}jdk.CPULoad {startTime = 00:56:08.883jvmUser = 0.13%jvmSystem = 0.13%machineTotal = 4.98%
}jdk.CPULoad {startTime = 00:56:09.887jvmUser = 0.00%jvmSystem = 0.26%machineTotal = 4.79%
}jdk.CPULoad {startTime = 00:56:10.893jvmUser = 0.00%jvmSystem = 0.13%machineTotal = 4.32%
}jdk.CPULoad {startTime = 00:56:11.897jvmUser = 0.00%jvmSystem = 0.26%machineTotal = 4.94%
}jdk.CPULoad {startTime = 00:56:12.898jvmUser = 0.00%jvmSystem = 0.26%machineTotal = 4.00%
}jdk.CPULoad {startTime = 00:56:13.900jvmUser = 0.00%jvmSystem = 0.26%machineTotal = 4.47%
}jdk.CPULoad {startTime = 00:56:14.910jvmUser = 0.00%jvmSystem = 0.26%machineTotal = 3.98%
}jdk.CPULoad {startTime = 00:56:15.903jvmUser = 0.00%jvmSystem = 0.26%machineTotal = 4.30%
}D:\develop\jdk\jdk-12\bin>

jdk12新特性

新的Shenandoah(雪兰多)收集器

雪兰多收集器使用的内存结构和G1类似,都是将内存划分为区域,整体流程也和G1相似。关于G1,请参见文章JVM学习之垃圾回收和垃圾回收器相关章节。

最大的区别在于雪兰多收集器实现了并发疏散环节,引入的Brooks Forwarding Pointer技术使得GC在移动对象时,对象的引用仍然可以访问,这样就降低了延迟,相关团队宣城是使99.9%的暂停小于10ms。

 

其工作周期如下:

1)、初始标记,并启动并发标记阶段

2)、并发标记遍历堆阶段

3)、并发标记完成阶段

4)、并发整理回收无活动区域阶段

5)、并发疏散,整理内存区域

6)、初始化更新引用阶段

7)、并发更新引用

8)、完成引用更新阶段

9)、并发回收无引用区域阶段

 

启用方法:

XX:+UnlockExperimentalVMOptions -XX:+UseShenandoahGC

微基准表达式

JMH(Java Microbenchmark Harness)是专门用于代码微基准测试的工具套件,用于方法层面的测试,精度可以达到微秒级。

其主要应用场景有:

1)、想准确知道某个方法需要执行多长时间,以及执行时间和输入之间的相关性

2)、对比接口的不同实现在给定条件下的吞吐量

3)、查看多少百分比的请求在多长时间内完成

 

jdk12添加了一套新的微基准测试,简化了现有微基准测试的运行和新微基准测试的创建过程

switch表达式

这个版本是jdk13的预览功能,所以要将jdk、jre和目标字节码的版本设置为13

首先是箭头操作符,可以同时处理多个case

public class Main {public static void main(String[] args) {Fruit f = Fruit.APPLE;switch (f) {case APPLE -> System.out.println(1);case ORANGE, GRAPE -> System.out.println(2);case PEAR, MANGO, WATERMALLON -> System.out.println(3);default ->System.out.println("No such fruit");}}
}enum Fruit {APPLE, ORANGE, GRAPE, PEAR, MANGO, WATERMALLON
}

输出自然是1

然后也可以把switch块当成一个表达式,用变量接收它的值

public class Main {public static void main(String[] args) {Fruit f = Fruit.APPLE;int ret = switch (f) {case APPLE -> 1;case ORANGE, GRAPE -> 2;case PEAR, MANGO, WATERMALLON -> 3;default ->throw new IllegalStateException("error");};System.out.println(ret);}
}enum Fruit {APPLE, ORANGE, GRAPE, PEAR, MANGO, WATERMALLON
}

这个改进类似于kotlin中的when表达式

JVM常量api

java.base模块新增了java.lang.constant包,里面定义了一系列的基于值的符号引用类型,用于描述每种可加载常量,主要用于节省内存

 

目前基本数据类型的包装类和String都实现了java.lang.constant.Constable和java.lang.constant.ConstantDesc两个接口,两个接口定义如下

package java.lang.constant;import java.lang.Enum.EnumDesc;
import java.lang.invoke.MethodHandle;
import java.lang.invoke.MethodHandles;
import java.lang.invoke.MethodType;
import java.lang.invoke.VarHandle.VarHandleDesc;public interface ConstantDesc {Object resolveConstantDesc(MethodHandles.Lookup lookup) throws ReflectiveOperationException;
}///////////////////////////////////////////////////////////////////////////////////////////////////////////package java.lang.constant;import java.lang.invoke.MethodHandle;
import java.lang.invoke.MethodType;
import java.lang.invoke.VarHandle;
import java.util.Optional;
public interface Constable {Optional<? extends ConstantDesc> describeConstable();
}

主要作用就是让加载这些类的时候更加快捷

只保留一个AArch64实现

之前的jdk存在两个64位的ARM端口,两个端口都产生了aarch64实现,但把src/hotspot/cpu/arm中的称为arm64,把open/src/hotspot/cpu/aarch64称为aarch64

 

jdk12中删除了arm64,只保留其中关于32位的arm端口实现,64位的全交给open/src/hotspot/cpu/aarch64中的AArch64来实现

 

这样就让开发贡献者避免实现两个64的arm

默认类数据共享归档文件

在同一台机器上启动多个JVM时,如果每个JVM都单独装在自己的类,那么启动成本和内存占用就很高。所以java团队就引入了类数据共享机制(Class Data Sharing,简称CDS),即一些核心类在JVM进程间共享,每个JVM只需要装载自己的应用类即可

 

CDS目前可以支持系统类、引导类和应用类,jdk12对此的改进是将其默认使能:-Xshare:auto,并对64位平台的jdk架构进行优化,自动调用java -Xshare:dump,生成的文件保存在JavaHome/lib/server目录下,名为classes.jar

可中止的G1混合收集器

当G1回收耗时超过目标暂停时间,就会终止垃圾回收过程

 

主要思路是:把回收集分为必须部分和可选部分,优先处理必须部分。

必须部分主要包括G1不能递增处理的部分(如年轻代),也可以包含老年代以提高效率。

在优先处理必须部分时,会维护可选部分的一些数据,但产生的CPU开销不会超过1%,而且会增加本机内存使用率;处理完必须部分后,如果还有时间,就处理可选部分,如果剩下时间不够,就可能只处理可选部分的一个子集。处理完一个子集后,G1会根据剩余时间来决定是否继续收集。

G1及时返回未使用的已分配内存

jdk12中的G1将在应用程序不活动期间定期生成或持续循环检测整体的java堆使用情况,以便更及时地将java堆中不使用的内存返回给OS。这一改进带来的优势在云平台的容器环境中更加明显,此时内存利用率的提高会直接降低经济成本

 

jdk12为此新增了两个参数:G1PeriodicGCInterval和G1PeriodicGCSystemLoadThreshold,两者均为0的话表示禁用此功能。前者表示定期检测的周期,后者表示触发内存返回的系统负载阈值

另有一个参数G1PeriodicInvokesConcurrent来控制定期GC的类型,默认是Full GC,如果设置值了,就会继续上一个或启动一个新的并发周期

 

如果定期GC严重影响程序执行,就要考虑程序的CPU负载,或者让用户禁用定期GC。

String中新增的方法

transform()方法

对字符串进行链式转换

String transform = "szc".transform(x -> x + "szc").transform(String::toUpperCase);
System.out.println(transform); // SZCSZC

indent()方法

在字符串的每一行前面加空格

String indent = "szcc\ncc\nanyang".indent(3);
System.out.println(indent);

输出如下,每一行前面加了3个空格

   szccccanyang

Files中新增的方法——mismatch()

返回两个Path对应的文件内容中首次字节不匹配发生的行索引,从0开始。如果返回-1,就是指两个文件内容完全一样

try (FileWriter fileWriter1 = new FileWriter("test1.txt");FileWriter fileWriter2 = new FileWriter("test2.txt")) {fileWriter1.write("a");fileWriter1.write("b");fileWriter1.write("c");fileWriter1.close();fileWriter2.write("a");fileWriter2.write("B");fileWriter2.write("C");fileWriter2.close();System.out.println(Files.mismatch(Path.of("test1.txt"), Path.of("test2.txt")));
} catch (IOException e) {e.printStackTrace();
}

输出为1

其他新增项

新增支持unicode11,包括684个字符、11个块和7个脚本

 

支持压缩数字格式化,比如1000可以格式化为1K,1000000可以格式化为1M,也可以根据指定的语言环境格式化

var cnf = NumberFormat.getCompactNumberInstance(Locale.CHINA, NumberFormat.Style.SHORT);
System.out.println(cnf.format(1L << 30));
System.out.println(cnf.format(1000));
System.out.println(cnf.format(1L << 40));
System.out.println(cnf.format(1_92000));
System.out.println(cnf.format(192000));

输出如下

11亿
1,000
1兆
19万
19万

jdk13新特性

动态CDS档案

CDS是jdk12的特性,jdk13中这个特性支持java应用执行之后进行动态归档,以后执行java程序后一些类就可以直接从这些归档文件中加载了

ZGC:提交未使用的堆内存

ZGC在jdk11中引入的收集器,jdk13中使能了向OS提交未使用的堆内存

 

ZGC中的区域称之为ZPage,当ZGC压缩堆时,ZPage被释放,然后变成ZPageCache,最后使用LRU算法对PageCache区域进行定时清除。时间间隔默认为5分钟,用户自定义时间间隔尚未实现,而如果-Xms和-Xmx相等的话,这个功能就相当于没有

重新实现旧版套接字api

重新实现了Socket接口,新的实现类是NioSocketImpl来替换jdk1.0的PlainSocketImpl,其有以下特点:

1)、使用和NIO相同的内部结构,无需再使用本地代码

2)、和现有的缓冲区机制集成在一起,因此不需要为IO使用线程栈

3)、使用java.util.concurrent锁,而不是synchronized同步方法,增强了并发能力

4)、新的实现是jdk13中的默认实现,但旧的实现还没有删除,可以通过系统属性jdk.net.usePlainSocketImpl(不为空,且不为false)来切换到旧版本

switch表达式中引入yield

default语句里可以单独用yield返回值

String x = "3";
int i = switch (x) {case "1" -> 10;case "3" -> 30;case "4", "5" -> 20;default -> {yield x.length();}
};

case语句里也可以使用yield,但yield和->只能存在一种

i = switch (x) {case "1":System.out.println("aa");yield 10;case "3":System.out.println("bb");yield 30;case "4", "5":yield 20;default:yield x.length();
};

yield用于从switch语句里返回值,作用域要比return小,和->相比它又允许case里有更多的逻辑

文本块

文本块用来表示多行字符串,用一对"""包住即可

String s = """<html><head><meta charset="utf-8"/></head><body><p>aaa</p></body></html>""";

比如表示SQL时

s = """select * from studentswhere id in (12, 13, 14, 15)order by grade desc""";

文本块避免了换行转义,提高了可读性

 

文本块第一个字符为行终止符,所以第一个可见字符必须在第二行

s = """a""";

每一行末尾实际上都有一个行终止符(换行符)。而且,运行时,文本块将被实例化为String实例,所以使用和传统的字符串对象是一样的;编译时,文本块中每一行后面多余的空格会被去掉,前面多余空格数将取决于结束"""的情况:如果结束"""是单独一行的话,保留的空格数将与结束"""对齐;否则全部删除

s = """a""";
System.out.println(s.length()); // 2
var s1 = """a""";
System.out.println(s1.length()); // 1
System.out.println(s1.equals(s)); // false
System.out.println(s1 == "a"); // trues = """a""";
System.out.println(s.length()); // 5

文本块可以表示空字符串

s1 = """""";
System.out.println(s1.equals("")); // true

文本块中显式\n依旧有效

System.out.println("""a\n""".length()); // 3

文本块中的"就不用转义了,但"""需要转义

System.out.println(""""I`ve got to go, \""" now \""". ", said Jason."Ok, as you wish.", said Mike""");/*
"I`ve got to go, """ now """. ", said Jason.
"Ok, as you wish.", said Mike
*/

文本块也可以拼接,注意结束"""就不要单独一行了

System.out.println("""a""" + """bcd"""); // abcd

可以使用replace()方法简化拼接过程

String type = "String";
System.out.println("""The type is $type""".replace("$type", type)); // The type is String

或者formatted()方法,此方法在jdk13刚被引进,就被标记为移除

String type = "String";
System.out.println("The type is %s".formatted(type)); // The type is String

似乎更推荐String.format()方法

System.out.println(String.format("The type is %s", type)); // The type is String

新增项

1)、添加new FileSystem(Path)、new FileSystem(Path, Map<String, ?>)方法

2)、新的ByteBuffer Bulk get/put方法

3)、支持Unicode12.1

4)、添加-XX:SoftMaxHeapSize,仅对ZGC有用

5)、ZGC最大的堆大小升到16TB

总结

语法层面:改进版的switch表达式、文本块

API层面:NioSocketImpl来替换原有的PlainSocketImpl

GC层面:改进了ZGC,以支持回收未使用的内存

jdk14新特性

instanceof省去了强制类型转换的过程

以前是这么写的

Object obj = "szc";
if (obj instanceof String) {String s = (String) obj;
}

现在可以这么写

if (obj instanceof String s) {System.out.println(s);
}

类的equals()方法因此也可以被简化

class Monitor {private String mName;private int mCount;@Overridepublic boolean equals(Object o) {return o instanceof Monitor other && other.mName.equals(mName) && other.mCount == mCount;}
}

更详细的空指针异常

在运行时加上参数-XX:+ShowCodeDetailsInExceptionMessages,可以更详细地显示空指针异常。例如以下代码

public class Main {public static void main(String[] args) {MonitorGroup group = new MonitorGroup();group.show();}
}class MonitorGroup {private List<Monitor> mMonitors;public MonitorGroup() {}public MonitorGroup(List<Monitor> mMonitors) {this.mMonitors = mMonitors;}public void show() {System.out.println(mMonitors.size());}
}class Monitor {
}

运行后报错如下

Exception in thread "main" java.lang.NullPointerException: Cannot invoke "java.util.List.size()" because "this.mMonitors" is nullat com.szc.MonitorGroup.show(Main.java:33)at com.szc.Main.main(Main.java:18)

报出了执行哪个方法时出现了异常,并且给出了哪个变量为空

Record数据结构

Record数据结构可以更方便地创建java bean类

1)、首先创建时选用record

2)、然后给出属性即可,这些属性都是final常量,也就是只能被赋值一次

public record User(String mName, int mAge) {
}

以上代码就相当于原始的属性+有参构造方法+get方法+toString()+equals()+hashcode()方法

User u = new User("szc", 23);
System.out.println(u); // User[mName=szc, mAge=23]
System.out.println(u.mName()); // szc
System.out.println(u.mAge()); // 23
System.out.println(u.equals(new User("szc", 23))); // true
System.out.println(u.hashCode() + ", " + new User("szc", 23).hashCode()); // 3546299, 3546299

record也可以覆写或定义方法,以及静态属性和方法

public record User(String mName, int mAge) {public static String sNation;public static String getNation() {return sNation;}public void show() {System.out.println("Name = " + mName + ", age = " + mAge);}
}

但是不能声明非静态的属性,而且record类也不能是抽象类

public record User(String mName, int mAge) {public static String sNation;// public int mCount;
}// abstract record Person() { }

而且record类是final的,不能有继承语句

// record Count() extends Thread { }

jdk12/13中的switch表达式正式转正

switch表达式终于不是测试功能了..

增强版的文本块

如果不想换行,可以加上\

System.out.println("""aaa\bbb"""); // aaabbb\n

弃用Parallel Scavenge和Serial Old的GC组合

下图中绿色虚线和CMS也被抛弃了,所以只剩下Serial GC -- Serial Old GC、Parallel Scavenge -- Parallel Old和G1三种GC(组合)了。关于这些经典垃圾回收器,请参见文章JVM学习之垃圾回收和垃圾回收器相关章节。

windows和mac上可用ZGC

使用参数为-XX:+UnlockExperimentalVMOptions -XX:+UseZGC

结语

虽然jdk迭代更新很快,但由于成规模的项目用的都是jdk7或jdk8,而且很多第三方库也都是基于jdk7或8的,所以选择对项目的jdk版本升级还是要三思而行,因为这些新的jdk似乎只是让开发更容易,而客户感受不到这些改进,那么带来的经济效益就值得商榷了。

不过,虽然升级jdk或者其他代码重构可能是费力不讨好的事儿,但尝个鲜也无可厚非,就当长见识,开开眼

查看全文
如若内容造成侵权/违法违规/事实不符,请联系编程学习网邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!

相关文章

  1. 分布式一致性算法——Paxos原理与推导过程

    Paxos算法在分布式领域具有非常重要的地位。但是Paxos算法有两个比较明显的缺点:1.难以理解 2.工程实现更难。网上有很多讲解Paxos算法的文章,但是质量参差不齐。看了很多关于Paxos的资料后发现,学习Paxos最好的资料是论文《Paxos Made Simple》,其次是中、英文版维基百科对…...

    2024/4/30 12:18:43
  2. 网络爬虫和爬虫代理之间的关系

    网络爬虫 网络爬虫也叫做网络机器人,可以代替人们自动地在互联网中进行数据信息的采集与整理。在大数据时代,信息的采集是一项重要的工作,如果单纯靠人力进行信息采集,不仅低效繁琐,搜集的成本也会提高。 此时,我们可以使用网络爬虫对数据信息进行自动采集,比如应用于搜…...

    2024/5/1 10:55:29
  3. java实现遍历文件夹下的文件及文件夹

    package com.gblfy.test;import java.io.File; import java.util.ArrayList; import java.util.LinkedList; import java.util.List;/*** 文件常用工具类** @author gblfy* @description FileUtil* @date 2020/07/03 17:05*/ public class FileUtil {/*** 遍历目录下面的文件夹…...

    2024/5/1 5:38:40
  4. SpringBoot-03自动配置原理

    SpringBoot-03自动配置原理 根据当前不同的条件判断,决定这个配置类是否生效!1.一但这个配置类生效;这个配置类就会给容器中添加各种组件; 2.这些组件的属性是从对应的properties类中获取的,这些类里面的每一个属性又是和配置文件绑定的; 3.所有在配置文件中能配置的属性…...

    2024/4/20 12:56:32
  5. linux下安装nvm

    nvm是nodejs的版本管理工具,用于切换nodejs版本在windows下使用exe安装包安装,linux下则使用脚本安装1.下载安装脚本https://github.com/nvm-sh/nvm/blob/master/install.sh2.运行安装脚本czy@Mint ~/workspace/gitee/nvm $ ./install.sh => Downloading nvm from git to…...

    2024/4/20 16:18:37
  6. LeetCode刷题---无重复字符的最长子串(3)

    题目 给定一个字符串,请你找出其中不含有重复字符的 最长子串 的长度。 示例 1: 输入: “abcabcbb” 输出: 3 解释: 因为无重复字符的最长子串是 “abc”,所以其长度为 3。 示例 2: 输入: “bbbbb” 输出: 1 解释: 因为无重复字符的最长子串是 “b”,所以其长度为 1。 示例 …...

    2024/4/16 13:36:14
  7. webpack 配置 alias

    webpack 配置 alias 后很方便,有时有我们项目比较大,比较复杂的时候尤为重要 const path = require(path); const resolvePath = relativePath => path.resolve(process.cwd(), relativePath); { .... alias: {@: resolvePath(src),@common: ../../common,},}...

    2024/4/1 0:28:03
  8. 我要开始写博客啦!!

    我要开始写博客啦!!一个简单的自我介绍 一个简单的自我介绍 20届研一,刚刚开始,和老师交流后准备研究车联网方向,现在开始读论文。准备写博客督促自己学习进度,练习内化输出知识。...

    2024/4/16 13:35:13
  9. HTML DIV 多层显示测试

    <!doctype html> <html> <head><title>table contenteditable</title><style type="text/css">.bg_img {/*相对位置*/position: relative;width: 625px;height: 352px; }.ms {/*绝对位置*/position: absolute;background: #a823…...

    2024/4/19 17:16:31
  10. 制作3389端口修改工具心得1

    设置思路人工修改方法c++操作注册表的方法c++开/关远程桌面的方法 人工修改方法 1、修改注册表 (1)HKEY_LOCAL_MACHINE\SYSTEM\\CurrentControlSet\\Control\\Terminal Server\\WinStations\\RDP-Tcp中的PortNumber (2)HKEY_LOCAL_MACHINE\SYSTEM\\CurrentControlSet\\Cont…...

    2024/4/18 2:42:55
  11. YARN工作流程

    自己画的 有错误请大家指出YARN的运行流程(工作机制) 1.clinet提交程序,向RM申请一个唯一的jobid 2.RM返回一个jobid,并且返回程序提交资源的路径发送给客户端 3.Client端将运行作业所需要的资源(如:jar包,配置文件,切片信息等)向指定的hdfs路径上传(注意:这个hdfs的路…...

    2024/5/2 16:34:35
  12. PAT甲级 A1096

    PAT甲级 A1096 题目详情 1096 Consecutive Factors (20分) Among all the factors of a positive integer N, there may exist several consecutive numbers. For example, 630 can be factored as 3567, where 5, 6, and 7 are the three consecutive numbers. Now given any …...

    2024/4/16 13:36:19
  13. RabbitMQ的应用场景以及基本原理介绍

    RabbitMQ的应用场景以及基本原理介绍 1.背景 RabbitMQ是一个由erlang开发的AMQP(Advanved Message Queue)的开源实现。 2.应用场景 2.1异步处理 场景说明:用户注册后,需要发注册邮件和注册短信,传统的做法有两种1.串行的方式;2.并行的方式 (1)串行方式:将注册信息写入数据库后…...

    2024/5/3 9:54:44
  14. 高等数学知识点汇总

    第一章 函数、极限与连续 1、函数的有界性2、极限的定义(数列、函数)3、极限的性质(有界性、保号性)4、极限的计算(重点)(四则运算、等价无穷小替换、洛必达法则、泰勒公式、重要极限、单侧极限、夹逼定理及定积分定义、单调有界必有极限定理)5、函数的连续性6、间断点的类型7、…...

    2024/4/16 13:37:20
  15. windows10 下用 docker 打包程序

    确定项目包和支持包 先确定项目包的内容,并导出所需要的包,放在项目目录下 pip freeze > requirements.txt创建 Dockerfile 然后与 default 同级创建 Dockerfile# 基于的基础镜像 FROM python:3.6.5#代码添加到 default_docker 文件夹 ADD ./default /default_docker# 设置…...

    2024/4/17 7:03:54
  16. 新增端口用于ssh

    内部服务器新增端口修改sshd_config配置文件vi /etc/ssh/sshd_config找到Port和ListenAddress的配置区域,进行如下修改Port 22 Port 24922 Port 18622说明:打开22注释以防配置发生意外,无法连接服务器重启sshd服务 systemctl restart sshd查看端口开放状态 netstat -nap | grep…...

    2024/5/2 16:20:56
  17. 第十一期:怎样使数据摄入端点的配置更安全?

    配置 ES 3 节点全加密,Kibana 的 SSL 加密配置,Beats 的高可靠性加密传输,用 RBAC 怎样把权限控制到最小,在配置文件中消除明文密码,这些你都做到了么?如何保证安全、能适应和可扩展的配置 Elastic Stack 技术栈,让我们从 Bests 的角度开始讲解,该兴趣的报名参加一下。…...

    2024/5/3 5:40:03
  18. 腾讯最爱考的2道数据分析面试题

    原文作者:腾讯数据分析师 annatx今天给各位分享两道数据分析试题,这是腾讯数据分析面试官在面试时考察候选人喜欢出的题,属于硬性技能考察题目,特别好用。如果你想投鹅厂的数据分析师岗位,强烈建议看看。刷题做实战题目是王道,刷一道顶得上在网上刷百道。以下是面试官在面…...

    2024/4/16 13:37:25
  19. Java学习(数组)

    数组排序及元素查找使用sort()方法对Java数组进行排序, 使用 binarySearch() 方法来查找数组中的元素import java.util.Arrays;//要有public class MainClass {public static void main(String args[]) {int array[] = { 2, 5, -2, 6, -3, 8, 0, -7, -9, 4 };Arrays.sort(arra…...

    2024/4/16 13:36:25
  20. 从PHP到Java的微服务网关演进之路

    背景随着公司业务的飞速发展,基于php的模块化架构难以支持未来业务的发展:php模块化架构远落后于行业主流架构(微服务–>云原生),而php生态的服务治理开源组件匮乏,研发投入过大杭州php人才匮乏,导致新鲜血液招聘困难基于php的多进程架构难以支撑电商高并发业务场景尽…...

    2024/5/3 11:26:07

最新文章

  1. 【Mac】Lightroom Classic 2024 v13.1安装教程

    软件介绍 Lightroom Classic 2024是Adobe公司推出的一款专业的数字图像处理软件&#xff0c;旨在为摄影师提供强大的工具和功能&#xff0c;以管理、编辑和分享他们的照片作品。以下是Lightroom Classic 2024的主要特点和功能&#xff1a; 数字照片管理&#xff1a; 提供直观…...

    2024/5/4 8:01:58
  2. 梯度消失和梯度爆炸的一些处理方法

    在这里是记录一下梯度消失或梯度爆炸的一些处理技巧。全当学习总结了如有错误还请留言&#xff0c;在此感激不尽。 权重和梯度的更新公式如下&#xff1a; w w − η ⋅ ∇ w w w - \eta \cdot \nabla w ww−η⋅∇w 个人通俗的理解梯度消失就是网络模型在反向求导的时候出…...

    2024/3/20 10:50:27
  3. milvus search api的数据结构

    search api的数据结构 此api的功能是向量相似度搜索(vector similarity search) 一个完整的search例子: 服务端collection是一个hnsw类型的索引。 import random from pymilvus import (connections,Collection, )dim 128if __name__ __main__:connections.connect(alias…...

    2024/5/3 3:17:04
  4. HarmonyOS NEXT应用开发之@State装饰器:组件内状态

    State装饰的变量&#xff0c;或称为状态变量&#xff0c;一旦变量拥有了状态属性&#xff0c;就和自定义组件的渲染绑定起来。当状态改变时&#xff0c;UI会发生对应的渲染改变。 在状态变量相关装饰器中&#xff0c;State是最基础的&#xff0c;使变量拥有状态属性的装饰器&a…...

    2024/5/1 2:10:44
  5. 编译amd 的 amdgpu 编译器

    1,下载源码 git clone --recursive https://github.com/ROCm/llvm-project.git 2, 配置cmake cmake -G "Unix Makefiles" ../llvm \ -DLLVM_ENABLE_PROJECTS"clang;clang-tools-extra;compiler-rt" \ -DLLVM_BUILD_EXAMPLESON …...

    2024/5/3 2:37:23
  6. 【外汇早评】美通胀数据走低,美元调整

    原标题:【外汇早评】美通胀数据走低,美元调整昨日美国方面公布了新一期的核心PCE物价指数数据,同比增长1.6%,低于前值和预期值的1.7%,距离美联储的通胀目标2%继续走低,通胀压力较低,且此前美国一季度GDP初值中的消费部分下滑明显,因此市场对美联储后续更可能降息的政策…...

    2024/5/1 17:30:59
  7. 【原油贵金属周评】原油多头拥挤,价格调整

    原标题:【原油贵金属周评】原油多头拥挤,价格调整本周国际劳动节,我们喜迎四天假期,但是整个金融市场确实流动性充沛,大事频发,各个商品波动剧烈。美国方面,在本周四凌晨公布5月份的利率决议和新闻发布会,维持联邦基金利率在2.25%-2.50%不变,符合市场预期。同时美联储…...

    2024/5/2 16:16:39
  8. 【外汇周评】靓丽非农不及疲软通胀影响

    原标题:【外汇周评】靓丽非农不及疲软通胀影响在刚结束的周五,美国方面公布了新一期的非农就业数据,大幅好于前值和预期,新增就业重新回到20万以上。具体数据: 美国4月非农就业人口变动 26.3万人,预期 19万人,前值 19.6万人。 美国4月失业率 3.6%,预期 3.8%,前值 3…...

    2024/4/29 2:29:43
  9. 【原油贵金属早评】库存继续增加,油价收跌

    原标题:【原油贵金属早评】库存继续增加,油价收跌周三清晨公布美国当周API原油库存数据,上周原油库存增加281万桶至4.692亿桶,增幅超过预期的74.4万桶。且有消息人士称,沙特阿美据悉将于6月向亚洲炼油厂额外出售更多原油,印度炼油商预计将每日获得至多20万桶的额外原油供…...

    2024/5/3 23:10:03
  10. 【外汇早评】日本央行会议纪要不改日元强势

    原标题:【外汇早评】日本央行会议纪要不改日元强势近两日日元大幅走强与近期市场风险情绪上升,避险资金回流日元有关,也与前一段时间的美日贸易谈判给日本缓冲期,日本方面对汇率问题也避免继续贬值有关。虽然今日早间日本央行公布的利率会议纪要仍然是支持宽松政策,但这符…...

    2024/4/27 17:58:04
  11. 【原油贵金属早评】欧佩克稳定市场,填补伊朗问题的影响

    原标题:【原油贵金属早评】欧佩克稳定市场,填补伊朗问题的影响近日伊朗局势升温,导致市场担忧影响原油供给,油价试图反弹。此时OPEC表态稳定市场。据消息人士透露,沙特6月石油出口料将低于700万桶/日,沙特已经收到石油消费国提出的6月份扩大出口的“适度要求”,沙特将满…...

    2024/4/27 14:22:49
  12. 【外汇早评】美欲与伊朗重谈协议

    原标题:【外汇早评】美欲与伊朗重谈协议美国对伊朗的制裁遭到伊朗的抗议,昨日伊朗方面提出将部分退出伊核协议。而此行为又遭到欧洲方面对伊朗的谴责和警告,伊朗外长昨日回应称,欧洲国家履行它们的义务,伊核协议就能保证存续。据传闻伊朗的导弹已经对准了以色列和美国的航…...

    2024/4/28 1:28:33
  13. 【原油贵金属早评】波动率飙升,市场情绪动荡

    原标题:【原油贵金属早评】波动率飙升,市场情绪动荡因中美贸易谈判不安情绪影响,金融市场各资产品种出现明显的波动。随着美国与中方开启第十一轮谈判之际,美国按照既定计划向中国2000亿商品征收25%的关税,市场情绪有所平复,已经开始接受这一事实。虽然波动率-恐慌指数VI…...

    2024/4/30 9:43:09
  14. 【原油贵金属周评】伊朗局势升温,黄金多头跃跃欲试

    原标题:【原油贵金属周评】伊朗局势升温,黄金多头跃跃欲试美国和伊朗的局势继续升温,市场风险情绪上升,避险黄金有向上突破阻力的迹象。原油方面稍显平稳,近期美国和OPEC加大供给及市场需求回落的影响,伊朗局势并未推升油价走强。近期中美贸易谈判摩擦再度升级,美国对中…...

    2024/4/27 17:59:30
  15. 【原油贵金属早评】市场情绪继续恶化,黄金上破

    原标题:【原油贵金属早评】市场情绪继续恶化,黄金上破周初中国针对于美国加征关税的进行的反制措施引发市场情绪的大幅波动,人民币汇率出现大幅的贬值动能,金融市场受到非常明显的冲击。尤其是波动率起来之后,对于股市的表现尤其不安。隔夜美国股市出现明显的下行走势,这…...

    2024/5/2 15:04:34
  16. 【外汇早评】美伊僵持,风险情绪继续升温

    原标题:【外汇早评】美伊僵持,风险情绪继续升温昨日沙特两艘油轮再次发生爆炸事件,导致波斯湾局势进一步恶化,市场担忧美伊可能会出现摩擦生火,避险品种获得支撑,黄金和日元大幅走强。美指受中美贸易问题影响而在低位震荡。继5月12日,四艘商船在阿联酋领海附近的阿曼湾、…...

    2024/4/28 1:34:08
  17. 【原油贵金属早评】贸易冲突导致需求低迷,油价弱势

    原标题:【原油贵金属早评】贸易冲突导致需求低迷,油价弱势近日虽然伊朗局势升温,中东地区几起油船被袭击事件影响,但油价并未走高,而是出于调整结构中。由于市场预期局势失控的可能性较低,而中美贸易问题导致的全球经济衰退风险更大,需求会持续低迷,因此油价调整压力较…...

    2024/4/26 19:03:37
  18. 氧生福地 玩美北湖(上)——为时光守候两千年

    原标题:氧生福地 玩美北湖(上)——为时光守候两千年一次说走就走的旅行,只有一张高铁票的距离~ 所以,湖南郴州,我来了~ 从广州南站出发,一个半小时就到达郴州西站了。在动车上,同时改票的南风兄和我居然被分到了一个车厢,所以一路非常愉快地聊了过来。 挺好,最起…...

    2024/4/29 20:46:55
  19. 氧生福地 玩美北湖(中)——永春梯田里的美与鲜

    原标题:氧生福地 玩美北湖(中)——永春梯田里的美与鲜一觉醒来,因为大家太爱“美”照,在柳毅山庄去寻找龙女而错过了早餐时间。近十点,向导坏坏还是带着饥肠辘辘的我们去吃郴州最富有盛名的“鱼头粉”。说这是“十二分推荐”,到郴州必吃的美食之一。 哇塞!那个味美香甜…...

    2024/4/30 22:21:04
  20. 氧生福地 玩美北湖(下)——奔跑吧骚年!

    原标题:氧生福地 玩美北湖(下)——奔跑吧骚年!让我们红尘做伴 活得潇潇洒洒 策马奔腾共享人世繁华 对酒当歌唱出心中喜悦 轰轰烈烈把握青春年华 让我们红尘做伴 活得潇潇洒洒 策马奔腾共享人世繁华 对酒当歌唱出心中喜悦 轰轰烈烈把握青春年华 啊……啊……啊 两…...

    2024/5/1 4:32:01
  21. 扒开伪装医用面膜,翻六倍价格宰客,小姐姐注意了!

    原标题:扒开伪装医用面膜,翻六倍价格宰客,小姐姐注意了!扒开伪装医用面膜,翻六倍价格宰客!当行业里的某一品项火爆了,就会有很多商家蹭热度,装逼忽悠,最近火爆朋友圈的医用面膜,被沾上了污点,到底怎么回事呢? “比普通面膜安全、效果好!痘痘、痘印、敏感肌都能用…...

    2024/5/4 2:59:34
  22. 「发现」铁皮石斛仙草之神奇功效用于医用面膜

    原标题:「发现」铁皮石斛仙草之神奇功效用于医用面膜丽彦妆铁皮石斛医用面膜|石斛多糖无菌修护补水贴19大优势: 1、铁皮石斛:自唐宋以来,一直被列为皇室贡品,铁皮石斛生于海拔1600米的悬崖峭壁之上,繁殖力差,产量极低,所以古代仅供皇室、贵族享用 2、铁皮石斛自古民间…...

    2024/4/28 5:48:52
  23. 丽彦妆\医用面膜\冷敷贴轻奢医学护肤引导者

    原标题:丽彦妆\医用面膜\冷敷贴轻奢医学护肤引导者【公司简介】 广州华彬企业隶属香港华彬集团有限公司,专注美业21年,其旗下品牌: 「圣茵美」私密荷尔蒙抗衰,产后修复 「圣仪轩」私密荷尔蒙抗衰,产后修复 「花茵莳」私密荷尔蒙抗衰,产后修复 「丽彦妆」专注医学护…...

    2024/4/30 9:42:22
  24. 广州械字号面膜生产厂家OEM/ODM4项须知!

    原标题:广州械字号面膜生产厂家OEM/ODM4项须知!广州械字号面膜生产厂家OEM/ODM流程及注意事项解读: 械字号医用面膜,其实在我国并没有严格的定义,通常我们说的医美面膜指的应该是一种「医用敷料」,也就是说,医用面膜其实算作「医疗器械」的一种,又称「医用冷敷贴」。 …...

    2024/5/2 9:07:46
  25. 械字号医用眼膜缓解用眼过度到底有无作用?

    原标题:械字号医用眼膜缓解用眼过度到底有无作用?医用眼膜/械字号眼膜/医用冷敷眼贴 凝胶层为亲水高分子材料,含70%以上的水分。体表皮肤温度传导到本产品的凝胶层,热量被凝胶内水分子吸收,通过水分的蒸发带走大量的热量,可迅速地降低体表皮肤局部温度,减轻局部皮肤的灼…...

    2024/4/30 9:42:49
  26. 配置失败还原请勿关闭计算机,电脑开机屏幕上面显示,配置失败还原更改 请勿关闭计算机 开不了机 这个问题怎么办...

    解析如下&#xff1a;1、长按电脑电源键直至关机&#xff0c;然后再按一次电源健重启电脑&#xff0c;按F8健进入安全模式2、安全模式下进入Windows系统桌面后&#xff0c;按住“winR”打开运行窗口&#xff0c;输入“services.msc”打开服务设置3、在服务界面&#xff0c;选中…...

    2022/11/19 21:17:18
  27. 错误使用 reshape要执行 RESHAPE,请勿更改元素数目。

    %读入6幅图像&#xff08;每一幅图像的大小是564*564&#xff09; f1 imread(WashingtonDC_Band1_564.tif); subplot(3,2,1),imshow(f1); f2 imread(WashingtonDC_Band2_564.tif); subplot(3,2,2),imshow(f2); f3 imread(WashingtonDC_Band3_564.tif); subplot(3,2,3),imsho…...

    2022/11/19 21:17:16
  28. 配置 已完成 请勿关闭计算机,win7系统关机提示“配置Windows Update已完成30%请勿关闭计算机...

    win7系统关机提示“配置Windows Update已完成30%请勿关闭计算机”问题的解决方法在win7系统关机时如果有升级系统的或者其他需要会直接进入一个 等待界面&#xff0c;在等待界面中我们需要等待操作结束才能关机&#xff0c;虽然这比较麻烦&#xff0c;但是对系统进行配置和升级…...

    2022/11/19 21:17:15
  29. 台式电脑显示配置100%请勿关闭计算机,“准备配置windows 请勿关闭计算机”的解决方法...

    有不少用户在重装Win7系统或更新系统后会遇到“准备配置windows&#xff0c;请勿关闭计算机”的提示&#xff0c;要过很久才能进入系统&#xff0c;有的用户甚至几个小时也无法进入&#xff0c;下面就教大家这个问题的解决方法。第一种方法&#xff1a;我们首先在左下角的“开始…...

    2022/11/19 21:17:14
  30. win7 正在配置 请勿关闭计算机,怎么办Win7开机显示正在配置Windows Update请勿关机...

    置信有很多用户都跟小编一样遇到过这样的问题&#xff0c;电脑时发现开机屏幕显现“正在配置Windows Update&#xff0c;请勿关机”(如下图所示)&#xff0c;而且还需求等大约5分钟才干进入系统。这是怎样回事呢&#xff1f;一切都是正常操作的&#xff0c;为什么开时机呈现“正…...

    2022/11/19 21:17:13
  31. 准备配置windows 请勿关闭计算机 蓝屏,Win7开机总是出现提示“配置Windows请勿关机”...

    Win7系统开机启动时总是出现“配置Windows请勿关机”的提示&#xff0c;没过几秒后电脑自动重启&#xff0c;每次开机都这样无法进入系统&#xff0c;此时碰到这种现象的用户就可以使用以下5种方法解决问题。方法一&#xff1a;开机按下F8&#xff0c;在出现的Windows高级启动选…...

    2022/11/19 21:17:12
  32. 准备windows请勿关闭计算机要多久,windows10系统提示正在准备windows请勿关闭计算机怎么办...

    有不少windows10系统用户反映说碰到这样一个情况&#xff0c;就是电脑提示正在准备windows请勿关闭计算机&#xff0c;碰到这样的问题该怎么解决呢&#xff0c;现在小编就给大家分享一下windows10系统提示正在准备windows请勿关闭计算机的具体第一种方法&#xff1a;1、2、依次…...

    2022/11/19 21:17:11
  33. 配置 已完成 请勿关闭计算机,win7系统关机提示“配置Windows Update已完成30%请勿关闭计算机”的解决方法...

    今天和大家分享一下win7系统重装了Win7旗舰版系统后&#xff0c;每次关机的时候桌面上都会显示一个“配置Windows Update的界面&#xff0c;提示请勿关闭计算机”&#xff0c;每次停留好几分钟才能正常关机&#xff0c;导致什么情况引起的呢&#xff1f;出现配置Windows Update…...

    2022/11/19 21:17:10
  34. 电脑桌面一直是清理请关闭计算机,windows7一直卡在清理 请勿关闭计算机-win7清理请勿关机,win7配置更新35%不动...

    只能是等着&#xff0c;别无他法。说是卡着如果你看硬盘灯应该在读写。如果从 Win 10 无法正常回滚&#xff0c;只能是考虑备份数据后重装系统了。解决来方案一&#xff1a;管理员运行cmd&#xff1a;net stop WuAuServcd %windir%ren SoftwareDistribution SDoldnet start WuA…...

    2022/11/19 21:17:09
  35. 计算机配置更新不起,电脑提示“配置Windows Update请勿关闭计算机”怎么办?

    原标题&#xff1a;电脑提示“配置Windows Update请勿关闭计算机”怎么办&#xff1f;win7系统中在开机与关闭的时候总是显示“配置windows update请勿关闭计算机”相信有不少朋友都曾遇到过一次两次还能忍但经常遇到就叫人感到心烦了遇到这种问题怎么办呢&#xff1f;一般的方…...

    2022/11/19 21:17:08
  36. 计算机正在配置无法关机,关机提示 windows7 正在配置windows 请勿关闭计算机 ,然后等了一晚上也没有关掉。现在电脑无法正常关机...

    关机提示 windows7 正在配置windows 请勿关闭计算机 &#xff0c;然后等了一晚上也没有关掉。现在电脑无法正常关机以下文字资料是由(历史新知网www.lishixinzhi.com)小编为大家搜集整理后发布的内容&#xff0c;让我们赶快一起来看一下吧&#xff01;关机提示 windows7 正在配…...

    2022/11/19 21:17:05
  37. 钉钉提示请勿通过开发者调试模式_钉钉请勿通过开发者调试模式是真的吗好不好用...

    钉钉请勿通过开发者调试模式是真的吗好不好用 更新时间:2020-04-20 22:24:19 浏览次数:729次 区域: 南阳 > 卧龙 列举网提醒您:为保障您的权益,请不要提前支付任何费用! 虚拟位置外设器!!轨迹模拟&虚拟位置外设神器 专业用于:钉钉,外勤365,红圈通,企业微信和…...

    2022/11/19 21:17:05
  38. 配置失败还原请勿关闭计算机怎么办,win7系统出现“配置windows update失败 还原更改 请勿关闭计算机”,长时间没反应,无法进入系统的解决方案...

    前几天班里有位学生电脑(windows 7系统)出问题了&#xff0c;具体表现是开机时一直停留在“配置windows update失败 还原更改 请勿关闭计算机”这个界面&#xff0c;长时间没反应&#xff0c;无法进入系统。这个问题原来帮其他同学也解决过&#xff0c;网上搜了不少资料&#x…...

    2022/11/19 21:17:04
  39. 一个电脑无法关闭计算机你应该怎么办,电脑显示“清理请勿关闭计算机”怎么办?...

    本文为你提供了3个有效解决电脑显示“清理请勿关闭计算机”问题的方法&#xff0c;并在最后教给你1种保护系统安全的好方法&#xff0c;一起来看看&#xff01;电脑出现“清理请勿关闭计算机”在Windows 7(SP1)和Windows Server 2008 R2 SP1中&#xff0c;添加了1个新功能在“磁…...

    2022/11/19 21:17:03
  40. 请勿关闭计算机还原更改要多久,电脑显示:配置windows更新失败,正在还原更改,请勿关闭计算机怎么办...

    许多用户在长期不使用电脑的时候&#xff0c;开启电脑发现电脑显示&#xff1a;配置windows更新失败&#xff0c;正在还原更改&#xff0c;请勿关闭计算机。。.这要怎么办呢&#xff1f;下面小编就带着大家一起看看吧&#xff01;如果能够正常进入系统&#xff0c;建议您暂时移…...

    2022/11/19 21:17:02
  41. 还原更改请勿关闭计算机 要多久,配置windows update失败 还原更改 请勿关闭计算机,电脑开机后一直显示以...

    配置windows update失败 还原更改 请勿关闭计算机&#xff0c;电脑开机后一直显示以以下文字资料是由(历史新知网www.lishixinzhi.com)小编为大家搜集整理后发布的内容&#xff0c;让我们赶快一起来看一下吧&#xff01;配置windows update失败 还原更改 请勿关闭计算机&#x…...

    2022/11/19 21:17:01
  42. 电脑配置中请勿关闭计算机怎么办,准备配置windows请勿关闭计算机一直显示怎么办【图解】...

    不知道大家有没有遇到过这样的一个问题&#xff0c;就是我们的win7系统在关机的时候&#xff0c;总是喜欢显示“准备配置windows&#xff0c;请勿关机”这样的一个页面&#xff0c;没有什么大碍&#xff0c;但是如果一直等着的话就要两个小时甚至更久都关不了机&#xff0c;非常…...

    2022/11/19 21:17:00
  43. 正在准备配置请勿关闭计算机,正在准备配置windows请勿关闭计算机时间长了解决教程...

    当电脑出现正在准备配置windows请勿关闭计算机时&#xff0c;一般是您正对windows进行升级&#xff0c;但是这个要是长时间没有反应&#xff0c;我们不能再傻等下去了。可能是电脑出了别的问题了&#xff0c;来看看教程的说法。正在准备配置windows请勿关闭计算机时间长了方法一…...

    2022/11/19 21:16:59
  44. 配置失败还原请勿关闭计算机,配置Windows Update失败,还原更改请勿关闭计算机...

    我们使用电脑的过程中有时会遇到这种情况&#xff0c;当我们打开电脑之后&#xff0c;发现一直停留在一个界面&#xff1a;“配置Windows Update失败&#xff0c;还原更改请勿关闭计算机”&#xff0c;等了许久还是无法进入系统。如果我们遇到此类问题应该如何解决呢&#xff0…...

    2022/11/19 21:16:58
  45. 如何在iPhone上关闭“请勿打扰”

    Apple’s “Do Not Disturb While Driving” is a potentially lifesaving iPhone feature, but it doesn’t always turn on automatically at the appropriate time. For example, you might be a passenger in a moving car, but your iPhone may think you’re the one dri…...

    2022/11/19 21:16:57