Categories
未分类

Java 中 Date 和 LocalDateTime 互相转换

LocalDateTime 转换为 Date 看示例: 输出结果: 简单分析下: 先调用 LocalDateTime 的 atZone 方法(参数为系统默认时区),获取带时区信息的 ZonedDateTime 时间对象,然后转换为 Instant 瞬时对象。最后通过 Date 的 from 方法创建 Date 对象。 Date 转换为 LocalDateTime 看示例: 输出结果: 简单分析下: 先转换 Date 为 Instant 瞬时对象,再调用 LocalDateTime 的 ofInstant 方法(第二个参数为系统默认时区)即可。 其它 完整源码,请参阅:LocalDatetimeAndDate.java。 (全文完) 扫码阅读和分享

Categories
PHP

PHP 通过 Redis NX 特性实现独占锁

对于简单的业务,我们可以通过单实例的 Redis 实现一个全局独占锁。笔者以 PHP 为例,实现一个加锁类。 实现原理 对于 Redis 的 SET 命令,支持 NX 特性,官方解释为:Only set the key if it does not already exist。也就是,当 key 不存在时设置成功后,才会返回 OK,否则返回 nil。这样,当多个并发请求设置 key 时,只有一个会成功。 然后,结合 EX 过期时长,指定加锁时长,即过期后自动释放锁。再通过指定 key 的值为随机 Token,来保证当前操作不会错误的释放其它业务请求的锁。详见下文实例。 SET 用法如下: 具体实现 实例的完整源码,放到了:https://github.com/xingchaovv/php-example/tree/master/src/RedisLocker,请参考使用。源码基于 PHP 8。 方法 lock 实现 方法 unlock 实现 用法 (完) 扫码阅读和分享

Categories
未分类

PHP 8 新特性:从构造函数直接声明属性

在 PHP 8 之前,自定义的类中,对于一个属性的初始化和使用过程是这样的。如下: 在 PHP 8 之后,我们可以直接在构造函数中将入参声明为类属性,并指明访问权限和变量类型。如下: 通过代码“__construct(private string $name)”,声明了属性变量 name,指明访问权限为 private,类型为 string。当通过构造函数构建实例时,直接对 name 进行了赋值。 (完) 扫码阅读和分享

Categories
PHP

PHP 8 新特性: Nullsafe 操作符(空安全)

PHP 8 新增了 Nullsafe 操作符(空安全):?->,顾名思义,以一种安全的方式操作可能为 null 的对象。以此可以简化对于 null 值的逻辑判断。 准备 我们先准备一些类和实例。如下: 以往实现 不严谨的程序员,想获取 user1 的 total 信息时,可能会直接取值。如下: 当然,程序会直接报错: 有点经验的程序员这么做(实际会经常这么做): 当然,实际中还需要对 fanInfo 等做一系列判断,也可能无法避免一些嵌套的判断。 Nullsafe 实现 现在有了 Nullsafe 操作符,我们可以直接这样用: 输出结果: 当然 user1 为 null 时,表达式直接返回了 null,且不再会调用属性 fanInfo 和后续操作。下面详细介绍求值策略。 短路求值策略 Nullsafe 操作符遵循的是完全短路(Full Short Circuiting)的求值策略。 举例说明: 当 a 为 null 时,方法 b 不会被调用,$foo 被赋值为 null。 当 a 为 null […]

Categories
PHP

PHP 8 函数 str_contains:检查是否包含子字符串

PHP 8 中新增了一个函数 str_contains,专门用于检查一个字符串是否包含了另外一个字符串。很大原因是 strpos 函数不够直观且容易出错。这里简单介绍下。 原型如下: 如果字符串 $haystack 中包了字符串 $needle,则返回 true,否则为 false。检查时大小写敏感。 看下例子: 输出为: 因为大小写敏感,第二行返回 false。 如同第三行,当目标字符串为空字符串时,结果总是为 true。 参考资料 str_contains 扫码阅读和分享

Categories
PHP

PHP 8 新特性:联合类型

定义 在 PHP 8 中,定义函数参数的类型时,可以指定多种类型;也就是允许它的值为这些类型中的一种;我们称这种类型为联合类型(Union Types)。 一般语法 联合类型的语法格式为: 举第一个例子 🌰: 上文中 int|float 指明了参数 $score 为联合类型,它可以是 int 类型 或 float 类型。 输出结果为: 上文中,因为传递了不允许的类型 string,直接抛出 TypeError 类型的错误。 ?Type 语法 我们可以指定类型为某个 Class 或者 null,比如 DateTime|null,简化写法为 ?Type。 另外,不支持单独使用类型 null。 举第二个例子 🌰: 输出为: 伪类型 false 可以在联合类型使用伪类型 false,比如 string|false。另外,不支持单独使用类型 false。暂不支持伪类型 true(保留关键字)。 参考资料 Type declarations 扫码阅读和分享

Categories
PHP

PHP 8 新特性:命名参数

PHP 8 新增了语言特性:命名参数(Named Arguments)。以往只能按照函数定义的顺序传递参数,现在可以指定参数名称自定义顺序。并且可以跳过带默认值的参数。 正文 我们举例说明。 我们先定义一个函数,接受三个参数。函数中直接将实际接收到的参数打印出来。代码如下: 在 PHP 7 中,我们调用函数时,不允许带参数名称。如下: 在 PHP 8 中,我们可以像下面这样。 指定默认顺序参数名,效果同上 参数一二顺序换位,不受影响 跳过带有默认值的参数 type。 无参数名和带参数名混合使用 话外 除了 PHP,还有哪些语言支持命名参数呢? Python:见《Expressions -> Calls》、《Python Keyword Arguments》 C# 4:见《命名实参和可选实参》 Swift:见《Functions -> Functions With Multiple Parameters》 参考资料: PHP RFC: Named Arguments (完) 扫码阅读和分享

Categories
未分类

Java 类成员四种访问级别在不同位置下的可见性

Java 里有四种访问控制级别,分别为:public、protected、default 和 private。default 为默认级别。 如下表,展示了四种访问级别在不同位置下的可见性。 位置\访问级别(可见性) public protected default private 当前类 可见 可见 可见 可见 当前包(含包内的子类) 可见 可见 可见 可见 子类(包外的子类) 可见 可见(仅继承) 不可见 不可见 包外(不含子类) 可见 不可见 不可见 不可见 (全文完) 扫码阅读和分享

Categories
PHP

PhpSpreadsheet(PHP Excel 类库)正确显示身份证号的解决办法

PhpSpreadsheet(原 PHPExcel)是 PHP 中最流行的电子表格软件(如 Excel)的处理类库,可以读取、写入 Excel 数据等,经常用于业务系统的报表导出等。 问题复现 在使用过程中,经常遇到的问题是,无法正常显示身份证号。我们看下实例: 源文件:sheet1.php 终端下执行下:% php sheet1.php,保存到了文件 users.xlsx,查看结果: 可见,莱德等小狗狗的身份证号,默认被当作了数字数据类型。 原因分析 这是因为在通过 fromArray 间接或 或直接使用 setCellValue 方法时,未指定数据类型。这时,PhpSpreadsheet 使用值绑定器(Value Binder)自动将传入的参数转换为合适的 Cell 数据类型。具体源码实现,见默认的值绑定器是 DefaultValueBinder。此处身份证号虽然是原生 string,但符合类对数字的定义,处理成了数字数据类型。 解决办法:使用 setCellValueExplicit 我们在设置值时使用 setCellValueExplicit 方法指定类型。 天天的身份证号已经正常显示。 若希望类似 fromArray 批量写入数据,可自行实现一个迭代处理。 解决办法:自定义值绑定器 另外一种办法是实现自定义的值绑定器类。 直接看实现源码: 结果 实现说明: 这里自定义了类 MyValueBinder,扩展了 DefaultValueBinder,“重写”了方法 dataTypeForValue。 参考资料 文档 Accessing cells (全文完) 扫码阅读和分享

Categories
未分类

Macbook Pro 2017 款 13 寸板载内存和硬盘升级小记

引言 笔者有一个 13 寸苹果本,主要放在公司做开发用。最近顺利地进行了升级,和大家分享一下。 笔记本是 MacBook Pro (13-inch, 2017, Two Thunderbolt 3 ports),型号为 A1708 EMC 3164(见笔记本背面),13 寸的低配版,8 G 内存和 128 G 硬盘。技术规则见:https://support.apple.com/kb/SP754?locale=zh_CN。 苹果为追求利润最大化 🐶 ,凭借不同的内存和硬盘配置带来的体验差别,来实现成本最低的价格歧视(见)。同时 2018 款及后续笔记本都采用了板载内存和板载硬盘(均带 Touchbar),消费者几乎不能自己升级。笔者的这一款有点例外,属于最后一款可拆卸硬盘的。但内存属于板载内存,所以升级板载内存是个难点。 升级前 升级前,内存为主板集成的 8G,如下。 硬盘为 128G,如下。 升级过程 内存升级 对于内存,从 B 站上找到一个专门升级板载内存笔记本的 UP 主。笔者找到他的淘宝店,直接下单拍了升级内存的服务,花费 865 元。我把自己的硬盘拆卸下来,邮寄过去,对方升级完成后,回寄回来。升级挺快,不算邮寄时间,两天搞定。 硬盘升级 硬盘的选择 经查,一共有三种硬盘可供选择:原装拆机硬盘、代工硬盘、转接卡硬盘。 原装拆机硬盘,最为稳定,同容量价格最贵。考虑到需要稳定且 256G 已完全满足需求,故笔者选择这个。 代工硬盘,淘宝商家有售。兼容性比转接卡硬盘好些。 转接卡硬盘,即通过专门的 A1708 转接卡配合 NVMe 固态硬盘。可能有兼容性问题,价格也最便宜。 重点:对于原装拆机硬盘,较早生产的硬盘可能存在故障的情况,需要注意,可以通过查询序列号判断是否存在问题。详见:13 […]