(置顶) 日常笔记

EVERYTHING IS HERE

Posted by gomyck on February 27, 2022

把一些零散的知识点都记录到这里

Certificate request error is persistent (TLS Certificate can’t be provisioned)

1
2
3
4
5
6
7
8
9
10
11
12
I had the same issue, turns out Github does not issue a TSL certificate unless your CNAME record is for www pointing to your username.github.io.
It took me days to figure that sucker out. Your problem should be solved within a few minutes after you change your DNS settings.

Here is what namecheap.com says:

Here you will need to create several records for your domain:

A record for @ pointing to 185.199.108.153
A record for @ pointing to 185.199.109.153
A record for @ pointing to 185.199.110.153
A record for @ pointing to 185.199.111.153
CNAME record for www pointing to your username.github.io (the username should be replaced with your actual GitHub account username):

POSTGRESQL在容器内由于 shm 过小, 导致吞吐量过低的问题

k8s 解决方案, 忽略了没用的参数, 具体方案是挂载 emptyDir, 媒介是内存, 大小是 512Mi

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
---
apiVersion: apps/v1
kind: StatefulSet
metadata:
  annotations: {}
spec:
  serviceName: postgres
  template:
    spec:
      containers:
        - volumeMounts:
            - mountPath: /dev/shm
              name: shm-volume
      volumes:
        - emptyDir:
            medium: Memory
            sizeLimit: 512Mi
          name: shm-volume

docker 解决方案

1
2
3
4
5
// 重建容器
--shm-size=512m
// 已有容器修改, 停止 docker 服务, 使用 inspect 查看容器挂载的卷, cd 进去后, 找到 hostconfig 文件(查看HostsPath这一项), 修改其中的 shm-size 大小
shm-size 默认大小是 64 * 1024 * 1024=64MB, 根据算法可自行计算
修改后, 重启 docker 服务, 进入容器 df -h 可发现 shem 大小已经改变

使用 EBS 创建的 pvc, 启动 mysql 报错

因为 mysql 在初始化时, 需要的是一个空文件夹, 但是 jiva 驱动出的 pvc, 里面有个lost+found, 还删不掉, 所以要在 mysql 的启动参数上加一个参数

1
--ignore-db-dir=lost+found

nexus 搭建 docker 私服

在使用 nexus 搭建 docker 私服时, 需要开启realms

Security > Realms > 把 docker bearer token realm 设置成 active

否则 docker 配置的 registry-mirrors 不好使

如果还是不行的话, 重启 nexus 解决

spring 资源文件加载方式

spring中资源加载的地址前缀如下:

classpath:表示从类路径加载资源

file:使用UrlResource从文件系统目录中装载资源,可采用绝对或相对路径

http:// :从Web服务器中装载资源

ftp:// : 从FTP服务器中装载资源

其中,classpath:和classpath*:的区别在于classpath*:会扫描所有类路径下出现的资源,而classpath只会在第一个加载的包下查找,即就是只加载一个资源文件。 ———————————————— 原文链接:https://blog.csdn.net/zhuxinquan61/article/details/53589874

js 中把字符串转 Unicode 码的方法

1
2
3
const str = 'ADFGSADASD';
const unicode = str.charCodeAt(1); //第二个字符转Unicode码
const newStr = String.fromCharCode(unicode); //Unicode 转字符串

为什么在 spring 中俩个 bean 互相依赖 却没有报循环依赖的错误?

spring bean 之间的依赖分为两种:

  1. A弱依赖B: 即A 的实例化过程不需要 B 的参与, 一般来说, 如果构造函数为默认, 那么 bean 中的依赖大部分都为弱依赖
  2. A强依赖B: 即A 的实例化过程需要 B 的参与, 在初始化 A 的时候需要使用 B 的实例来执行一些业务逻辑

在不使用依赖注入技术时, 我们通常使用构造函数去传入实例化时需要的依赖对象, 这样久而久之, 类之间的依赖关系就会变得难以管理, 而造成代码维护,运行时风险提高

spring 通过以下几种方式降低了类之间的依赖紧密度:

  1. 使用无参构造函数
  2. 使用 setter getter 或注解分析依赖关系, 并自动注入需要的
  3. 通过bean 的声明周期, 横向分解类实例化的过程, 把实例化与实例化期间执行的逻辑分解到: @PostConstruct 和 InitializingBean 的 afterPropertiesSet()中

通过上述三种方式, 使 bean 的初始化变得无状态化, 而在所有 bean 都实例化之后统一管理后续的生命周期方法, 进而达到依赖调节的目标, 使强依赖弱化为弱依赖

结论: 通过构造函数的依赖传递可能造成无法调解的强依赖, 通过 setter/getter 进行依赖注入可以被调解

上述结论在 @Configuration 注解的类中不适用

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
@Configuration
public class ConfigurationBean{

  // b 是强依赖, spring 为了规避内部其他 bean 在初始化时的空指针风险(initA 中用到了 b), 强制规定配置类的属性为强依赖
  @Bean
  private B b;

  @Bean
  private A initA(){
    //if use b, and b is null
    return new A();
  }

}

忽略maven 从父工程继承的spring-boot-maven-plugin插件

因为大部分工程都是服务类工程, 所以我在顶级工程中配置了spring-boot-maven-plugin, 方便子工程使用, 但是有例外的非微服务工程也集成顶级工程

此时需要排除spring-boot-maven-plugin插件, 以免出现错误, exp: 找不到 main-class, 配置如下:

1
2
3
<properties>
    <spring-boot.repackage.skip>true</spring-boot.repackage.skip>
</properties>

具体请看: RepackageMojo.java

servlet3.0 注解声明 servlet 不生效的问题

应该是 web.xml 的版本太低了, 导致应用的 servlet 标准低, 换成下方版本可解决

1
2
3
4
5
6
7
8
9
10
<web-app xmlns="http://java.sun.com/xml/ns/javaee"
	      xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
	      xsi:schemaLocation="http://java.sun.com/xml/ns/javaee
	      http://java.sun.com/xml/ns/javaee/web-app_3_0.xsd"
	      version="3.0">

  <display-name>Servlet 3.0 Web Application</display-name>


</web-app>

自定义 starter 偏好文件自动生成 yml 提示

在工程中加入以下依赖, 那么配置了 configurationProperties 的类将会自动生成偏好文件描述

1
2
3
4
5
<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-autoconfigure-processor</artifactId>
    <optional>true</optional>
</dependency>

maven 整体版本号提升

1
2
3
4
5
mvn versions:set -DnewVersion=1.1.1-SNAPSHOT

mvn versions:revert

mvn versions:commit

idea mapper 不显示提示

设置了数据源, 但是 mybatis 的 xml 还是不显示表提示, 点击 preference, 然后搜索 sql resolution, 选择数据源即可

建表常用字段

1
2
3
4
5
6
7
alter table tableName
    add hold_flag int default 0 not null comment '0:启用  1:禁用',
    add delete_flag int default 0 not null comment '0:未删除 >0 删除',
    add create_time datetime not null comment '创建时间',
    add create_user_id bigint not null comment '创建人 ID',
    add update_time datetime null comment '更新时间',
    add update_user_id bigint null comment '更新人 ID';

MAC 蓝牙功率调解

1
2
3
4
5
6
7
defaults write com.apple.BluetoothAudioAgent "Apple Bitpool Max (editable)" 80
defaults write com.apple.BluetoothAudioAgent "Apple Bitpool Min (editable)" 80
defaults write com.apple.BluetoothAudioAgent "Apple Initial Bitpool (editable)" 80
defaults write com.apple.BluetoothAudioAgent "Apple Initial Bitpool Min (editable)" 80
defaults write com.apple.BluetoothAudioAgent "Negotiated Bitpool" 80
defaults write com.apple.BluetoothAudioAgent "Negotiated Bitpool Max" 80
defaults write com.apple.BluetoothAudioAgent "Negotiated Bitpool Min" 80

ruby 安装大坑

yum 安装的 ruby 版本太低了 大概是 2.0.0 左右的版本, 不满足一些其他应用 gem 安装的版本要求 所以不要使用 yum 安装 ruby

而且 yum 安装的 ruby 有问题, gem 也有问题 很奇怪

推荐使用 rvm 管理 ruby 版本

官网链接: http://rvm.io/ 根据 rvm 官网提示, 需要先下载公钥, 从 gpg 仓库, 但是这里有一个大坑

gpg2 –recv-keys 409B6B1796C275462A1703113804BB82D39DC0E3 7D2BAF1CF37B13E2069D6956105BD0E739499BDB

这个链接时好时坏, 至少我最近一次安装 rvm 的时候, 就不好用, gpg no name 的错误

解决办法: gpg2 –keyserver hkp://keyserver.ubuntu.com:80 –recv-keys 409B6B1796C275462A1703113804BB82D39DC0E3 7D2BAF1CF37B13E2069D6956105BD0E739499BDB

–keyserver hkp://keyserver.ubuntu.com:80 这个地址是好用的 像一些官网服务一般来说都不好使

1
2
$ rvm list known # 获取可用版本
$ rvm install [version] # 安装指定版本的 ruby

gem 镜像更改

1
2
$ gem sources --add https://gems.ruby-china.com/ --remove https://rubygems.org/
$ gem sources -l

vpn 搭建遇到的问题

vpn client -> vpn server 不通, 一开始以为是 tcp 端口的问题, 后来排查是因为 UDP 端口的问题

vps manager 管理端走的是 tcp 协议, 但是 vpn 隧道连接时使用的是 udp 协议, 具体如下:

PPTP: 1723

L2TP: 500 / 4500

vpn 服务器安装之后应该开启虚拟 nat 和 dhcp 否则远程机器连接不到

Axure 使用笔记

找元件, 好的元件库事半功倍 > 定制母版 > 锁定母版 > 画界面(不要做效果, 只调样式) > 为每个元素添加事件

把多个元素设置成 > 动态面板(不要设置成组合, 不然又好多事件和效果不能触发), 也就是选中多个元素之后, 右键选择 create dynamic pannel, 而不是 group

动态面板可以隔离多余的干扰信息(isolate), 按钮在关闭左边(右上角)

移动效果选择经过, 不要选到达, 到达是绝对定位, 而经过是相对移动

所有的元件最好有名字, 搜索起来快, 交互是可以复制的

页面之间保持独立性, 不要用动态面板来做(比如新增和查看页面), 如果使用动态面板来做, 会存在变量污染, 好多变量和名称都要重新改一遍(因为查看是copy新增的副本)

Mac 短位密码设置

pwpolicy -clearaccountpolicies 清除密码策略

知识点

三姬分金: 博弈论

经济学: 亚当斯密 大卫李嘉图

nginx if 多表达式不支持的解决办法

set $flag = 0; if ( condition ) { $flag = 1; } if ( condition ) { $flag = 0 } if ( $flag = 1 ) {

}

maven shade 插件 解决项目中依赖高低版本组件的问题

https://maven.apache.org/plugins/maven-shade-plugin/examples/class-relocation.html

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
<groupId>com.gomyck</groupId>
<artifactId>shaded</artifactId>
<version>1.0.0-SNAPSHOT</version>
<properties>
    <elasticsearch.version>2.1.2</elasticsearch.version>
</properties>
<dependencies>
    <dependency>
        <groupId>org.elasticsearch</groupId>
        <artifactId>elasticsearch</artifactId>
        <version>${elasticsearch.version}</version>
    </dependency>
    <dependency>
        <groupId>com.google.guava</groupId>
        <artifactId>guava</artifactId>
        <version>18.0</version>
    </dependency>
</dependencies>
<build>
    <plugins>
        <plugin>
            <groupId>org.apache.maven.plugins</groupId>
            <artifactId>maven-shade-plugin</artifactId>
            <version>2.4.1</version>
            <configuration>
                <createDependencyReducedPom>false</createDependencyReducedPom>
            </configuration>
            <executions>
                <execution>
                    <phase>package</phase>
                    <goals>
                        <goal>shade</goal>
                    </goals>
                    <configuration>
                        <relocations>
                            <relocation>
                                <pattern>com.google.guava</pattern>
                                <shadedPattern>gomyck.elasticsearch.guava</shadedPattern>
                            </relocation>
                            <relocation>
                                <pattern>org.joda</pattern>
                                <shadedPattern>gomyck.elasticsearch.joda</shadedPattern>
                            </relocation>
                            <relocation>
                                <pattern>com.google.common</pattern>
                                <shadedPattern>gomyck.elasticsearch.common</shadedPattern>
                            </relocation>
                            <relocation>
                                <pattern>org.elasticsearch</pattern>
                                <shadedPattern>gomyck.elasticsearch</shadedPattern>
                            </relocation>
                        </relocations>
                        <transformers>
                            <transformer implementation="org.apache.maven.plugins.shade.resource.ManifestResourceTransformer" />
                            <mainClass>com.gomyck.core.ApplicationStart</mainClass>
                        </transformers>
                    </configuration>
                </execution>
            </executions>
        </plugin>
    </plugins>
</build>

关闭 sockjs, 防止非本机 IP 访问无限刷新

1
2
3
// 1. 找到/node_modules/sockjs-client/dist/sockjs.js
// 2. 找到代码的 1605行
self.xhr.send(payload);  //把这行注释掉

hashMap 死锁原因

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
void transfer(Entry[] newTable, boolean rehash){
    int newCapacity=newTable.length;
    for(Entry<K, V> e:table){
        while(null!=e){
            Entry<K, V> next=e.next;
            if(rehash){
                e.hash=null==e.key?0:hash(e.key);
            }
            int i=indexFor(e.hash,newCapacity);
            //下面这三行导致死锁
            e.next=newTable[i];  //当前元素的 next 是新数组 index 存储的元素
            newTable[i]=e;       //当前元素替换到 新数组 index 位置
            e=next;              //当前元素引用到原有的 next 继续循环
        }
    }
}
//上述代码可分析得出, 如果原有 bucket 的元素顺序为 A>B>C, 假设 rehash 后 bucket index 不变的话, 那么数组引用关系会变为 C>B>A
//如果在循环的过程中线程挂起, 此时新的 bucket 引用关系为 B>A, 另外的线程也触发 resize 的话, 那么 A 和 B 两个元素就会发生循环引用而导致死锁

敏捷开发的一些总结

1
2
3
4
5
6
7
8
9
10
11
12
1. 通过早期和持续交付有价值的软件,实现客户满意度。
2. 欢迎不断变化的需求,即使是在项目开发的后期。要善于利用需求变更,帮助客户获得竞争优势。
3. 不断交付可用的软件,周期通常是几周,越短越好。
4. 项目过程中,业务人员与开发人员必须在一起工作。
5. 项目必须围绕那些有内在动力的个人而建立,他们应该受到信任。
6. 面对面交谈是最好的沟通方式。
7. 可用性是衡量进度的主要指标。
8. 提倡可持续的开发,保持稳定的进展速度。
9. 不断关注技术是否优秀,设计是否良好。
10. 简单性至关重要,尽最大可能减少不必要的工作。
11. 最好的架构、要求和设计,来自团队内部自发的认识。
12. 团队要定期反思如何更有效,并相应地进行调整。

spring transaction 的实现

  1. TransactionAutoConfiguration: EnableTransactionManagementConfiguration

  2. EnableTransactionManagement: TransactionManagementConfigurationSelector

  3. ProxyTransactionManagementConfiguration : TransactionInterceptor

为什么 byte 在转成 int 类型时, 要 &0xFF

我们常用的摘要算法, 在计算签名之后, 需要把 byte 转成 int 在转成 hex, 而 byte 转 int 的时候, 计算机会对 byte 进行补位, 通过符号位进行补位

这样可以保证 byte 代表的数值不变, 但却带来一个问题: 原有的二进制存储不一样了(负数)

正数存储一致: 01111111 补码 -> 01111111 符号位填充 -> 00000000 00000000 00000000 01111111

存储不一致了: 11111111 补码 -> 10000001 符号位填充 -> 11111111 11111111 11111111 10000001

而摘要算法并不在意 10 进制字面值, 而是存储一致, 所以需要 &0xFF 00000000 00000000 00000000 11111111

这样可以保证除了低 8 位, 其他高位都舍弃

查看 linux 发行信息

1
2
3
$ cd /etc
$ find ./ -name '*release'
$ cat  .....

windows 查看 wifi 密码

1
2
3
4
5
netsh wlan show profiles

netsh wlan show profiles [wifi name] key=clear

找到安全设置表单下的: 关键内容, 就是密码

SpEL # $ 的区别

1
2
3
#{…} 用于执行SpEl表达式,并将内容赋值给属性
${…} 主要用于加载外部属性文件中的值
#{…} 和${…} 可以混合使用,但是必须#{}外面,${}在里面,#{ '${}' } ,注意单引号,注意不能反过来

JAVA 对象头组成

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
|-----------------------------------------------------------------------------------------------------------------|
|                                             Object Header(128bits)                                              |
|-----------------------------------------------------------------------------------------------------------------|
|                                   Mark Word(64bits)               |  Klass Word(64bits)    |      State         |
|-----------------------------------------------------------------------------------------------------------------|
| unused:25|identity_hashcode:31|unused:1|age:4|biase_lock:1|lock:2 | OOP to metadata object |      Nomal         |
|-----------------------------------------------------------------------------------------------------------------|
| thread:54|      epoch:2       |unused:1|age:4|biase_lock:1|lock:2 | OOP to metadata object |      Biased        |
|-----------------------------------------------------------------------------------------------------------------|
|                     ptr_to_lock_record:62                 |lock:2 | OOP to metadata object | Lightweight Locked |
|-----------------------------------------------------------------------------------------------------------------|
|                    ptr_to_heavyweight_monitor:62          |lock:2 | OOP to metadata object | Heavyweight Locked |
|-----------------------------------------------------------------------------------------------------------------|
|                                                           |lock:2 | OOP to metadata object |    Marked for GC   |
|-----------------------------------------------------------------------------------------------------------------|

sublime 一些常用的插件

1
2
3
4
5
6
7
8
1. HTML5
2. CSS3
3. MarkdownEditing
4. SublimeServer          让Sublime成为静态WEB服务器
5. Color Highlighter      展示颜色代码的真正颜色
6. AutoFileName           提示文件路径,快速输入文件名
7. DocBlockr
8. ConvertToUTF8

java 三种启动传参的方式

1
2
3
4
5
6
7
8
9
10
11
1.-DpropName=propValue 的形式携带
    eg:java -Dxxx=123 -DprocessType=234 -jar xxx.jar
   取值: System.getProperty("processType")

2.参数直接跟在命令后⾯
    eg:java -jar xxx.jar processType=1 processType2=2
   取值:参数就是jar包⾥主启动类中main⽅法的args参数,按顺序来

3.springboot的⽅式 --key=value
    eg:java -jar xxx.jar --xxx=test
   取值 spring的 @value("${xxx}")

mysql 显示所有进程

1
show full processlist ;

mac docker 容器访问宿主机的快速配置

从17.06开始,我们的建议是连接到特殊的Mac-Only DNS名称 docker.for.mac.localhost 这将决定主机使用的内部IP地址。

docker.for.win.localhost 也可以访问 windows 的宿主机

host.docker.internal 是通用的配置, 但是需要 docker 18.03 以上版本

把多次失败的登录 ip 加入到限制登录名单中

1
$ cat /var/log/secure | grep "Failed password for invalid user" | awk '{print $13}' | sort | uniq -c | sort -n | tail -10 |awk '{print "sshd:"$2":deny"}' >> /etc/hosts.allow

zsh tab 补全时, 出现重复字符

在 .zshrc 里面添加一条 export LC_CTYPE=en_US.UTF-8

或者在 /etc/locale.conf 添加一行 LC_CTYPE=en_US.UTF-8 修改完后运行locale.gen。

技术栈描述

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
1. Elasticsearch

分布式搜索和分析引擎。具有高可伸缩、高可靠和易管理等特点。基于 Apache Lucene 构建,能对大容量的数据进行接近实时的存储、搜索和分析操作。

2. Logstash

日志收集器。搜集各种数据源,并对数据进行过滤、分析、格式化等操作,然后存储到 Elasticsearch。

3. Kibana

数据分析和可视化平台。与 Elasticsearch 配合使用,对其中数据进行搜索、分析、图表展示。

4. Filebeat

一个轻量级开源日志文件数据搜集器,Filebeat 读取文件内容,发送到 Logstash 进行解析后进入 Elasticsearch,或直接发送到 Elasticsearch 进行集中式存储和分析。

5. Nginx

Nginx 是一个开源且高性能、可靠的 HTTP 中间件,代理服务。采用的是多进程(单线程) + 多路 IO 复用模型。使用了 I/O 多路复用技术的 Nginx,就成了 并发事件驱动 的服务器。

6. Kubernetes

Kubernetes 是一个开源的容器编排引擎,用来对容器化应用进行自动化部署、 扩缩和管理。该项目托管在 CNCF。

7. ansible
ansible 是又红帽开源的一款自动化部署工具, 给予 python, 实现了批量系统配置, 程序部署, 运行命令等功能



JAVA多态

JAVA 继承为单继承, 方法表从上至下也就代表了顶级父类 Object 的方法以及子类依次向下的罗列堆叠, 子类集成的父类方法, 与父类的方法表索引一致

在实际调用时, 只需要 O(1) 的时间复杂度就可以完成寻址

而接口可以 impl 多个, 这样方法表的位置无法保证, 所以在调用接口方法时, 是要搜索方法表的(invokeinterface), 所以一般来说, 接口方法调用比类方法调用要慢

JAVA 方法调用的优先级:

1
2
3
4
this.func(P)
super.func(P)
this.func((super)P)
super.func((super)P)

kafka在 k8s 中部署, 集群内外访问

1
2
3
4
5
6
# INSIDE 指的是集群内部互相通信的监听, 用于 broker 互相通信
# OUTSIDE 是外部访问的 IP, 用来解决外部客户端连接 kafka 时, 要连接的地址(不能用 inside, 因为是 service name, 外部解析不了)
$ export KAFKA_LISTENERS=INSIDE://:9092,OUTSIDE://:9094
$ export KAFKA_ADVERTISED_LISTENERS=INSIDE://<container>:9092,OUTSIDE://<host>:9094
$ export KAFKA_LISTENER_SECURITY_PROTOCOL_MAP=INSIDE:PLAINTEXT,OUTSIDE:PLAINTEXT
$ export KAFKA_INTER_BROKER_LISTENER_NAME=INSIDE

JAVA 打印内存详细信息

1
$ jcmd 1 VM.native_memory summary | detail

使用 jcmd pid 可以查看很多 jvm 运行时参数, 以及执行一些 jdk 命令, 如 gc, 具体使用 jcm pid help 来查看命令

linux pv lv 以及相关概念

LVM 是一种高级的磁盘分区管理方案,通过 LVM 管理可以将多个硬盘上的磁盘分区合并成一个大的分区组,从而提高磁盘空间利用率和可扩展性。在 LVM 中,物理卷(PV)是实际磁盘分区,逻辑卷(LV)是虚拟的磁盘分区,由一个或多个物理卷组成。VG(Volume Group)是一组物理卷的集合,也是逻辑卷的存储池。

PV 是物理卷的简称,指硬盘上的一个磁盘分区。PV 需要预先格式化并设置为 LVM 类型。VG 是卷组的简称,指一组 PV 的集合。VG 通过将 PV 进行逻辑划分,组成一组可供 LV 使用的物理卷。

LV 是逻辑卷的简称,指 VG 中可供使用的存储池。LV 可以使用 VG 中的任何 PV 空间,且大小可以随时扩充或缩小。可以将一个 LV 分配给一个文件系统、swap 分区、虚拟机磁盘等。

在 LVM 中,每个 PV、VG 和 LV 都有一个唯一的名称,称为 UUID(Universally Unique Identifier),通过 UUID 可以确定每个卷或分区的唯一性。

k8s service 和 headless service 的区别

service 天生带负载, 而且会分配 clusterIp, 也可以暴露给集群外

headless service 不带负载, 但是可以通过 pod 名称 + service name 来定位到 pod 服务, service 则不可以