月度记录-2023-10月

208 阅读10分钟

1. .cfb是什么文件

.CFB是一种文件格式,它代表复合文件二进制(Compound File Binary)格式。它是一种用于存储和组织多种类型数据的文件格式。CFB文件格式最常见的用途是在Microsoft Office文件中,如.doc、.xls和.ppt文件中。

CFB文件是一种层次化的二进制文件格式,它使用一种树状结构来组织数据。它可以包含多个存储对象(如文本、图像、音频等),并使用目录结构来管理这些对象。CFB文件中的每个对象都有一个唯一的标识符,并可以通过该标识符进行访问和检索。

CFB文件格式提供了一种有效的方式来存储和管理多种类型的数据,并允许在文件中进行随机访问。这使得它非常适合用于存储复杂的文档、电子表格和演示文稿等Microsoft Office文件。

2. minio:什么是预签名

预签名(Presigned)是一种机制,用于生成一个临时的URL,允许在不需要进行身份验证的情况下访问受保护的资源。在MinIO中,预签名URL允许您生成一个临时的URL,用于访问存储在MinIO对象存储中的对象,而无需提供访问密钥或进行身份验证。这对于与其他应用程序或用户共享对象或在特定时间范围内提供临时访问权限非常有用。预签名URL具有时间限制,一旦过期,就无法再使用。

3. 获取一小时有多少秒,等等。。。

int expiry = (int) TimeUnit.HOURS.toSeconds(1L);

4. 后端查出来数据返回到前端,少了八个小时

设置时区即可

@JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss", timezone = "GMT+8")

5. 启动时禁止Activiti加载processes目录下的BPMN文件

以下参数设置为false即可

activiti: check-process-definitions: false

6. activiti中HistoryService.createHistoricProcessInstanceQuery()的variableValueEquals查询变量,为什么把符合条件的任务变量也给查出来了?不是只查询流程变量吗?

当您使用variableValueEquals()方法来设置查询条件时,它将检查流程实例的所有变量(包括流程变量和任务变量),并返回符合条件的历史流程实例。

7. 谷歌的v8引擎内存大小限制

V8是一款主流的javascript执行引擎,采用即时编译(速度快);V8对内存设置了限制,在64位系统内存大小不超过1.4G,在32位系统内存大小不超过700M,限制大小是因为,第一,V8本身是为浏览器制造的,这个大小对应网页来说已经足够了;第二,和V8的GC算法有关,在回收垃圾时程序是暂停执行的,如果一次回收过多的垃圾,程序会暂停过长从而影响用户体验。

8. java实体类字段名大写导致的knife4j文档不显示参数说明的问题

大写在文档上还会转为小写,swagger就存在这个问题,knife4j完美的继承了过来。。

因为Swagger 默认使用 Java Bean 规范来解析实体类的属性。解决方法:确保实体类的字段名遵循 Java Bean 规范,即首字母小写。

经过我的测试,第一个和第二个字母都不能大写,大写就出不来,而且参数会变为全小写,坑啊!!!

9. Skywalking

SkyWalking是一个开源的应用性能监控工具

目前市面上开源的APM系统主要有CAT、Zipkin、Pinpoint、SkyWalking,大都是参考Google的Dapper实现的

10. maven filtering过滤resource下的文件

<filtering>true</filtering>
<includes>
    <include>**.yml</include>
    <include>config/**</include>
    <include>mapper/*.xml</include>
    <include>logback-spring.xml</include>
    <include>processes/*</include>
</includes>

11. curl

Curl(全称:Client for URLs)是一个开源的命令行工具和库,用于进行数据传输,特别是通过各种网络协议从服务器获取数据。Curl 支持多种协议,包括HTTP、HTTPS、FTP、SCP、SFTP、LDAP、SMTP,等等。它可在各种操作系统上运行,包括Linux、macOS、Windows等。

Curl 是一个功能强大的工具,常用于命令行界面,可以用来执行各种网络请求和操作,如下载文件、上传文件、发送HTTP请求、测试API等。它可以通过简单的命令行参数完成各种网络任务,也可以用于自动化脚本和程序中,以便进行网络数据传输和交互。

12. 记一次bug

上线前生产环境测出来bug说文件下载有问题,经过排查发现报错是minio生成下载外链失败,去服务器上看,是根本就没有那个bucket和object。加呗,加上去之后倒是不报生成外链错误了,下载直接弹个窗出来,也不下载。

经过排查发现生成的外链是内网ip,所以第一次尝试,把ip和端口替换为外网的。发现还是不ok。

第二次尝试,第二次觉得可能是nginx的问题,所以让请求先去访问nginx,再通过nginx打到内网上,自然也是不行。

第三次尝试:在前两种都不行的情况下,想到了是不是生成的链接有问题,换句话说,直接生成对的ip不行吗?有了这个想法之后就去检察这个ip是在哪配置的,测试后发现是配置文件,配置文件些什么最后生成的就是什么。

一个简单的问题,绕了这么一大圈。回想一下还是排查问题的思路有问题,ip不对,为什么要去替换ip?直接让他生成对的ip不好吗?真是自作聪明,正好minio生成的下载链接,是只能用配置文件里写的那个ip下载。这就导致做了无头苍蝇,通过试错去解决问题,而不是通过逻辑推理。根本原因还是没有深入了解minio以及部署环境,导致无法准确定位问题。

13. RTFM和STFW

14. 如果浏览器cookie被禁掉,token咋办

好的做法是用html5的数据存储,之后通过http请求标头传后端。可以选择存在localStorage或sessionStorage。区别如下:

数据生命周期:

localStorage:存储在 localStorage 中的数据是持久性的,即使关闭浏览器或重新启动计算机,数据仍然保留在其中,直到您明确删除它们。

sessionStorage:存储在 sessionStorage 中的数据只在当前会话期间有效。一旦关闭浏览器标签或窗口,数据就会被销毁。

访问范围:

localStorage:存储在 localStorage 中的数据在同一浏览器的不同窗口或标签页之间共享。

sessionStorage:存储在 sessionStorage 中的数据仅在同一标签页或窗口中共享,不同标签页或窗口无法访问彼此的数据。

15. select ... for update

使用 SELECT ... FOR UPDATE 语句可以在事务中实现悲观锁(pessimistic locking)的机制,确保查询结果的数据在事务期间不会被其他事务修改。这对于处理并发操作和保证数据的一致性非常有用。

16. mysql默认的repeatable read隔离级别下 update是行锁还是表锁?

update操作既可以是行锁也可以是表锁,具体取决于执行update语句的条件、事务隔离级别等因素。

如果update语句中的where条件,where条件包含索引列,并且只更新一条数据那这个时候就会加行锁,如果where条件中不包含索引列这个时候就会加表锁。

另外根据查询范围不同,Mysql也会选择不同粒度的锁。(挖个坑!!!)

来分析一个例子:mysql隔离级别为可重复读。如果我有个user表,userid不是主键。我开启事务,update一条并不存在的数据,例如userid为1的数据。此时开启第二个事务,也去update那个userid为1的数据,这时候第二个update语句会被阻塞吗?

答:经测试,不管去update存在的数据,还是不存在的数据,甚至插入数据,都会被阻塞,总之这张表就是用不了。

表锁!表锁!

再来分析:如果userid加了索引呢?

答:开启事务UPDATE qqq SET isdelete = 'Y' WHERE userid = '001',然后UPDATE qqq SET isdelete = 'Y' WHERE userid = '0011',互相不影响。

但是如果开启事务UPDATE qqq SET isdelete = 'Y' WHERE userid = '001',再开启事务UPDATE qqq SET isdelete = 'Y' WHERE userid = '001',这个时候就会阻塞。

行锁!行锁!

再来测试:如果搞出来两个表,然后搞两条会锁表的sql。在两个事务中先后执行,会怎样?

答:UPDATE rrr SET name = 'Y' WHERE mm = '5sdf55'

UPDATE qqq SET isdelete = 'Y' WHERE name = 'dasfds'

这两条都会锁表,我开启事务a和b交换这两条执行的先后顺序,然后惊喜出现了,mysql报错:1213 - Deadlock found when trying to get lock; try restarting transactio

WOW,差点就以为mysql很脆弱了,原来没有那么脆弱。但mysql的性能还是很容易受到影响,通过今天下午的鼓捣意识到还是得看那两本mysql的书。

17. 那delete呢?

delete 的where条件如果不加索引,那么也是表锁

delete的where调价如果加了索引,那么也是行锁。但是吧,只有删除是行锁。如果删除掉,事务不提交,那么这个时候在另外一个事务中还是不能插入数据的。

tips:where如果是多个条件,不管条件有没有索引,全都是表锁。where!!!最好只有一个条件,且加了索引。

(我现在所得到的结论,可能都是错的,我现在就像是山洞里的人)

18. spring做数字正整数校验

import javax.validation.constraints.Positive;
@Validated // 类上加注解开启校验
public class XXXController {
    // @Positive表示只能输入正数
    public void select(@RequestParam("num") @Positive Integer num) {
    }
}

这么写可以校验参数,省去了if语句,这本来不值得我记录,但是我发现报错竟然是中文的:select.num: 必须是正数。

这就有点6l,明显是应用程序配置了 Bean Validation(JSR 380)的中文本地化支持。

那什么是JSR 380?

chatgpt答:Bean Validation(JSR 380)是Java平台的一项规范,旨在为Java应用程序提供对象验证和校验的通用框架。它定义了一组注解,这些注解可以用于验证和校验JavaBean对象的属性值。这有助于确保应用程序中的数据符合特定的规则和要求,从而提高数据质量和安全性。

例如:@NotNull、@Size、@Email、@Min、@Max、@Pattern等等都是包含在内的。

规范的好处啊,很整洁,但是还得去学习。

19. DATEDIFF(DAY, SYSDATE, cqsj) < 1;这段sql什么意思

这段SQL使用了DATEDIFF函数来计算两个日期之间的天数差异,通常用于日期比较。

注意:并不是比较是否差距超过一整天,这个是按照天来计算的。假设当前系统日期是2023-10-29 23:59,用于比较的参数是2023-10-30 00:01,这样DATEDIFF函数依然得到1天,而不是小于一天。

20. git提交类型规范

feat: 新功能(feature)
fix: 修补bug
docs: 文档(documentation)
style: 格式(不影响代码运行的变动)
refactor: 重构(即不是新增功能,也不是修改bug的代码变动)
chore: 构建过程或辅助工具的变动
revert: 撤销,版本回退
perf: 性能优化
test:测试
improvement: 改进
build: 打包
ci: 持续集成

21. 数据库表结构生成word文档

screw