时间API在更新,传奇已经谢幕,但技术永远不死

CSDN 博文征集活动(和日期相关的代码和bug):点击这里
各位 “big guys”,这篇博文主要讲解一下JDK8 之后 时间相关 API 的变革,与 Java 源起两部分内容。JDK8 Oracle 更新了大量新特性,比如大家熟知的 Stream 和 Lambda API,本文主要重点讲解:时间相关的API。
文章目录
- Part A:我记忆中的 Java 源起公司 Sun Microsystems
- Sun 故去的辉煌
- 太阳从升起到最耀眼,花了近二十年,而陨落却只用了不到一年时间!
- Part B:Java 中的时间、日期 API
- JDK8 以前的时间、日期 API 以及缺点
- JDK8 新日期、时间 API
- 新日期与时间类
- LocalDate 和 LocalTime
- LocalDateTime
- Instant
- Duration
- Period
- 日期的操作和格式化
- 增加和减少日期
- 格式化日期
- 时区 相关
- Part C:没有如果的如果(云计算领域博主怎会在文中不提云计算)
Part A:我记忆中的 Java 源起公司 Sun Microsystems
在2000年最高峰期, Sun 公司 市值最高时超过 2000亿美元,全球有5万多员工。当时,在“新经济四骑士”(即Sun Microsystems、甲骨文、思科和EMC)的推动下,科技行业不断走向繁荣,那个时候,马克·扎克伯格(Mark Zuckerberg)还是一个高中生,而我还不知道在哪里玩泥巴,更不知道 Java 是个什么东西。

Sun 故去的辉煌
我上大学之后才知道 Sun 公司,才开始了解 Eclipse(日食)基金会,Oracle,微软,IBM,Google这几个公司的世纪大战与渊源纠缠,也知道了 Java。
Sun 公司和很多传奇企业一样,都是从斯坦福大学孵化出的高科技公司,Sun 公司的名字由来就是斯坦福大学网络(Stanford University Network)的首字母缩写而来,说来斯坦福大学也真的传奇,堪称高科技公司的摇篮孵化场,硅谷的支柱。以后有机会可以写一篇文章来做介绍。
Sun 在 1995 年发明了 Java 语言,有人可能不太明白,觉得语言又卖不了钱,新推出的语言一般都是求着开发者去使用,是的语言确实卖不了钱,打个比方 English 这门语言是公开的,它不是商品,但是服务和解决方案却是要收钱的(很遗憾 Sun 没有发现这一点)。
那么 Java 本身的潜质怎么样呢,可以用“横空出世,后无来者”来形容。这个不能说的太细,马上就会打起来了(比如有人会说 php 必须是最好的语言),程序员之间相互评论对方的语言,就像是不同的大夫评论彼此的处方一样,是非常不文明的行为,有时候更像是不同教徒评论对方的信仰。
Sun 公司除了造就了 Java 外,还被大家熟知还有:Solaris 操作系统、ZFS、网络文件系统(NFS)、和SPARC 微处理器,其实 Sun 公司对多项关键计算技术的发展做出了重大贡献,其中包括Unix、RISC 处理器、瘦客户端计算和虚拟化计算. 值得注意的 Sun 收购包括VirtualBox的创建者Cray Business Systems Division、Storagetek和Innotek GmbH。
注意这里所提到的,Sun 公司以前拥有过虚拟化技术 VirtualBox,也就是在 2008年 Sun 收购了 VirtualBox,当然现在你也已经知道 VBox现在是 Oracle 的产品了。
Sun 公司市值最高的时候超过市值超过两千亿美元,而且远远超过当时市值排名第二的 Google 的一千七百亿美元、和排名第三的 IBM 的一千六百亿美元。它的办公面积超过五十个足球场(四十五万平方米),并且还有十几个足球场大小的办公楼。太阳公司不仅当时打败了包括 IBM 在内的全部工作站(Work Station)和小型机(Mini Computer)公司,而且依靠它的 Solaris(一种Unix)和风靡世界的 Java 程序语言,成为在操作系统上最有可能挑战微软的公司。太阳公司不乏能人,它不仅为 Google 培养了 CEO 埃里克·施密特和首任工程部副总裁韦恩.罗森(Wayne Rosen),并且在一定程度上奠定了今天 Google 工程部门的基础。

太阳从升起到最耀眼,花了近二十年,而陨落却只用了不到一年时间!
2008年金融危机你一定知道,Sun 公司也没有挺过这次危机,最终结果是 Sun 公司破产,于 2009年被 Oracle 公司以74亿美元收购。
早在2000美国互联网泡沫破裂之后,Sun 公司从前一年盈利9亿美元瞬间变成亏损5亿美元,之后便一蹶不振,跌出一线互联网巨头行列。其中缘由种种,很难用一句话两句话可以讲完(巨难受中… …)。

Sun 公司失败了,但成功的是留下了 Java。
1991年4月,James Gosling(JAVA之父)博士带着一帮小弟开始了绿色计划,这个计划最初目标是为了开发一种能在各种电子产品上跑的程序架构。这个就是 Java 的前身:Oak。
1995年互联网兴起后,Oak更名为 Java,在 SunWorld 大会上正式发布 Java1.0,并提出了 “Write Once,Run Anywhere”。(Java:想偷懒么, 那就加入我们吧)

Part B:Java 中的时间、日期 API
JDK8 以前的时间、日期 API 以及缺点
java.util.Date 可以说是一个糟糕的类型,这也就解释了为什么在 Java 1.1 中弃用了这么多(但不幸的是很多地方仍在使用)。
上学的时候记得老师讲课的时候就有吐槽过Date类型的设计缺陷,毕业后感触越发强烈。设计缺陷总结起来包括:
-
旧 Date API 的名字具有误导性:它不代表一个Date,它代表一个瞬间。所以它应该被称为
Instant,就像它的 java.time 等价一样。 -
旧 Date API 不是
final类型的:这就鼓励了对继承的不良使用,例如java.sql.Date(这意味着代表一个日期,并且由于具有相同的短名称也很容易混淆,这一点我到现在都要吐槽,以前自动引包快捷键按完的提示记忆犹新) -
旧 Date API 是可变的:日期/时间类型是自然值,由于旧 API 是可变的Date类型(例如可以通过setTime方法改变),这也就意味着开发人员最终会到处创建避免被修改的副本对象(
哪个S.X这几天改了代码,我的代码前几天测试好好的,今天怎么bug了)。// 例如,假设我们想比较两个 Date 对象,假设它们分别表示的是 2018 年 5 月 28 日和 2018 年 5 月 29 日。那么我们可能会用下面的代码: Date date1 = new Date(2018, 5, 28); Date date2 = new Date(2018, 5, 29); if (date1.compareTo(date2) > 0) { System.out.println("date1 is after date2"); }在上述例子中由于 Date 对象是可变的,我们需要确保 date1 和 date2 在比较之前没有被修改。如果没有注意,date2 可能会在比较之前被修改,从而导致比较的结果不准确。
-
旧 Date API 的月份编号是从 0 开始的,早期是直接从C语言中复制过来的,这就导致很多月份差一个月的错误。举例来说:
Date d = new Date(2022, 3, 5);// 此处的3表示4月份,因为月份编号是从0开始的 System.out.println(d); // 输出:Tue Apr 05 00:00:00 CST 2022 -
旧 Date API 的方法命名不明确:getDate() 返回月中的第几天,而getDay() 返回星期几(造孽啊!离谱)。
-
旧 Date API 是否支持闰秒是模棱两可的:“秒用0到61的整数表示;值 60 和 61 只出现在闰秒中,即使这样也只出现在实际正确跟踪闰秒的 Java 实现中。” 我强烈怀疑大多数开发人员(包括我自己)已经做出了大量假设,即 for 的范围getSeconds()实际上在 0-59 范围内(含 0-59)。
-
旧 Date API 明确表示一个值:一个瞬间,没有关联的日历系统、时区或文本格式,精确到毫秒。
总之旧的 Date API由于设计缺陷,造成很多地方容易出错,也迷惑程序员,很可能写出很多bug。
JDK8 新日期、时间 API
JDK 8中增加了一套全新的日期时间API,新的 API 设计合理,且是线程安全的。
新日期与时间类
LocalDate 和 LocalTime
LocalDate 类表示一个具体的日期,但不包含具体时间,也不包含时区信息。可以通过 LocalDate 的静态方法 of() 创建一个实例,LocalDate 也包含一些方法用来获取年份,月份,天,星期几等
LocalDate localDate = LocalDate.of(2023, 2, 22); // 初始化一个日期:2023-02-22
int year = localDate.getYear(); // 年份:2023
Month month = localDate.getMonth(); // 月份:FEBRUARY
int dayOfMonth = localDate.getDayOfMonth(); // 月份中的第几天:22
DayOfWeek dayOfWeek = localDate.getDayOfWeek(); // 一周的第几天:WEDNESDAY
int length = localDate.lengthOfMonth(); // 月份的天数:28
boolean leapYear = localDate.isLeapYear(); // 是否为闰年:false// 也可以调用静态方法now()来获取当前日期:
LocalDate now = LocalDate.now(); // 2023-02-22
LocalTime 和 LocalDate 类似,他们之间的区别在于 LocalDate 不包含具体时间,而 LocalTime 包含具体时间,例如:
LocalTime localTime = LocalTime.of(8, 8, 8); // 初始化一个时间:8:08:08
int hour = localTime.getHour(); // 时:8
int minute = localTime.getMinute(); // 分:8
int second = localTime.getSecond(); // 秒:8
LocalDateTime
LocalDateTime 类可以看做是 LocalDate 和 LocalTime 的结合体,可以通过 of()方法直接创建,也可以调用 LocalDate 的 atTime() 方法或LocalTime 的 atDate() 方法将 LocalDate 或 LocalTime 合并成一个 LocalDateTime,例如:
LocalDateTime ldt1 = LocalDateTime.of(2023, Month.JANUARY, 4, 17, 23, 52);LocalDate localDate = LocalDate.of(2023, Month.JANUARY, 4);
LocalTime localTime = LocalTime.of(17, 23, 52);
LocalDateTime ldt2 = localDate.atTime(localTime);// LocalDateTime 也提供用于向 LocalDate 和 LocalTime 的转化:
LocalDate date = ldt1.toLocalDate();
LocalTime time = ldt1.toLocalTime();
Instant
Instant 用于表示一个时间戳,它与我们常使用的 System.currentTimeMillis() 有些类似,不过 Instant 可以精确到纳秒(Nano-Second),System.currentTimeMillis() 方法只精确到毫秒(Milli-Second)。如果查看 Instant 源码,发现它的内部使用了两个常量,seconds 表示从1970-01-01 00:00:00 开始到现在的秒数,nanos 表示纳秒部分(nanos 的值不会超过999,999,999)。Instant 除了使用 now() 方法创建外,还可以通过 ofEpochSecond 方法创建,例如:
// ofEpochSecond()方法的第一个参数为秒,第二个参数为纳秒,
// 下面代码表示从1970-01-01 00:00:00开始后两分钟的10万纳秒的时刻
Instant instant = Instant.ofEpochSecond(120, 100000); // 1970-01-01T00:02:00.000100Z
Duration
Duration 的内部实现与 Instant 类似,也是包含两部分:seconds 表示秒,nanos 表示纳秒。两者的区别是 Instant 用于表示一个时间戳(或者说是一个时间点),而 Duration 表示一个时间段,所以 Duration 类中不包含 now() 静态方法。可以通过 Duration.between() 方法创建Duration对象,例如:
LocalDateTime from = LocalDateTime.of(2023, Month.JANUARY, 5, 10, 7, 0); // 2023-01-05 10:07:00
LocalDateTime to = LocalDateTime.of(2023, Month.FEBRUARY, 5, 10, 7, 0); // 2023-02-05 10:07:00
Duration duration = Duration.between(from, to); // 表示从 2023-01-05 10:07:00 到 2023-02-05 10:07:00 这段时间long days = duration.toDays(); // 这段时间的总天数
long hours = duration.toHours(); // 这段时间的小时数
long minutes = duration.toMinutes(); // 这段时间的分钟数
long seconds = duration.getSeconds(); // 这段时间的秒数
long milliSeconds = duration.toMillis(); // 这段时间的毫秒数
long nanoSeconds = duration.toNanos(); // 这段时间的纳秒数
Duration 对象还可以通过 of() 方法创建,该方法接受一个时间段长度,和一个时间单位作为参数,例如:
Duration duration1 = Duration.of(10, ChronoUnit.DAYS); // 10天
Duration duration2 = Duration.of(1000, ChronoUnit.MILLIS); // 1000毫秒
Period
Period 在概念上和 Duration 类似,区别在于 Period 是以年月日来衡量一个时间段,比如5年3个月4天:
Period period = Period.of(5, 3, 4);
Period 对象也可以通过between()方法创建,值得注意的是,由于 Period 是以年月日衡量时间段,所以 between() 方法只能接收 LocalDate类型的参数,例如:
// 2023-01-05 到 2023-02-05 这段时间
Period period = Period.between(LocalDate.of(2023, 1, 5),LocalDate.of(2023, 2, 5));
日期的操作和格式化
增加和减少日期
JDK8 中的日期、时间类都是不可变的(用final修饰),这是为了保证线程安全。当然,新的日期/时间类也提供了方法用于创建对象的可变版本,比如增加一天或者减少一天(这就非常Oracle,有没有觉得和数据库的时间加减函数一样),例如:
LocalDate date = LocalDate.of(2023, 1, 5); // 2023-02-22LocalDate date1 = date.withYear(2023); // 修改为 2023-02-22
LocalDate date2 = date.withMonth(2); // 修改为 2023-02-22
LocalDate date3 = date.withDayOfMonth(1); // 修改为 2023-02-01LocalDate date4 = date.plusYears(1); // 增加一年 2024-02-22
LocalDate date5 = date.minusMonths(2); // 减少两个月 2023-12-22
LocalDate date6 = date.plus(5, ChronoUnit.DAYS); // 增加5天 2023-02-27
上面例子中对于日期的操作比较简单,但是有些时候我们要面临更复杂的时间操作,比如将时间调到下一个工作日,或者是下个月的最后一天,这时候我们可以使用with()方法的另一个重载方法,它接收一个TemporalAdjuster参数,可以使我们更加灵活的调整日期,例如:
LocalDate date7 = date.with(nextOrSame(DayOfWeek.SUNDAY)); // 返回下一个距离当前时间最近的星期日
LocalDate date9 = date.with(lastInMonth(DayOfWeek.SATURDAY)); // 返回本月最后一个星期六
格式化日期
新的日期API中提供了一个 DateTimeFormatter 类用于处理日期格式化操作,它被包含在 java.time.format 包中,JDK 8 的日期类有一个format() 方法用于将日期格式化为字符串,该方法接收一个 DateTimeFormatter 类型参数,例如:
LocalDateTime dateTime = LocalDateTime.now();
String strDate1 = dateTime.format(DateTimeFormatter.BASIC_ISO_DATE); // 20230222
String strDate2 = dateTime.format(DateTimeFormatter.ISO_LOCAL_DATE); // 2023-02-22
String strDate3 = dateTime.format(DateTimeFormatter.ISO_LOCAL_TIME); // 14:20:16.998
String strDate4 = dateTime.format(DateTimeFormatter.ofPattern("yyyy-MM-dd")); // 2023-02-22
String strDate5 = dateTime.format(DateTimeFormatter.ofPattern("今天是:YYYY年 MMMM DD日 E", Locale.CHINESE)); // 今天是:2023年 二月 22日 星期三
同样,日期类也支持将一个字符串解析成一个日期对象,例如:
String strDate6 = "2023-01-22";
String strDate7 = "2023-02-22 14:30:05";LocalDate date = LocalDate.parse(strDate6, DateTimeFormatter.ofPattern("yyyy-MM-dd"));
LocalDateTime dateTime1 = LocalDateTime.parse(strDate7, DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss"));
时区 相关
JDK 8中的时区操作被很大程度上简化了,新的时区类java.time.ZoneId是原有的java.util.TimeZone类的替代品。ZoneId 对象可以通过ZoneId.of() 方法创建,也可以通过ZoneId.systemDefault()获取系统默认时区,例如:
ZoneId shanghaiZoneId = ZoneId.of("Asia/Shanghai");
ZoneId systemZoneId = ZoneId.systemDefault();
of()方法接收一个“区域/城市”的字符串作为参数,你可以通过getAvailableZoneIds()方法获取所有合法的“区域/城市”字符串:
Set<String> zoneIds = ZoneId.getAvailableZoneIds();
对于老的时区类TimeZone,Java 8也提供了转化方法:
ZoneId oldToNewZoneId = TimeZone.getDefault().toZoneId();
有了ZoneId,我们就可以将一个LocalDate、LocalTime或LocalDateTime对象转化为ZonedDateTime对象:
LocalDateTime localDateTime = LocalDateTime.now();
// 其输出结果为:2017-01-05T15:26:56.147+08:00[Asia/Shanghai]
ZonedDateTime zonedDateTime = ZonedDateTime.of(localDateTime, shanghaiZoneId);
另一种表示时区的方式是使用ZoneOffset,它是以当前时间和世界标准时间(UTC)/ 格林威治时间(GMT)的偏差来计算,例如:
ZoneOffset zoneOffset = ZoneOffset.of("+09:00");
LocalDateTime localDateTime = LocalDateTime.now();
OffsetDateTime offsetDateTime = OffsetDateTime.of(localDateTime, zoneOffset);
Part C:没有如果的如果(云计算领域博主怎会在文中不提云计算)

在文中 Part A 中我有提到过,Sun 公司在 2008年 Sun 收购了 VirtualBox,虚拟化技术成熟的公司,另外一提的是,Sun 最著名的贡献之一是“网络即是计算机(The Network Is The Computer)”的口号,它是由 Sun 公司的 CEO Scott McNealy 在1996年提出的。
他们在近三十年前就意识到 网络即是计算机,网络作为单独的研究对象,它具有计算能力,存储能力,这活脱脱就是互联网乃至云计算的思维啊!后来大家也知道了,真正云计算这个名词开始兴起的时候,也就是 Sun 即将破产的时候。
云计算始于2007年,当时亚马逊推出S3存储服务,开创了全新的云计算时代。随后,谷歌,微软,IBM等多家公司都推出了自己的云计算服务,使云计算的发展变得越来越迅速。
如果 Sun 从开始全力投入云计算,那么在提出网络即是计算机10年后云计算浮出水面的时候,Sun可能就是最大玩家了。
- 如果 Sun 没有轻敌微软
- 如果 Sun 没有摆烂Java
- 如果 Sun 没有收购 MySQL
- 如果 Sun 不押宝所有赌注在硬件和 solaris x86 上

相关文章:
时间API在更新,传奇已经谢幕,但技术永远不死
(Bill Joy(左一),Vinod Khosla(左二),Andy Bechtolsheim(右二),Scott McNealy(右一) ) CSDN 博文征集活动(和日期相关的代码和bug):点击这里 各位 “big guys”,这篇博文…...
SQL调优指南笔记22:Gathering Diagnostic Data with SQL Test Case Builder
本文为SQL Tuning Guide 第21章“Gathering Diagnostic Data with SQL Test Case Builder”的笔记。 SQL Test Case Builder 是一种工具,可自动收集在不同数据库实例中重现问题所需的信息。 SQL 测试用例是一组信息,使开发人员能够为遇到性能问题的特定…...
从0开始学python -43
Python3 正则表达式 正则表达式是一个特殊的字符序列,它能帮助你方便的检查一个字符串是否与某种模式匹配。 Python 自1.5版本起增加了re 模块,它提供 Perl 风格的正则表达式模式。 re 模块使 Python 语言拥有全部的正则表达式功能。 compile 函数根…...
Kafka基本原理
总述 简介 Kafka是最初由Linkedin公司开发,是一个分布式、支持分区的(partition)、多副本的(replica),基于zookeeper协调的分布式消息系统,它的最大的特性就是可以实时的处理大量数据以满足各…...
css3的重点内容
css3的重点内容 浮动 父级边框塌陷问题 浮动的清除 clear:left; //清除左侧浮动 clear:right; //清除右侧浮动 clear:both; //清除两侧浮动解决方案 增加父级元素的高度增加一个空的div,之后清除浮动通过overflow来进行相关元素的修剪给父类添加相应的伪类元素…...
《Roller: Fast and Efficient Tensor Compilation for Deep Learning》
《Roller: Fast and Efficient Tensor Compilation for Deep Learning》 用于深度学习 快速高效的张量编译器 作者 微软亚洲研究院以及多伦多大学等多所高校 摘要 当前编译为了产生高效的kernel时,搜索空间大,通常使用机器学习的方法 找到最优的方案…...
顺丰同城测试开发一面 49min答案,全文7000字,面试总结都在这里了
今天给大家分享一份顺丰同城的测试开发一面面试真题。老规矩,当你看到这份面试题的时候,先不要着急去看答案,你可以想想假如你在面试现场,你会怎么回答?这个思考的过程其实也是很重要的。 全文7000字干货,…...
docker启动容器服务之后访问失败
关于docker启动容器服务之后,宿主机访问失败(解决方法) 注:在进行docker容器启动宿主机进行容器访问时,无需进行网络的配置,docker容器在启动时会自动解决 第一种原因及修改方法 在进行启动的时候&#…...
GraalVM-云原生时代的JVM(Java)
文章目录一、GraalVM是什么?二、GraalVM有哪些特点?2.1、高性能2.2、多语言支持2.3、互操作性2.4、安全性三、GraalVM的应用效果3.1、提高性能3.2、简化开发3.3、降低成本3.4、节省资源3.5、支持云环境四、使用GraalVM编译springboot应用程序4.1、下载并…...
如何外网登录访问瑞友天翼应用虚拟化系统?——快解析内网端口映射方案
瑞友天翼应用虚拟化系统(GWT System)是国内具有自主知识产权的应用虚拟化平台,是基于服务器计算(Server-based Computing)的应用虚拟化平台。如何将内网平台提供到互联网上外网访问,是我们比较关注的问题。…...
蓝海彤翔执行副总裁张加廷接受【联播苏州】独家专访
今年春节档,科幻类电影《流浪地球2》票房口碑双丰收,截至目前,累计票房已破 38 亿,淘票票评分 9.6 ,影片的特效质感可以媲美国际顶尖水平。其中,蓝海彤翔为影片的后期制作提供了出色的渲染服务。2月21日&am…...
iOS Airplay Screen Mirroring 同屏技术详解
投屏技术已经被大量用在身边的产品,比如电视投屏,投影仪,视频会议产品中。 在iOS平台外的其他平台中都已经有非常成熟的标准和实现。但在封闭的苹果iOS和Mac系统中,苹果使用私有的Airplay协议进行多屏互动,只开放给自己…...
更新 Python 100道基础入门检测练习题【下篇】(附答案)
前言 大家早好、午好、晚好吖 ❤ ~ 爆肝更新 Python 100道基础入门练习题【篇上】 更多精彩内容、资源皆可点击文章下方名片获取此处跳转 实例021:猴子偷桃 题目: 猴子吃桃问题:猴子第一天摘下若干个桃子,当即吃了一半…...
[RDMA-高级计算机网络report] Congestion Control for Large-Scale RDMA Departments
本文主要解决的问题是在RoCEv2体系中,基于优先级的拥塞控制PFC是一种粗粒度的机制。 它在端口(或端口加优先级)级别上运行,并且不区分流。PAUSE机制是基于每个端口(和优先级)的,而不是基于每个流…...
ROS2功能包Hello world(python)
文章目录环境准备Python创建工作空间、功能包及节点方法编译使用环境准备 为了便于日后复现,相关环境已经打包到docker中。 拉取docker镜像 docker pull 1224425503/ros2_foxy_full:latest新建容器 docker run -dit --rm --privilegedtrue --network host -e NV…...
数学建模竞赛的一些心得体会
1.数学建模经验首先简要的介绍一下我的情况。数学建模我也是在大一暑假开始接触的,之前对其没有任何的了解。我本身对数学也有相对较厚的兴趣,同时我也是计算机专业的学生,因此,我觉得我可参加数学建模的这个比赛。大一的暑假参加…...
什么是自动化测试?自动化测试现状怎么样?
什么是自动化测试:其实自动化测试,就是让我们写一段程序去测试另一段程序是否正常的过程,自动化测试可以更加省力的替代一部分的手动操作。 现在自动化测试的现状,也是所有学习者关心的,但现在国内公司主要是以功能测…...
CHAPTER 2 Web HA集群部署 - Heartbeat
Web HA集群部署 - Heartbeat1. Heartbeat 概述1.1 Heartbeat主要组成部分2. 环境依赖2.1 环境及组件软件2.2 关闭firewalld & selinux2.3 配置双机互信,SSH密钥登录2.4 同步时间(以主节点时间为准)2.5 配置域名解析3 安装软件3.1 安装…...
蓝桥杯每日一题:不同路径数(dfs深度优先)
给定一个 nm的二维矩阵,其中的每个元素都是一个 [1,9] 之间的正整数。 从矩阵中的任意位置出发,每次可以沿上下左右四个方向前进一步,走过的位置可以重复走。 走了 k 次后,经过的元素会构成一个 (k1) 位数。 请求出一共可以走出…...
NCRE计算机等级考试Python真题(十)
第十套试题1、数据库系统的核心是___________。A.数据库管理系统B.数据模型C.软件工具D.数据库正确答案: A2、下列叙述中正确的是___________。A.线性表链式存储结构的存储空间可以是连续的,也可以是不连续的B.线性表链式存储结构与顺序存储结构的存储空…...
uniapp微信小程序视频实时流+pc端预览方案
方案类型技术实现是否免费优点缺点适用场景延迟范围开发复杂度WebSocket图片帧定时拍照Base64传输✅ 完全免费无需服务器 纯前端实现高延迟高流量 帧率极低个人demo测试 超低频监控500ms-2s⭐⭐RTMP推流TRTC/即构SDK推流❌ 付费方案 (部分有免费额度&#x…...
工业自动化时代的精准装配革新:迁移科技3D视觉系统如何重塑机器人定位装配
AI3D视觉的工业赋能者 迁移科技成立于2017年,作为行业领先的3D工业相机及视觉系统供应商,累计完成数亿元融资。其核心技术覆盖硬件设计、算法优化及软件集成,通过稳定、易用、高回报的AI3D视觉系统,为汽车、新能源、金属制造等行…...
【JavaWeb】Docker项目部署
引言 之前学习了Linux操作系统的常见命令,在Linux上安装软件,以及如何在Linux上部署一个单体项目,大多数同学都会有相同的感受,那就是麻烦。 核心体现在三点: 命令太多了,记不住 软件安装包名字复杂&…...
在web-view 加载的本地及远程HTML中调用uniapp的API及网页和vue页面是如何通讯的?
uni-app 中 Web-view 与 Vue 页面的通讯机制详解 一、Web-view 简介 Web-view 是 uni-app 提供的一个重要组件,用于在原生应用中加载 HTML 页面: 支持加载本地 HTML 文件支持加载远程 HTML 页面实现 Web 与原生的双向通讯可用于嵌入第三方网页或 H5 应…...
Mysql中select查询语句的执行过程
目录 1、介绍 1.1、组件介绍 1.2、Sql执行顺序 2、执行流程 2.1. 连接与认证 2.2. 查询缓存 2.3. 语法解析(Parser) 2.4、执行sql 1. 预处理(Preprocessor) 2. 查询优化器(Optimizer) 3. 执行器…...
使用Spring AI和MCP协议构建图片搜索服务
目录 使用Spring AI和MCP协议构建图片搜索服务 引言 技术栈概览 项目架构设计 架构图 服务端开发 1. 创建Spring Boot项目 2. 实现图片搜索工具 3. 配置传输模式 Stdio模式(本地调用) SSE模式(远程调用) 4. 注册工具提…...
解读《网络安全法》最新修订,把握网络安全新趋势
《网络安全法》自2017年施行以来,在维护网络空间安全方面发挥了重要作用。但随着网络环境的日益复杂,网络攻击、数据泄露等事件频发,现行法律已难以完全适应新的风险挑战。 2025年3月28日,国家网信办会同相关部门起草了《网络安全…...
提升移动端网页调试效率:WebDebugX 与常见工具组合实践
在日常移动端开发中,网页调试始终是一个高频但又极具挑战的环节。尤其在面对 iOS 与 Android 的混合技术栈、各种设备差异化行为时,开发者迫切需要一套高效、可靠且跨平台的调试方案。过去,我们或多或少使用过 Chrome DevTools、Remote Debug…...
数据结构:递归的种类(Types of Recursion)
目录 尾递归(Tail Recursion) 什么是 Loop(循环)? 复杂度分析 头递归(Head Recursion) 树形递归(Tree Recursion) 线性递归(Linear Recursion)…...
基于鸿蒙(HarmonyOS5)的打车小程序
1. 开发环境准备 安装DevEco Studio (鸿蒙官方IDE)配置HarmonyOS SDK申请开发者账号和必要的API密钥 2. 项目结构设计 ├── entry │ ├── src │ │ ├── main │ │ │ ├── ets │ │ │ │ ├── pages │ │ │ │ │ ├── H…...
