[{"content":"#!/bin/sh set -e # 定义项目目录名 PROJECT=\u0026#34;dist\u0026#34; # 1. 设置 umask（解压前宽松，解压后恢复） umask 022 # 2. 获取当前月日（如 0819） suffix=$(date +%m%d) # 3. 如果旧的项目目录存在，则重命名（添加月日后缀） if [ -d \u0026#34;$PROJECT\u0026#34; ]; then # 备份目标目录名 backup_dir=\u0026#34;${PROJECT}${suffix}\u0026#34; # 如果备份目录已经存在，为避免覆盖，追加一个递增数字 if [ -d \u0026#34;$backup_dir\u0026#34; ]; then count=1 while [ -d \u0026#34;${PROJECT}${suffix}_${count}\u0026#34; ]; do count=$((count + 1)) done backup_dir=\u0026#34;${PROJECT}${suffix}_${count}\u0026#34; fi echo \u0026#34;Moving existing $PROJECT to $backup_dir\u0026#34; mv \u0026#34;$PROJECT\u0026#34; \u0026#34;$backup_dir\u0026#34; fi # 4. 解压新的 zip 到项目目录 unzip \u0026#34;${PROJECT}.zip\u0026#34; -d \u0026#34;$PROJECT\u0026#34; # 5. 恢复 umask umask 027 echo \u0026#34;Done. New extraction is in $PROJECT/\u0026#34; ","date":"2026-08-25T16:55:14+08:00","permalink":"/p/linux%E4%B8%8B%E5%89%8D%E7%AB%AF%E8%A7%A3%E5%8E%8B%E6%9B%B4%E6%96%B0%E8%84%9A%E6%9C%AC/","title":"Linux下前端解压更新脚本"},{"content":" # 查看第一行日志的字段分布 head -1 access.log | awk \u0026#39;{for(i=1;i\u0026lt;=NF;i++) print i\u0026#34;: \u0026#34;$i}\u0026#39; # 或者统计各字段类型 head -1000 access.log | awk \u0026#39;{print $10}\u0026#39; | sort -n | tail -5 # 查询响应体大于指定大小 awk \u0026#39;$10 \u0026gt; 1048576\u0026#39; access.log \u0026gt; large_requests.log # 查询特定路径的请求记录 awk \u0026#39;$7 ~ /^\\/api\\/path1\\/path2/ {print}\u0026#39; access.log \u0026gt; apas_requests.log #去重请求地址 awk \u0026#39;{print $7}\u0026#39; access.log | sort -u \u0026gt; unique_paths.txt # 如果需要知道每个路径的访问次数 awk \u0026#39;{print $7}\u0026#39; access.log | sort | uniq -c | sort -nr \u0026gt; paths_with_count.txt # 只保留出现次数大于等于2的记录 awk \u0026#39;{print $7}\u0026#39; access.log | sort | uniq -c | sort -nr | awk \u0026#39;$1 \u0026gt;= 4\u0026#39; \u0026gt; paths_with_count.txt # 过滤出带有字符串 awk \u0026#39;{print $7}\u0026#39; access.log | sort | uniq -c | sort -nr | awk \u0026#39;$1 \u0026gt; 1 \u0026amp;\u0026amp; $0 ~ /api/\u0026#39; \u0026gt; paths_with_count.txt # 过滤出不带有字符串 awk \u0026#39;{print $7}\u0026#39; access.log | sort | uniq -c | sort -nr | awk \u0026#39;$1 \u0026gt; 1 \u0026amp;\u0026amp; $0 !~ /api/\u0026#39; \u0026gt; paths_with_count.txt ","date":"2026-08-25T16:39:16+08:00","permalink":"/p/nginx%E6%97%A5%E5%BF%97%E7%AD%9B%E9%80%89/","title":"Nginx日志筛选"},{"content":"Canal 同步中断时的排查笔记。\n一、查询 Canal 日志 logs/example/example.log —— 连接错误的日志\nlogs/example/meta.log —— 数据同步的日志\n二、查询 MySQL 的 binlog 日志 查看 binlog 信息 -- 获取最新一个日志文件 show binary logs; 查看指定日志的详情 -- 获取 log_name、pos 起始位置信息 show binlog events in \u0026#39;mysql-bin-000**\u0026#39;; 三、修改 Canal 配置 # 修改 journalName、position vi /canal/conf/example/meta.dat 四、重启 / 启动 Canal /canal/bin/restart.sh /canal/bin/startup.sh ","date":"2026-08-25T13:39:00+08:00","permalink":"/p/canal-config-issue/","title":"Canal 配置问题"},{"content":"一、使用CURL分析HTTP请求耗时 1. 基本命令结构 curl -o /dev/null -s -w \u0026#39;dns_resolution: %{time_namelookup} connect_time: %{time_connect} appconnect_time: %{time_appconnect} pretransfer_time: %{time_pretransfer} starttransfer_time: %{time_starttransfer} total_time: %{time_total}\\n\u0026#39; \u0026#39;http://baidu.com\u0026#39; curl：调用CURL工具。 -o /dev/null：将服务器返回的数据输出到/dev/null，不保存响应内容。 -s：启用静默模式（silent），不显示进度条或错误信息，使输出更加简洁。 -w：指定自定义的输出格式，后面跟随一串格式化字符串。字符串中包含多个变量，用于显示请求各个阶段的耗时。 \u0026lsquo;http://baidu.com\u0026rsquo;：目标URL。 2. 时间变量解析(单位均为秒s) 变量名 含义 解释 影响 %{time_namelookup} DNS解析时间 从请求开始到完成域名解析所需的时间 影响请求启动速度，尤其在DNS缓存未命中时显著 %{time_connect} TCP连接时间 从DNS解析完成到完成TCP连接建立所需的时间 影响整体请求响应速度，涉及三次握手过程 %{time_appconnect} SSL握手时间 从TCP连接建立到完成SSL握手（如果使用HTTPS）所需的时间。 保障通信安全的同时增加请求耗时 %{time_pretransfer} 从请求开始到文件传输即将开始的时间 从请求开始到准备好传输数据的时间，包括所有初始化过程。 涵盖数据传输前的准备工作，对整体性能有一定影响 %{time_starttransfer} 从请求开始到接收到第一个字节的时间 从请求开始到服务器开始响应并接收到第一个字节所需的时间，通常反映了服务器的响应速度。 反映服务器处理请求的效率，是评估服务器响应性能的关键指标 %{time_total} 总请求时间 从请求开始到请求完成的总耗时，包括所有阶段。 综合衡量请求性能的指标，直接影响用户体验 3. 命令执行示例 dns_resolution: 0.029 connect_time: 0.058 appconnect_time: 0.528 pretransfer_time: 0.528 starttransfer_time: 0.839 total_time: 0.866 ","date":"2026-08-25T09:35:17+08:00","permalink":"/p/curl%E5%9C%A8http%E8%AF%B7%E6%B1%82%E8%80%97%E6%97%B6%E5%88%86%E6%9E%90%E4%B8%AD%E7%9A%84%E5%BA%94%E7%94%A8/","title":"CURL在HTTP请求耗时分析中的应用"},{"content":"1.将本地jar安装到本地maven厂库中 call mvn install:install-file -DgroupId=net.sf.json-lib -DartifactId=json-lib -Dversion=2.4 -Dpackaging=jar -Dfile=json-lib.jar -DgroupId 设置groupId名称 -DartifactId设置包的artifactId名称 -Dversion 版本号 -Dpackaging 类型:pom/jar/war/maven-plugin -Dfile 包的文件路径 2. maven3.8.1版本不允许http协议仓库下载 \u0026lt;mirror\u0026gt; \u0026lt;id\u0026gt;maven-default-http-blocker\u0026lt;/id\u0026gt; \u0026lt;mirrorOf\u0026gt;blocker\u0026lt;/mirrorOf\u0026gt; \u0026lt;name\u0026gt;用于突破maven-3.8.1版本以后默认禁用http仓库的限制\u0026lt;/name\u0026gt; \u0026lt;url\u0026gt;http://0.0.0.0/\u0026lt;/url\u0026gt; \u0026lt;/mirror\u0026gt; 3. 清理pom.xml中的包，并重新下载 mvn dependency:purge-local-repository # -DactTransitively=false 仅对项目的直接依赖项进行操作 4.多模块项目的子模块单独打包 mvn clean install -pl module1 -am -DskipTests ## -pl module1\t--projects 的简写，指定只构建 module1 模块 ## -am\t--also-make 的简写，表示同时构建 module1 所依赖的其他模块 ## -DskipTests\t它的作用是跳过单元测试的执行（但依然编译测试代码） ","date":"2026-08-25T09:35:08+08:00","permalink":"/p/maven%E6%93%8D%E4%BD%9C/","title":"Maven操作"},{"content":"1. 同步主机时区 #第一种方式(推荐)： environment: TZ: Asia/Shanghai #第二种方式： environment: SET_CONTAINER_TIMEZONE=true CONTAINER_TIMEZONE=Asia/Shanghai #第三种方式： volumes: - /etc/timezone:/etc/timezone - /etc/localtime:/etc/localtime 2. 指定compose文件运行 docker-compose -f docmer-compose.yml up -d 3. 清理docker容器日志 docker ps -aq | xargs docker inspect --format=\u0026#39;{{.LogPath}}\u0026#39; | xargs truncate -s 0 ","date":"2026-08-25T09:35:03+08:00","permalink":"/p/docker%E5%B8%B8%E7%94%A8%E6%93%8D%E4%BD%9C/","title":"docker常用操作"},{"content":"场景： 保存常用的服务器命令启动jar包脚本 #!/bin/bash port=8080 name=demo.jar logname=temp.log ID=$( netstat -lnp|grep ${port}|awk \u0026#39;{printf $7}\u0026#39;|cut -d/ -f1) if [ -z \u0026#34;${ID}\u0026#34; ] then echo -e \u0026#34;\\033[31m 未启动............. \\033[0m\u0026#34; else echo -e \u0026#34;\\033[31m 正在停止,进程id: ${ID} \\033[0m\u0026#34; kill -9 ${ID} echo -e \u0026#34;\\033[31m 进程已停止................. \\033[0m\u0026#34; fi nohup java -jar ${name} --server.port=${port} \u0026gt;${logname} 2\u0026gt;\u0026amp;1 \u0026amp; ss -tanl echo -e \u0026#34;\\033[5;31m 服务正在启动............ \\033[0m\u0026#34; ","date":"2026-08-25T09:34:58+08:00","permalink":"/p/linux-jar%E5%90%AF%E5%8A%A8%E8%84%9A%E6%9C%AC/","title":"Linux jar启动脚本"},{"content":"解决办法：手动下载安装\n1、下载对应.whl文件，cpxx指的是python版本\n2、安装.whl文件\npip install opencv_python-3.1.0.0-cp27-cp27mu-manylinux1_x86_64.whl ","date":"2026-08-25T09:34:52+08:00","permalink":"/p/python2.7%E5%AE%89%E8%A3%85opencv-python%E5%87%BA%E9%94%99/","title":"python2.7安装opencv-python出错"},{"content":"## (测试生效) 删除环境变量中的\u0026quot;%USERPROFILE%\\AppData\\Local\\Microsoft\\WindowsApps\u0026quot; ## 修改环境变量的顺序(未测试)。 ","date":"2026-08-25T09:34:47+08:00","permalink":"/p/cmd%E8%BE%93%E5%85%A5python%E6%97%A0%E5%93%8D%E5%BA%94%E5%BC%B9%E5%87%BA%E4%BA%86%E5%BA%94%E7%94%A8%E5%95%86%E5%BA%97/","title":"cmd输入python无响应，弹出了应用商店"},{"content":" 1、模版提取\n请阅读以下销售邮件。删除任何可用于识别个人身份的信息 (PII)，并用相应的占位符替换它。例如，用\u0026#34;[姓名]\u0026#34;替换\u0026#34;John Doe\u0026#34;。 你好 John， 我写信给你是因为我注意到你最近买了一辆新车。我是一家当地经销商 (Cheap Dealz) 的销售员，我想让你知道我们有一辆新车的超值优惠。如果你有兴趣，请告诉我。 谢谢， Jimmy Smith 电话：410-805-2345 电子邮件：jimmysmith@cheapdealz.com 2、SVG总结卡片\n# SVG总结卡片生成 作为专业的知识卡片设计师，根据提供的内容创建现代扁平化科技风格SVG信息卡片，确保内容层次清晰，视觉风格统一。 ## 卡片结构与布局 - 主卡片: 白色背景，圆角20px，两侧和底部具有轻微阴影以形成悬浮效果(不透明度0.1) - 尺寸: 宽度1000px(主卡片宽度950px)，高度应根据内容自动调整，不使用固定高度，顶部与SVG边界留白14px - 背景: 使用10px网格的点阵图案提升质感 ## 内容板块 1. **标题区域:** - 顶部全宽标题栏，下方无圆角设计，渐变背景(#0d8999→#26b7bc) - 主标题：根据输入内容提取或直接使用，居中显示 - 副标题：对主标题的补充说明 2. **引用区域:** - 标题下方，浅青色背景(#E9F6F5)，左侧竖线(#26b7bc) - 选择相关名言或创建总结性陈述 - 标明来源或作者 3. **插图区域:** - 首先对[主题]或相关问题进行解释，提供概念概述和背景信息 - 使用适当的可视化方法(流程图、关系图、时间线等)展示复杂概念 - 根据插图大小调整卡片大小，避免超出卡片边界 4. **正文内容:** - 主要内容卡片：按照逻辑顺序展开[主题]的各个方面，每个卡片聚焦一个具体方面 - 对比/表格卡片：如有必要，使用表格或并列视图展示对比内容 - 案例/应用卡片：展示[主题]的实际应用案例或示例 5. **问答区域:** - 创建底部常见问题部分，整体使用卡片包裹 - 设计几个与主题相关的问题 - 每个问答设计为独立的白色矩形卡片(宽860px，高度根据内容调整) - 卡片使用主题色细边框(#26b7bc，宽1px)，圆角10px ## 视觉设计规范 - 字体: 无字体要求，正文部分14px大小 - 小标题设计: 每个小标题字体使用浅蓝色，下方应有浅蓝色分割线，宽度与标题文本等宽 - 文本格式: 所有文本不超出右侧边界，较长文本拆分为多行，正文部分有适当缩进，文字间距应宽松 - 视觉元素: 渐变填充、几何装饰、流程线使用虚线或渐变 - 卡片效果: 每个卡片的两侧和底部具有轻微阴影以形成悬浮效果(不透明度0.1) ## 输出要求 - 返回完整SVG代码，及简要设计思路说明 - 确保SVG内所有元素定位准确，无内容溢出 3、欢迎来到成人世界\n你是一个见多识广的智者，请创建一个极度直白、毫不留情、简洁有力，能引起人共鸣的’成人世界真相’格言，揭露社会中最残酷的现实和人性中最阴暗的角落。内容应该足够尖锐到让人感到不适，但又不得不承认其中的真实性。然后将这句话制作成一个SVG卡片，黑白简约风格，标题为“欢迎来到成人世界”，图形元素需要与文字相互呼应。 4、知识问答\n## Role 知识解析专家 ## Skills - 精通知识传授技巧：能将复杂概念分解为易于理解的组成部分，掌握循序渐进的教学方法，并能根据不同知识领域的特点提供清晰解释。 - 丰富的跨学科知识：具备广泛的知识背景，能够将专业知识与日常生活、实际应用等方面联系起来，帮助用户建立知识连接。 - 清晰的表达能力：能够用通俗易懂的语言解释复杂概念，善用比喻、类比和例子使抽象内容具体化，激发学习兴趣。 - 优秀的教学设计能力：善于组织知识结构，了解用户的认知需求和可能的困惑点，并能及时调整解释方式，帮助用户构建完整知识体系。 - research in english, respond in chinese. - 涉及到人名、地名，使用中文（原文）对照显示。 - 请不要与我寒暄，也不需要任何形式的引导词，请直接进行知识解析，也不需要说你用了MermaidJS图表。 ## Mermaid图表格式规范（必须严格遵循） - **必须规则1**：所有MermaidJS图表内的节点文字描述都必须加上双引号，例如：A[\u0026#34;二氧化碳 (CO2)\u0026#34;] --\u0026gt; B[\u0026#34;水 (H2O)\u0026#34;] - **必须规则2**：禁止使用任何style相关代码（如style、fill、stroke等）来设置背景颜色或边框样式 - **正确示例**：`A[\u0026#34;设备A\u0026#34;] --\u0026gt; B[\u0026#34;交换机\u0026#34;]` 或 `A[[\u0026#34;IP 地址 \u0026#34;逻辑地址\u0026#34;\u0026#34;] --\u0026gt; B[\u0026#34;局域网寻址 \u0026#34;同一网络段\u0026#34;\u0026#34;]` - **错误示例**：`A[设备A] --\u0026gt; B[交换机]` 或 `style A fill:#f9f,stroke:#333,stroke-width:2px` ## Action 1. 知识概览： - 用50个字左右，总结所询问的知识点，用直白的语言帮助用户快速理解内容。 2. 核心内容： - 列出该知识领域的关键概念、原理或方法，帮助用户建立完整的知识框架。采用有序列表的形式，尽可能详尽。 - 详细解释：使用无序列表的结构（注意不要嵌套结构），对每一个概念详细向用户解释，确保零基础用户也能理解这些内容。 - 实例说明：使用具体的例子来解释抽象概念，将理论与实践联系起来。 - 应用指导：为用户提供实际应用这些知识的具体建议或步骤。 - 尽量给每一段核心内容里面插入 mermaidJS 图表，采用多种合适的mermaidJS 表现类型进行可视化表达，例如：对于 Git 相关问题，可以使用 `gitGraph`。 - Mermaid图表要求： * 每个图表必须严格遵循上述Mermaid格式规范 * 生成图表后，检查确保所有节点文字都用双引号包裹 * **绝对禁止** 使用任何style相关代码 3. 问答：提出几个用户可能关心的问题，并给出详细的回答，解决学习过程中可能遇到的困惑。 4. 最终检查： - 再次检查所有Mermaid图表，确保遵循格式规范 - 确认所有节点文字都已用双引号包裹 - **绝对禁止**使用任何style相关代码 \u0026lt;Example\u0026gt; ## {翻译后的知识点标题} - 例如，关于“光合作用”的知识，光合作用是植物通过光能将二氧化碳和水转化为葡萄糖和氧气的过程。这一过程是地球上大多数生命的能量来源。 ## 核心内容： ### 1. 光合作用的基本过程 - 光合作用分为两个主要阶段：光反应和暗反应。 - 光反应发生在叶绿体的类囊体膜上，利用光能分解水分子，释放氧气并生成ATP和NADPH。 - 暗反应（卡尔文循环）在叶绿体的基质中进行，利用ATP和NADPH将二氧化碳转化为葡萄糖。 ```mermaid graph TD A[\u0026#34;光合作用\u0026#34;] --\u0026gt; B[\u0026#34;光反应\u0026#34;] A --\u0026gt; C[\u0026#34;暗反应\u0026#34;] B --\u0026gt; D[\u0026#34;水分解\u0026#34;] B --\u0026gt; E[\u0026#34;ATP和NADPH生成\u0026#34;] C --\u0026gt; F[\u0026#34;二氧化碳转化\u0026#34;] C --\u0026gt; G[\u0026#34;葡萄糖生成\u0026#34;] \\``` ### 2. 光合作用的影响因素 - **光强度**：光强度越高，光合作用速率越快。 - **二氧化碳浓度**：增加二氧化碳浓度可以提高光合作用速率。 - **温度**：适宜的温度范围内，光合作用速率会随温度升高而增加，但过高温度会抑制光合作用。 ```mermaid pie title 光合作用影响因素 \u0026#34;光强度\u0026#34; : 40 \u0026#34;二氧化碳浓度\u0026#34; : 35 \u0026#34;温度\u0026#34; : 25 \\``` ### 3. 光合作用的生态意义 - **生产氧气**：光合作用是地球上氧气的主要来源。 - **碳固定**：帮助减少大气中的二氧化碳，减缓全球变暖。 - **食物链基础**：为生态系统提供能量基础。 ## 问答 ### Q: 光合作用的主要产物是什么？ A: 光合作用的主要产物是葡萄糖和氧气。葡萄糖为植物提供能量，氧气则是大气中重要的组成部分。 ### Q: 为什么光合作用对生态系统重要？ A: 光合作用是生态系统中能量的主要来源，支持了植物的生长，并为动物提供食物，是维持生态平衡的关键。 ### Q: 如何提高光合作用的效率？ A: 可以通过增加光照、提高二氧化碳浓度以及优化温度条件来提高光合作用的效率。 \u0026lt;/Example\u0026gt; ","date":"2026-08-25T09:34:34+08:00","permalink":"/p/prompt%E4%B9%8B%E6%A8%A1%E7%89%88%E6%8F%90%E5%8F%96/","title":"prompt之模版提取"},{"content":"1、下载Minio的二进制包 [minio二进制](https://dl.min.io/server/minio/release/linux-amd64/minio) 2、 赋予执行权限 chmod +x minio 3、 创建存储数据的目录 mkdir minio-data/ 5、 启动 minio ./minio server minio-data/ 6、 指定启动端口号以及控制台端口号后台挂起： nohup ./minio server minio-data/ --address :9000 --console-address :9001 \u0026gt;minio.log 2\u0026gt;\u0026amp;1 \u0026amp; ","date":"2026-08-25T09:34:21+08:00","permalink":"/p/linux%E5%AE%89%E8%A3%85minio%E6%9C%8D%E5%8A%A1%E5%99%A8%E5%91%BD%E4%BB%A4/","title":"Linux安装minio服务器命令"},{"content":"说明：【数字 → 字符串】、【字符串 → 数字】互为逆运算，数字不同，转换的字符串也不同，可用于短连接的id转换\nimport java.util.HashMap; /** * * 将数字转换为字母组合，再转换为数字，可以得到相同的结果 */ public class PECode { /** * 打乱改字符数组的组合顺序，可以得到不同的转换结果 */ public static final char[] array = {\u0026#39;q\u0026#39;, \u0026#39;w\u0026#39;, \u0026#39;e\u0026#39;, \u0026#39;r\u0026#39;, \u0026#39;t\u0026#39;, \u0026#39;y\u0026#39;, \u0026#39;u\u0026#39;, \u0026#39;i\u0026#39;, \u0026#39;o\u0026#39;, \u0026#39;p\u0026#39;, \u0026#39;a\u0026#39;, \u0026#39;s\u0026#39;, \u0026#39;d\u0026#39;, \u0026#39;f\u0026#39;, \u0026#39;g\u0026#39;, \u0026#39;h\u0026#39;, \u0026#39;j\u0026#39;, \u0026#39;k\u0026#39;, \u0026#39;l\u0026#39;, \u0026#39;z\u0026#39;, \u0026#39;x\u0026#39;, \u0026#39;c\u0026#39;, \u0026#39;v\u0026#39;, \u0026#39;b\u0026#39;, \u0026#39;n\u0026#39;, \u0026#39;m\u0026#39;, \u0026#39;8\u0026#39;, \u0026#39;5\u0026#39;, \u0026#39;2\u0026#39;, \u0026#39;7\u0026#39;, \u0026#39;3\u0026#39;, \u0026#39;6\u0026#39;, \u0026#39;4\u0026#39;, \u0026#39;0\u0026#39;, \u0026#39;9\u0026#39;, \u0026#39;1\u0026#39;, \u0026#39;Q\u0026#39;, \u0026#39;W\u0026#39;, \u0026#39;E\u0026#39;, \u0026#39;R\u0026#39;, \u0026#39;T\u0026#39;, \u0026#39;Y\u0026#39;, \u0026#39;U\u0026#39;, \u0026#39;I\u0026#39;, \u0026#39;O\u0026#39;, \u0026#39;P\u0026#39;, \u0026#39;A\u0026#39;, \u0026#39;S\u0026#39;, \u0026#39;D\u0026#39;, \u0026#39;F\u0026#39;, \u0026#39;G\u0026#39;, \u0026#39;H\u0026#39;, \u0026#39;J\u0026#39;, \u0026#39;K\u0026#39;, \u0026#39;L\u0026#39;, \u0026#39;Z\u0026#39;, \u0026#39;X\u0026#39;, \u0026#39;C\u0026#39;, \u0026#39;V\u0026#39;, \u0026#39;B\u0026#39;, \u0026#39;N\u0026#39;, \u0026#39;M\u0026#39;}; private static final HashMap\u0026lt;Character, Integer\u0026gt; indexMap = createIndexMap(); public static String encode(Long number) { if (number \u0026lt;= 0) throw new IllegalArgumentException(\u0026#34;Number must be positive.\u0026#34;); StringBuilder result = new StringBuilder(0); while (number \u0026gt; 0) { int index = (int) (number % array.length); result.insert(0, array[index]); number /= array.length; } return result.toString(); } public static Long decode(String input) { if (input == null || input.isEmpty()) throw new IllegalArgumentException(\u0026#34;Input string cannot be null or empty.\u0026#34;); long result = 0L; long multiple = 1; for (int i = input.length() - 1; i \u0026gt;= 0; i--) { char c = input.charAt(i); int index = indexMap.get(c); result += index * multiple; multiple *= array.length; } return result; } private static HashMap\u0026lt;Character, Integer\u0026gt; createIndexMap() { HashMap\u0026lt;Character, Integer\u0026gt; map = new HashMap\u0026lt;\u0026gt;(); for (int i = 0; i \u0026lt; array.length; i++) { map.put(array[i], i); } return map; } } ","date":"2026-08-25T09:34:15+08:00","permalink":"/p/%E5%AD%97%E7%AC%A6%E4%B8%B2%E6%95%B0%E5%AD%97%E8%BD%AC%E6%8D%A2%E5%B7%A5%E5%85%B7%E7%B1%BB/","title":"字符串数字转换工具类"},{"content":"1.Vite插件(vitePlugins.push(cspPlugin(isBuild));) csp.ts\nimport type { Plugin } from \u0026#39;vite\u0026#39;; export function cspPlugin(mode: boolean): Plugin[] { // mode 执行方式：true为打包 ，false为本地运行 const nonce = mode ? \u0026#39;__SERVER-GENERATED-NONCE__\u0026#39; : \u0026#39;nonce\u0026#39;; // const nonce = mode ? \u0026#39;UzIeWf1T3ifABGK\u0026#39; : \u0026#39;nonce\u0026#39;; const regexScript = /\u0026lt;script(.*?)/gi; const replacementScript = `\u0026lt;script nonce=\u0026#34;${nonce}\u0026#34;$1`; const regexStyle = /\u0026lt;style(.*?)/gi; const replacementStyle = `\u0026lt;style nonce=\u0026#34;${nonce}\u0026#34;$1`; const regexLink = /\u0026lt;link(.*?)/gi; const replacementLink = `\u0026lt;link nonce=\u0026#34;${nonce}\u0026#34;$1`; const fs = require(\u0026#39;fs\u0026#39;); if (fs.existsSync(\u0026#39;log.txt\u0026#39;)) fs.rmSync(\u0026#39;log.txt\u0026#39;); if (fs.existsSync(\u0026#39;log1.txt\u0026#39;)) fs.rmSync(\u0026#39;log1.txt\u0026#39;); if (fs.existsSync(\u0026#39;log2.txt\u0026#39;)) fs.rmSync(\u0026#39;log2.txt\u0026#39;); // something const viteClientRegex = /node_modules\\/vite\\/dist\\/client\\/client\\.mjs$/gi; // antd-vue dynamicCss version 4.1.1 const antdvCsp = /node_modules\\/ant-design-vue\\/es\\/vc-util\\/Dom\\/dynamicCss\\.js$/gi; // antd icons-vue version 3.3.11 const iconRegex = /node_modules\\/@ant-design\\/icons-vue\\/es\\/utils\\.js$/gi; // vite-plugin-theme version 0.8.6 const themeRegex = /node_modules\\/@rys-fe\\/vite-plugin-theme\\/es\\/client\\.js$/gi; // vite-plugin-svg-icons version 4.5.2 const svgRegex = /svg-icons-register/gi; const transformStr: Plugin = { name: \u0026#39;transform-file\u0026#39;, transform(src, id) { // fs.appendFileSync(\u0026#39;log.txt\u0026#39;, \u0026#39;----------------\u0026#39; + id + \u0026#39;\\r\\n\u0026#39; + src + \u0026#39;\\r\\n\u0026#39; + \u0026#39;----------\u0026#39; + \u0026#39;\\r\\n\u0026#39;, function (err) { // if (err) { // return console.log(err); // } // console.log(\u0026#39;The file was saved!\u0026#39;); // }); if (viteClientRegex.test(id)) { return { code: src.replace( \u0026#34;style.setAttribute(\u0026#39;data-vite-dev-id\u0026#39;, id);\u0026#34;, `style.setAttribute(\u0026#39;data-vite-dev-id\u0026#39;, id); style.setAttribute(\u0026#39;nonce\u0026#39;, \u0026#39;${nonce.toString()}\u0026#39;);` ), }; } if (antdvCsp.test(id)) { return { code: src.replace(\u0026#39; const {\\n csp,\u0026#39;, `option.csp = {nonce:\u0026#34;__SERVER-GENERATED-NONCE__\u0026#34;}; const {\\n csp,`), }; } if (iconRegex.test(id)) { return { code: src.replace(\u0026#39;csp.value\u0026#39;, `csp \u0026amp;\u0026amp; csp.value ? csp.value : {nonce:\u0026#34;__SERVER-GENERATED-NONCE__\u0026#34;}`), }; } if (themeRegex.test(id)) { return { code: src .replace(\u0026#34;style.setAttribute(\u0026#39;id\u0026#39;, id);\u0026#34;, `style.setAttribute(\u0026#39;id\u0026#39;, id);style.setAttribute(\u0026#34;nonce\u0026#34;, \u0026#34;__SERVER-GENERATED-NONCE__\u0026#34;);`) .replace(\u0026#39;styleDom.innerHTML = cssText;\u0026#39;, \u0026#34;styleDom.innerHTML = cssText;styleDom.setAttribute(\u0026#39;nonce\u0026#39;, \u0026#39;__SERVER-GENERATED-NONCE__\u0026#39;);\u0026#34;), }; } if (svgRegex.test(id)) { return { code: src .replace( \u0026#34;svgDom.setAttribute(\u0026#39;xmlns:link\u0026#39;,\u0026#39;http://www.w3.org/1999/xlink\u0026#39;);\u0026#34;, \u0026#34;svgDom.setAttribute(\u0026#39;xmlns:link\u0026#39;,\u0026#39;http://www.w3.org/1999/xlink\u0026#39;);svgDom.setAttribute(\u0026#39;nonce\u0026#39;,\u0026#39;__SERVER-GENERATED-NONCE__\u0026#39;);\u0026#34; ) .replaceAll(/\u0026lt;symbol([\\s\\S]*?)\u0026gt;\u0026lt;\\/symbol\u0026gt;/g, (args) =\u0026gt; { return ( args .replaceAll(/\u0026lt;style\u0026gt;/g, \u0026#39;\u0026lt;style nonce=\\\\\u0026#34;__SERVER-GENERATED-NONCE__\\\\\u0026#34;\u0026gt;\u0026#39;) .replaceAll(/style=(\\\\)+\u0026#34;([^\u0026#34;]*fill):([^;\u0026gt;]*)/g, \u0026#39;$2=\\\\\u0026#34;$3\\\\\u0026#34;\u0026#39;) // .replaceAll(/style=\\\\\u0026#34;[^\u0026#34;]*fill:(#[0-9a-fA-F]+)[^\u0026#34;]*\u0026#34;/g, \u0026#39;fill=\\\\\u0026#34;$1\\\\\u0026#34;\u0026#39;) .replaceAll(/style=(\\\\)+\u0026#34;([^\u0026#34;]*opacity):([^;\u0026gt;]*)/g, \u0026#39;$2=\\\\\u0026#34;$3\\\\\u0026#34;\u0026#39;) ); }), }; } }, }; const createTag: Plugin = { name: \u0026#39;html-inject-nonce-into-script-tag\u0026#39;, enforce: \u0026#39;post\u0026#39;, transformIndexHtml(html) { return html.replace(regexScript, replacementScript).replace(regexStyle, replacementStyle).replace(regexLink, replacementLink); }, }; return [transformStr, createTag]; } 2.Nginx配置（include/csp.conf） csp.conf\nuserid on; set $cspNonce \u0026#39;UzIeWf1T3ifABGK\u0026#39;; if ($http_cookie ~ \u0026#34;((?\u0026lt;=^.{4}).{4})\u0026#34; ){ set $cspNonce $1; } if ($http_cookie ~ \u0026#34;((?\u0026lt;=^.{12}).{4})\u0026#34; ){ set $cspNonce $cspNonce$1; } if ($http_cookie ~ \u0026#34;((?\u0026lt;=^.{17}).{4})\u0026#34; ){ set $cspNonce $cspNonce$1; } if ($http_cookie ~ \u0026#34;((?\u0026lt;=^.{10}).{4})\u0026#34; ){ set $cspNonce $cspNonce$1; } if ($cspNonce ~ \u0026#34;([^%\u0026amp;\u0026#39;,;=?$\\x22]+)\u0026#34; ){ set $cspNonce $1; } sub_filter __SERVER-GENERATED-NONCE__ $cspNonce; sub_filter_types application/javascript; sub_filter_once off; add_header Content-Security-Policy \u0026#34;default-src \u0026#39;self\u0026#39;;script-src \u0026#39;strict-dynamic\u0026#39; \u0026#39;unsafe-eval\u0026#39; \u0026#39;nonce-$cspNonce\u0026#39;;style-src \u0026#39;self\u0026#39; \u0026#39;nonce-$cspNonce\u0026#39;;img-src \u0026#39;self\u0026#39; data: ; object-src \u0026#39;self\u0026#39;;font-src \u0026#39;self\u0026#39; data:; frame-ancestors \u0026#39;self\u0026#39;;connect-src \u0026#39;self\u0026#39;\u0026#34;; add_header X-Content-Type-Options \u0026#34;nosniff\u0026#34;; add_header X-XSS-Protection \u0026#34;1; mode=block\u0026#34;; #proxy_set_header Accept-Encoding \u0026#39;\u0026#39;; 其它可行方式(未测试) 监听htmlElment的创建，并设置nonce\n\u0026lt;script nonce=\u0026#34;UzIeWf1T3ifABGK\u0026#34;\u0026gt; var container = document.querySelector(\u0026#34;head\u0026#34;) var config = {childList: true} // 当观察到变动时执行的回调函数 const callback = function (mutationsList, observer) { // Use traditional \u0026#39;for loops\u0026#39; for IE 11 for (let mutation of mutationsList) { if (mutation.type === \u0026#34;childList\u0026#34;) { if (mutation.addedNodes \u0026amp;\u0026amp; mutation.addedNodes[0]) { mutation.addedNodes[0].setAttribute(\u0026#34;nonce\u0026#34;, \u0026#34;UzIeWf1T3ifABGK\u0026#34;); } // console.log(\u0026#34;A child node has been added or removed.\u0026#34;); } else if (mutation.type === \u0026#34;attributes\u0026#34;) { console.log(\u0026#34;The \u0026#34; + mutation.attributeName + \u0026#34; attribute was modified.\u0026#34;); } } }; // 创建一个观察器实例并传入回调函数 const observer = new MutationObserver(callback); // 以上述配置开始观察目标节点 observer.observe(container, config); \u0026lt;/script\u0026gt; ","date":"2026-08-25T09:34:09+08:00","permalink":"/p/jeecg%E5%89%8D%E7%AB%AF3.0%E5%A4%84%E7%90%86csp%E5%86%85%E5%AE%B9%E5%AE%89%E5%85%A8%E7%AD%96%E7%95%A5/","title":"Jeecg前端3.0处理CSP内容安全策略"},{"content":" Windows git乱码处理 命令行 git config --global core.quotepath false # 显示status编码 git config --global gui.encoding utf-8 # 图形界面编码 git config --global i18n.commit.encoding utf-8 # 提交信息编码 git config --global i18n.logoutputencoding utf-8 # 输出log编码 环境变量 set LESSCHARSET=UTF-8 git 自动转换文件 换行符 # 值 远程 拉取 提交 # true x -\u0026gt; LF -\u0026gt; CRLF # input x -\u0026gt; LF -\u0026gt; LF # false x -\u0026gt; x -\u0026gt; x git config --global core.autocrlf false ","date":"2026-08-25T09:34:05+08:00","permalink":"/p/git%E4%B9%B1%E7%A0%81%E5%A4%84%E7%90%86/","title":"git乱码处理"},{"content":" src/api/jimmerApi.ts import { Api } from \u0026#39;../_generated\u0026#39;; import { defHttp } from \u0026#39;/@/utils/http/axios\u0026#39;; const BASE_URL = import.meta.env.VITE_API_JIMMER_BASE_URL; export const api = new Api(async ({ uri, method, body }) =\u0026gt; { return defHttp.request({ url: `${BASE_URL}${uri}`, method, params: body, }); }); export const api1 = new Api(async ({ uri, method, body }) =\u0026gt; { const tenant = (window as any).__tenant as string | undefined; const response = await fetch(`${BASE_URL}${uri}`, { method, body: body !== undefined ? JSON.stringify(body) : undefined, headers: { \u0026#39;content-type\u0026#39;: \u0026#39;application/json;charset=UTF-8\u0026#39;, ...(tenant !== undefined \u0026amp;\u0026amp; tenant !== \u0026#39;\u0026#39; ? { tenant } : {}), }, }); if (response.status !== 200) { throw await response.json(); } const text = await response.text(); if (text.length === 0) { return undefined; } return JSON.parse(text); }); views/demo/system/jimmer/index.vue \u0026lt;template\u0026gt; \u0026lt;div\u0026gt; \u0026lt;input v-model=\u0026#34;options.id\u0026#34; placeholder=\u0026#34;请输入文本\u0026#34; /\u0026gt; \u0026lt;button @click=\u0026#34;query\u0026#34;\u0026gt;成功按钮\u0026lt;/button\u0026gt; {{ data.id }} \u0026lt;/div\u0026gt; \u0026lt;/template\u0026gt; \u0026lt;script lang=\u0026#34;ts\u0026#34; setup name=\u0026#34;list\u0026#34;\u0026gt; import { api } from \u0026#39;/@/api/JimmerApi\u0026#39;; import { RequestOf, ResponseOf } from \u0026#39;/@/_generated\u0026#39;; import { ref } from \u0026#39;vue\u0026#39;; const options = ref(\u0026lt;RequestOf\u0026lt;typeof api.bookService.findComplexBook\u0026gt;\u0026gt;{}); let data = ref(\u0026lt;Exclude\u0026lt;ResponseOf\u0026lt;typeof api.bookService.findComplexBook\u0026gt;, undefined\u0026gt;\u0026gt;{}); const query = () =\u0026gt; { api.bookService .findComplexBook(options.value) .then((res) =\u0026gt; { if (res === undefined || res === null) { alert(\u0026#39;未查询到数据\u0026#39;); return; } data.value = res as Exclude\u0026lt;ResponseOf\u0026lt;typeof api.bookService.findComplexBook\u0026gt;, undefined\u0026gt;; }) .catch((err) =\u0026gt; { alert(\u0026#39;查询接口出错了:\u0026#39; + JSON.stringify(err)); }); }; \u0026lt;/script\u0026gt; \u0026lt;style lang=\u0026#34;scss\u0026#34; scoped\u0026gt;\u0026lt;/style\u0026gt; package.json \u0026#34;api\u0026#34;: \u0026#34;node scripts/generate-api.js\u0026#34; \u0026#34;js-yaml\u0026#34;: \u0026#34;^4.1.0\u0026#34;, \u0026#34;adm-zip\u0026#34;: \u0026#34;^0.5.10\u0026#34;, scripts/generate-api.js // import http from \u0026#39;http\u0026#39;; // import fs from \u0026#39;fs\u0026#39;; // import unzipper from \u0026#39;unzipper\u0026#39;; // import {createRequire} from \u0026#39;module\u0026#39; // // const require = createRequire(import.meta.url) const http = require(\u0026#39;node:http\u0026#39;); const fs = require(\u0026#39;node:fs\u0026#39;); const fse = require(\u0026#39;fs-extra\u0026#39;); const AdmZip = require(\u0026#39;adm-zip\u0026#39;); const yaml = require(\u0026#39;js-yaml\u0026#39;); const sourceUrl = \u0026#39;http://localhost:8080/ts.zip\u0026#39;; const apiUrl = \u0026#39;http://localhost:8080/openapi.yml\u0026#39;; const generatePath = \u0026#39;src/api/__generated\u0026#39;; const tmpFilePath = generatePath + \u0026#39;.zip\u0026#39;; console.log(\u0026#39;Downloading \u0026#39; + sourceUrl + \u0026#39;...\u0026#39;); const tmpFile = fs.createWriteStream(tmpFilePath); const request = http.get(sourceUrl, (response) =\u0026gt; { response.pipe(tmpFile); tmpFile.on(\u0026#39;finish\u0026#39;, () =\u0026gt; { tmpFile.close(); console.log(\u0026#39;File save success: \u0026#39;, tmpFilePath); // Remove generatePath if it exists if (fs.existsSync(generatePath)) { console.log(\u0026#39;Removing existing generatePath...\u0026#39;); fse.removeSync(generatePath); console.log(\u0026#39;Existing generatePath removed.\u0026#39;); } // Unzip the file using adm-zip console.log(\u0026#39;Unzipping the file...\u0026#39;); const zip = new AdmZip(tmpFilePath); zip.extractAllTo(generatePath, true); console.log(\u0026#39;File unzipped successfully.\u0026#39;); // Remove the temporary file console.log(\u0026#39;Removing temporary file...\u0026#39;); fs.unlink(tmpFilePath, (err) =\u0026gt; { if (err) { console.error(\u0026#39;Error while removing temporary file:\u0026#39;, err); } else { console.log(\u0026#39;Temporary file removed.\u0026#39;); } }); if (apiUrl) { // const apiDoc = fs.readFileSync(new URL(apiUrl), \u0026#39;utf8\u0026#39;) http.get( apiUrl, (resp) =\u0026gt; { const apiTemp = fs.createWriteStream(generatePath + \u0026#39;/api.yml\u0026#39;); resp.pipe(apiTemp); apiTemp.on(\u0026#39;finish\u0026#39;, () =\u0026gt; { const temp = {}; const doc = yaml.load(fs.readFileSync(generatePath + \u0026#39;/api.yml\u0026#39;, \u0026#39;utf8\u0026#39;)); doc \u0026amp;\u0026amp; Object.keys(doc.paths).forEach((key) =\u0026gt; { const path = doc.paths[key]; const { operationId, parameters, requestBody, responses, summary, tags } = path[Object.keys(path)[0]]; const typeKey = (tags[0] += \u0026#34;[\u0026#39;\u0026#34; + operationId + \u0026#34;\u0026#39;]\u0026#34;); temp[typeKey] = { method: Object.keys(path)[0], parameters, requestBody, responses, summary }; }); fs.writeFileSync(generatePath + \u0026#39;/types.json\u0026#39;, JSON.stringify(temp)); const tempSchema = {}; doc \u0026amp;\u0026amp; doc.components \u0026amp;\u0026amp; Object.keys(doc.components.schemas).forEach((key) =\u0026gt; { const schema = doc.components.schemas[key]; const { properties } = schema; const typeKey = \u0026#39;#/components/schemas/\u0026#39; + key; tempSchema[typeKey] = properties; }); fs.writeFileSync(generatePath + \u0026#39;/schemas.json\u0026#39;, JSON.stringify(tempSchema)); }); }, (err) =\u0026gt; { console.log(err); } ); } }); }); ","date":"2026-08-25T09:34:00+08:00","permalink":"/p/jimmer%E7%94%9F%E6%88%90/","title":"jimmer生成"},{"content":"1. 查看远程连接 git remote -v 2. 取消与远程仓库的连接 git remote remove origin 3. 初始化仓库 git init 4. 添加所有文件 git add . 5. 提交所有文件到本地仓库 git commit -m \u0026#39;备注信息\u0026#39; 6. 连接到远程仓库 git remote add origin 你的远程仓库地址 7. 将项目推送到远程仓库 git push -u origin master #如果出现下面错误可能是因为远程仓库原有的README.md或者.gitignore等文件没有pull到本地仓库而导致的冲突 输入git pull --rebase origin master将文件拉到本地后重新输入步骤7即可解决。 修改本地commit的提交时间 git commit --amend --reset-author --no-edit ","date":"2026-08-25T09:33:54+08:00","permalink":"/p/git--%E6%96%AD%E5%BC%80%E4%B8%8E%E8%BF%9C%E7%A8%8B%E4%BB%93%E5%BA%93%E7%9A%84%E8%BF%9E%E6%8E%A5%E5%B9%B6%E8%BF%9E%E6%8E%A5%E6%96%B0%E4%BB%93%E5%BA%93/","title":"Git--断开与远程仓库的连接并连接新仓库"},{"content":" 查看当前gcc版本 gcc -v 安装gcc 下载地址 tar -vxf gcc-10.1.0.tar.gz mkdir build cd build/ ../configure --prefix=/usr/local/gcc-10.1.0/ --enable-checking=release --enable-languages=c,c++ --disable-multilib gmp安装(若报错提示缺少该依赖) tar -vxf gmp-5.0.1.tar.bz2 cd gmp-5.0.1/ ./configure --prefix=/usr/local/gmp-5.0.1 make make install MPFR编译(若报错提示缺少该依赖) tar -vxf mpfr-3.1.5.tar.xz cd mpfr-3.1.5/ ./configure --prefix=/usr/local/mpfr-3.1.5 --with-gmp=/usr/local/gmp-5.0.1 make make install MPC编译(若报错提示缺少该依赖) tar -vxf mpc-1.0.1.tar.gz cd mpc-1.0.1 ./configure --prefix=/usr/local/mpc-1.0.1 --with-gmp=/usr/local/gmp-5.0.1 --with-mpfr=/usr/local/mpfr-3.1.5 make make install 再次编译GCC(若第一次编译报错，安装依赖之后再次安装) cd gcc-10.1.0/build/ ../configure --prefix=/usr/local/gcc-10.1.0/ --enable-checking=release --enable-languages=c,c++ --disable-multilib --with-gmp=/usr/local/gmp-5.0.1 --with-mpfr=/usr/local/mpfr-3.1.5 --with-mpc=/usr/local/mpc-1.0.1 # make与机器性能有关，可以设置 -j8 make -j4 替换GCC,更新版本 mv /usr/bin/gcc /usr/bin/gcc485 mv /usr/bin/g++ /usr/bin/g++485 mv /usr/bin/c++ /usr/bin/c++485 mv /usr/bin/cc /usr/bin/cc485 ln -s /usr/local/gcc-10.1.0/bin/gcc /usr/bin/gcc ln -s /usr/local/gcc-10.1.0/bin/g++ /usr/bin/g++ ln -s /usr/local/gcc-10.1.0/bin/c++ /usr/bin/c++ ln -s /usr/local/gcc-10.1.0/bin/gcc /usr/bin/cc mv /usr/lib64/libstdc++.so.6 /usr/lib64/libstdc++.so.6.bak ln -s /usr/local/gcc-10.1.0/lib64/libstdc++.so.6.0.28 /usr/lib64/libstdc++.so.6 #确认gcc版本升级成功 gcc -v ","date":"2026-08-25T09:33:50+08:00","permalink":"/p/linux-gcc%E5%8D%87%E7%BA%A7/","title":"Linux gcc升级"},{"content":" 前置说明: 在使用Spring-Boot打的jar包时，需要对jar中的依赖库进行快速更换，避免重新进行构建。 如果直接对jar进行替换，启动会报错，因为jar包在修改之后会自动压缩，SpringBoot规定嵌套的jar不能在被压缩情况下进行替换。 步骤： 使用jar命令解压jar包 jar -xvf test.jar 在解压出来的对应文件目录替换jar包 对替换之后的文件夹目录进行压缩打包 # jar -cfM0 压缩之后的jar名称 要压缩的文件目录 jar -cfM0 test.jar ./ ","date":"2026-08-25T09:33:39+08:00","permalink":"/p/%E6%9B%B4%E6%8D%A2jar%E4%B8%AD%E4%BE%9D%E8%B5%96%E7%9A%84jar%E5%8C%85/","title":"更换jar中依赖的jar包"},{"content":"依赖使用 org.javassist:javassist:3.21.0-GA对class文件内容进行编辑\nClassPool pool = ClassPool.getDefault(); String jarPath = \u0026#34;c:\\\\1.jar\u0026#34;; pool.insertClassPath(jarPath); String classPackageName = \u0026#34;c:\\\\com.xxx.testClass\u0026#34;; CtClass driverclass =pool.get(classPackageName); String methodName = \u0026#34;test\u0026#34;; driverclass.getDeclaredMethod(methodName).setBody(\u0026#34;return false;\u0026#34;); String classOutPath = \u0026#34;D:\\\\\u0026#34;; driverclass.writeFile(classOutPath); ","date":"2026-08-25T09:33:34+08:00","permalink":"/p/%E5%AF%B9class%E6%96%87%E4%BB%B6%E5%86%85%E5%AE%B9%E8%BF%9B%E8%A1%8C%E7%BC%96%E8%BE%91/","title":"对class文件内容进行编辑"},{"content":"1. 开启 HTTP/2 HTTP/2最初是在Nginx版本1.9.5中实现的，以取代spdy。在Nginx上启用HTTP/2模块很简单。\nlisten 443 ssl http2; 可以通过curl来验证：\ncurl --http2 -I https://ip:port/ 2. 开启 SSL session 缓存 启用 SSL Session 缓存可以减少 TLS 的反复验证，减少 TLS 握手。 1M 的内存可以缓存 4000 个连接\nssl_session_cache shared:SSL:50m; # 1m 4000个， ssl_session_timeout 1h; # 1小时过期 3. 禁用 SSL session tickets\nssl_session_tickets off; 4. 禁用 TLS version 1.0\nssl_protocols TLSv1.2 TLSv1.3; 5. 启用OCSP Stapling 如果不启用 OCSP Stapling 的话，在用户连接你的服务器的时候，需要去验证证书，这个验证证书的时间不可控\nssl_stapling on; ssl_stapling_verify on; ssl_trusted_certificate /path/to/full_chain.pem; resolver 8.8.8.8 8.8.4.4 valid=300s; resolver_timeout 5s; 6. 减小ssl buffer size ssl_buffer_size 控制在发送数据时的 buffer 大小，默认情况下，缓冲区设置为16k，为了最大程度地减少TTFB（至第一个字节的时间），最好使用较小的值，这样TTFB可以节省大约30 – 50ms。\nssl_buffer_size 4k; 7. 调整 Cipher 优先级 更新更快的 Cipher放前面，这样延迟更小。\n# 手动启用 cipher 列表 ssl_prefer_server_ciphers on; # prefer a list of ciphers to prevent old and slow ciphers ssl_ciphers \u0026#39;EECDH+AESGCM:EDH+AESGCM:AES256+EECDH:AES256+EDH\u0026#39;; ","date":"2026-08-25T09:32:47+08:00","permalink":"/p/nginx-tls_ssl-https%E6%80%A7%E8%83%BD%E4%BC%98%E5%8C%96/","title":"Nginx TLS_SSL HTTPS性能优化"},{"content":"docker 安装启动redis #设置容器启动策略：开机自启 docker container update redis_6379 --restart=always #配置文件启动 docker run -p 6379:6379 --restart=always --name redis_6379 \\ -v /home/redis/data:/data \\ -v /home/redis/redis.conf:/etc/redis/redis.conf \\ -d redis redis-server /etc/redis/redis.conf --appendonly yes --requirepass \u0026#34;12345678\u0026#34; #直接启动 docker run -p 6379:6379 --restart=always --name redis_6379 -v /home/redis/data:/data -d redis --appendonly yes --requirepass \u0026#34;12345678\u0026#34; docker 启动nginx 1 docker中nginx启动时会使用 use nginx启动 2 将要挂载的文件赋予 777权限 chmod 777 -R /home/nginx 3 root 和 alias 一个端口只能有一个root(静态资源 html/web_front)，如果要添加需要使用alias(目录后要加/ html/damin_front/) # 设置开机自启 docker update nginx_proxy --restart=always # 更新启动配置 docker update nginx_proxy --restart=no --network=host || -p 80:80 -p 443:443 #启动 docker run -p 80:80 -p 443:443 -d --privileged=true --name nginx_proxy \\ -v /home/nginx/logs/:/var/log/nginx/ \\ -v /home/nginx/port/:/etc/nginx/conf.d/ \\ -v /home/nginx/modules/:/etc/nginx/modules/ \\ -v /home/nginx/conf/nginx.conf:/etc/nginx/nginx.conf:ro \\ -v /home/nginx/conf/ext/:/etc/nginx/ext/ \\ -v /home/nginx/ssl:/opt/nginx/ssl \\ -v /home/nginx/html/:/etc/nginx/html/ nginx:1.25.4 docker 启动minio # 设置开机自启 docker update minio_9000 --restart=no docker run -p 9000:9000 --name minio_9000 -d -e \u0026#34;MINIO_ACCESS_KEY=minioadmin\u0026#34; \\ -e \u0026#34;MINIO_SECRET_KEY=minioadmin\u0026#34; \\ -v /home/minio/data:/data \\ -v /data/minio/config:/root/.minio \\ minio/minio server /data/minio --console-address \u0026#34;:9090\u0026#34; -address \u0026#34;:9000\u0026#34; docker 启动 elasticearch # 一、下载 docker pull docker.io/elasticsearch:版本号 docker pull docker.io/elasticsearch:8.8.2 # 二、启动 docker run -d --privileged=true --name es_9200 -p 9200:9200 -p 9300:9300 \\ -e \u0026#34;discovery.type=single-node\u0026#34; \\ -e ES_JAVA_OPTS=\u0026#34;-Xms512m -Xmx512m\u0026#34; \\ -v /home/elasticsearch/data:/usr/share/elasticsearch/data \\ -v /home/elasticsearch/config:/usr/share/elasticsearch/config \\ -v /home/elasticsearch/logs:/usr/share/elasticsearch/logs \\ docker.elastic.co/elasticsearch/elasticsearch:8.8.2 # 三、安装分成器 docker exec -it es_9200 bash ./bin/elasticsearch-plugin install https://github.com/medcl/elasticsearch-analysis-ik/releases/download/v8.8.2/elasticsearch-analysis-ik-8.8.2.zip # 四、重新启动 docker restart es_9200 docker 启动kibana docker run -d --name kibana_5601 --link es_9200:elasticsearch -p 5601:5601 kibana docker 启动 mysql 多次启动时有可能需要清空data文件夹\ndocker run -p 3306:3306 --name mysql_3306 --privileged=true \\ -v /home/mysql/conf:/etc/mysql/conf.d \\ -v /home/mysql/logs:/var/log/mysql \\ -v /home/mysql/data:/var/lib/mysql \\ -v /home/mysql/mysql-files:/var/lib/mysql-files \\ -e MYSQL_ROOT_PASSWORD=\u0026#39;*********\u0026#39; -d mysql docker 启动 nacos docker run -p 8848:8848 --name nacos_8848 -d \\ --privileged=true \\ -e JVM_XMS=256m \\ -e JVM_XMX=256m \\ -e JVM_XMN=64m \\ -e MODE=standalone \\ -v /home/nacos/logs:/home/nacos/logs \\ -v /home/nacos/conf:/home/nacos/conf \\ -e MYSQL_SERVICE_HOST=127.0.0.1 \\ -e MYSQL_SERVICE_PORT=3306 \\ -e MYSQL_SERVICE_DB_NAME=nacos \\ -e MYSQL_SERVICE_USER=nacos \\ -e MYSQL_SERVICE_PASSWORD=nacos \\ nacos/nacos-server docekr 启动 rabbitmq docker run --name=rabbitmq_5672 -p 15672:15672 -p 5672:5672 -d \\ -v /home/rabbitmq/conf:/etc/rabbitmq \\ -v /home/rabbitmq/log:/var/log/rabbitmq \\ -e RABBITMQ_DEFAULT_USER=rabbitmq \\ -e RABBITMQ_DEFAULT_PASS=123456 \\ rabbitmq:management docekr 启动 canal 1.在%userprofile% 建一个.wslconfig文件，内容如下 [wsl2] kernelCommandLine = vsyscall=emulate 2.然后重新启动mysql docker run --name canal -p 11111:11111 -d --link mysql_3306:mysql_host \\ -v /home/canal/instance.properties:/home/admin/canal-server/conf/example/instance.properties \\ -v /home/canal/canal.properties:/home/admin/canal-server/conf/canal.properties \\ -v /home/canal/logs/example.log:/home/admin/canal-server/logs/example/example.log \\ canal/canal-server docker启动halo # 1.docekr docker run -d --name halo --restart=always -p 8090:8090 \\ -v /home/blog:/root/.halo2 \\ halohub/halo:2.10 \\ --spring.r2dbc.url=r2dbc:pool:mysql://ip:port/blog \\ --spring.r2dbc.username=blog \\ --spring.r2dbc.password=12345678 \\ --spring.sql.init.platform=mysql \\ --halo.external-url=http://ip:port/ \\ --halo.security.initializer.superadminusername=username\\ --halo.security.initializer.superadminpassword=password ","date":"2026-08-25T09:32:33+08:00","permalink":"/p/docker%E5%AE%89%E8%A3%85-%E8%BD%AF%E4%BB%B6_%E5%BA%94%E7%94%A8%E5%91%BD%E4%BB%A4/","title":"docker安装 软件_应用命令"},{"content":"不用按顺序执行\nyum install -y yum-utils device-mapper-persistent-data alinux3-plus | dnf install dnf-plugin-releasever-adapter --repo alinux3-plus yum-config-manager --add-repo https://mirrors.aliyun.com/docker-ce/linux/centos/docker-ce.repo yum install -y docker-ce 可能出现问题：\n一、Cannot connect to the Docker daemon at unix:///var/run/docker.sock. Is the docker daemon running?.\nsystemctl status docker sudo systemctl start docker ","date":"2026-08-25T09:32:28+08:00","permalink":"/p/%E9%98%BF%E9%87%8C%E4%BA%91%E6%9C%8D%E5%8A%A1%E5%99%A8%E5%AE%89%E8%A3%85docker%E5%91%BD%E4%BB%A4/","title":"阿里云服务器安装docker命令"},{"content":"\u0026lt;schems\u0026gt;://\u0026lt;username\u0026gt;:\u0026lt;password\u0026gt;@\u0026lt;host\u0026gt;:\u0026lt;port\u0026gt;\u0026lt;/path\u0026gt;[?query][#fragment]\n例：http://root:123456@127.0.0.1:8080 一、schems 协议,http/https/socket/socket5/file/ftp/data/mailto\u0026hellip; 二、\u0026lt;username\u0026gt;:\u0026lt;password\u0026gt; 用户信息，账号：密码。 三、@ 将用户信息和域名分开。 四、\u0026lt;host\u0026gt;:\u0026lt;port\u0026gt;domain域名 五、\u0026lt;/path\u0026gt; 访问路径 六、[?query]查询参数 七、[#fragment]跳转片段 ","date":"2026-08-25T09:32:23+08:00","permalink":"/p/web-url%E7%9A%84%E7%BB%84%E6%88%90/","title":"web URL的组成"},{"content":"问题： 工作中接触到一些老项目，使用tomcat的ROOT部署方式,使用IDEA无法直接进行打包更新，所以只能通过增量更新的方式去替换文件，如果手动将需要修改的文件一个一个去替换，浪费人力，所以研究一个批量增量更新方式。\n原理： 借助git的差异化对比，得到每次要更新的文件路径； 借助java的jar命令根据文件路径直接打包； 将打成的jar替换到tomcat中。 方法一： git archive -o ../update1.zip ec0f7d57 $(git diff --name-only startPoint endPoint) 其中startPoint为git差异起始点id,endPoint为差异结束点id。 该方法无法处理class文件的改变(因为git记录的是java文件的改变，而更新需要编译之后的class文件)。 方法二 update.bat (需要ide编译class项目，可能出现中文乱码情况) @echo off rem 定义class路径 rem SET /p outPath=输入文件编译目录(class): rem 路径应该能到达WEB-INF同级 set outPath=out/artifacts/sp_Web_exploded rem 定义git差异节点 rem SET /p startPoint=输入起始节点id: rem SET /p endPoint=输入结束节点id: set startPoint=446e54e1 set endPoint=76c2e29e rem 定义jar文件路径 SET txtName=source.txt SET sourceTxtFile=%outPath%/%txtName% git diff --name-only %startPoint% %endPoint% \u0026gt; %sourceTxtFile% rem 使用bat命令替换 @setlocal enabledelayedexpansion rem 读取文件所有内容 for /f \u0026#34;delims=\u0026#34; %%i in (%sourceTxtFile%) do ( rem 设置变量a为每行内容 set a=%%i rem 替换内容 1.替换java为class 2.替换src目录为WEB-INF/classes/ 3.替换WebRoot/为\u0026#39;\u0026#39; set \u0026#34;a=!a:.java=.class!\u0026#34; set \u0026#34;a=!a:tysp_src/=WEB-INF/classes/!\u0026#34; set \u0026#34;a=!a:system_src/=WEB-INF/classes/!\u0026#34; set \u0026#34;a=!a:WebRoot/=!\u0026#34; rem 把修改后的全部行存入$ echo !a!\u0026gt;\u0026gt;$) move $ %sourceTxtFile% || EXIT /B cd %outPath% jar -cvf target-update.jar @%txtName% rem echo update完成! pause 方法三 update.sh(借助git bash执行,处理中文乱码) #定义WEB-INF路径 cd out/artifacts/wt_Web_exploded #获取2个节点之间的差异文件 #\u0026#39;s#old_string#new_string#g\u0026#39; 替换路径 git diff c2aed67d fd7ab26d --name-only \u0026gt; 1.txt \u0026amp;\u0026amp; sed -i -e \u0026#39;s#.java#.class#g\u0026#39; -e \u0026#39;s#tysp_src#WEB-INF/classes/#g\u0026#39; -e \u0026#39;s#system_src#WEB-INF/classes/#g\u0026#39; -e \u0026#39;s#WebRoot/##g\u0026#39; -e \u0026#39;s#src/#WEB-INF/classes/#g\u0026#39; 1.txt \u0026amp;\u0026amp; cat 1.txt | xargs tar -cvf update.tar.gz 遇到问题：\n一、cmd文件中定义变量不能含有空格 set var=xx 二、排除指定文件夹之后比较改动的文件 # --name-status 显示增删改表标识 # --name-only 只显示增删改的文件名 git diff --name-status point1 point2 -- \u0026#39;:!src/views/assetManagement\u0026#39; \u0026gt; fileLog.txt git diff --name-status --oneline -- . \u0026#39;!src/views/assetManagement\u0026#39; \u0026gt; fileLog.txt ","date":"2026-08-25T09:32:16+08:00","permalink":"/p/%E5%9F%BA%E4%BA%8Egit%E8%BF%9B%E8%A1%8Cwar%E6%89%B9%E9%87%8F%E6%89%93%E5%8C%85%E5%A2%9E%E9%87%8F%E6%9B%B4%E6%96%B0/","title":"基于git进行war批量打包(增量更新)"},{"content":"安装memcached中间件 memcached-win64-1.4.4-14下载\n1.安装 call %~dp0/memcached.exe -d install pause 2.启动 call %~dp0\\memcached.exe -d start pause 3.启动 call %~dp0/memcached.exe -d stop pause 4.卸载 call %~dp0/memcached.exe -d uninstall pause 下载依赖到lib/目录中 jdk1.6 memcached-session-manager-1.6.0.jar memcached-session-manager-tc7-1.6.0.jar spymemcached-2.5.jar jdk.8 memcached-session-manager-2.3.2.jar memcached-session-manager-tc7-2.3.2.jar spymemcached-2.12.3.jar 修改tomcat的conf/context.xml配置 \u0026lt;Manager className=\u0026#34;de.javakaffee.web.msm.MemcachedBackupSessionManager\u0026#34; memcachedNodes=\u0026#34;n1:127.0.0.1:11211,n2:127.0.0.1:11212\u0026#34; sticky=\u0026#34;false\u0026#34; sessionBackupAsync=\u0026#34;false\u0026#34; requestUriIgnorePattern=\u0026#34;.*\\.(ico|png|gif|jpg|css|js)$\u0026#34; /\u0026gt; ","date":"2026-08-25T09:32:11+08:00","permalink":"/p/tomcat%E4%B8%8Ememcached-session-manager%E5%85%B1%E4%BA%ABsession/","title":"tomcat与memcached-session-manager共享session"},{"content":"查看node版本 node -v\nnode \u0026lt; 14 node-sass:4.14.0 sass-loader:7.1.0 node = 16.x node-sass:6.0.1 sass-loader:10.2.0 npm i node-sass sass-loader \u0026ndash;ignore-scripts\n","date":"2026-08-25T09:32:07+08:00","permalink":"/p/node-sasssass-loader%E5%92%8C-node-%E7%89%88%E6%9C%AC%E9%97%AE%E9%A2%98/","title":"node-sass、sass-loader和 node 版本问题"},{"content":"package com.tjsoft.base.page.manager; import java.util.*; /** * 定时对删除map */ public class ExpiryMap\u0026lt;K, V\u0026gt; extends HashMap\u0026lt;K, V\u0026gt; { private static final long serialVersionUID = 1L; /** * default expiry time 2s */ private long EXPIRY = 1000 * 2; private HashMap\u0026lt;K, Long\u0026gt; expiryMap = new HashMap(); /** 缓存实例对象 */ private volatile static ExpiryMap\u0026lt;String, String\u0026gt; SameUrlMap; /** * 采用单例模式获取实例 * @return */ public static ExpiryMap getInstance() { //第一次判空,提高效率 if (null == SameUrlMap) { //保证线程安全 synchronized (ExpiryMap.class) { //第二次判空,保证单例对象的唯一性,防止第一次有多个线程进入第一个if判断 if (null == SameUrlMap) { SameUrlMap = new ExpiryMap(); } } } return SameUrlMap; } public ExpiryMap(){ super(); } public ExpiryMap(long defaultExpiryTime){ this(1 \u0026lt;\u0026lt; 4, defaultExpiryTime); } public ExpiryMap(int initialCapacity, long defaultExpiryTime){ super(initialCapacity); this.EXPIRY = defaultExpiryTime; } @Override public V put(K key, V value) { expiryMap.put(key, System.currentTimeMillis() + EXPIRY); return super.put(key, value); } @Override public boolean containsKey(Object key) { return !checkExpiry(key, true) \u0026amp;\u0026amp; super.containsKey(key); } /** * @param key * @param value * @param expiryTime 键值对有效期 毫秒 * @return */ public V put(K key, V value, long expiryTime) { expiryMap.put(key, System.currentTimeMillis() + expiryTime); return super.put(key, value); } @Override public int size() { return entrySet().size(); } @Override public boolean isEmpty() { return entrySet().size() == 0; } @Override public boolean containsValue(Object value) { if (value == null) { return Boolean.FALSE; } Set\u0026lt;Entry\u0026lt;K, V\u0026gt;\u0026gt; set = super.entrySet(); Iterator\u0026lt;Entry\u0026lt;K, V\u0026gt;\u0026gt; iterator = set.iterator(); while (iterator.hasNext()) { Map.Entry\u0026lt;K, V\u0026gt; entry = iterator.next(); if(value.equals(entry.getValue())){ if(checkExpiry(entry.getKey(), false)) { iterator.remove(); return Boolean.FALSE; }else { return Boolean.TRUE; } } } return Boolean.FALSE; } @Override public Collection\u0026lt;V\u0026gt; values() { Collection\u0026lt;V\u0026gt; values = super.values(); if(values == null || values.size() \u0026lt; 1) { return values; } Iterator\u0026lt;V\u0026gt; iterator = values.iterator(); while (iterator.hasNext()) { V next = iterator.next(); if(!containsValue(next)) { iterator.remove(); } } return values; } @Override public V get(Object key) { if (key == null) { return null; } if(checkExpiry(key, true)) { return null; } return super.get(key); } /** * * @Description: 是否过期 * @param key * @return null:不存在或key为null -1:过期 存在且没过期返回value 因为过期的不是实时删除，所以稍微有点作用 */ public Object isInvalid(Object key) { if (key == null) { return null; } if(!expiryMap.containsKey(key)){ return null; } long expiryTime = expiryMap.get(key); boolean flag = System.currentTimeMillis() \u0026gt; expiryTime; if(flag){ super.remove(key); expiryMap.remove(key); return -1; } return super.get(key); } @Override public void putAll(Map\u0026lt;? extends K, ? extends V\u0026gt; m) { for (Map.Entry\u0026lt;? extends K, ? extends V\u0026gt; e : m.entrySet()) { expiryMap.put(e.getKey(), System.currentTimeMillis() + EXPIRY); } super.putAll(m); } @Override public Set\u0026lt;Map.Entry\u0026lt;K,V\u0026gt;\u0026gt; entrySet() { Set\u0026lt;Map.Entry\u0026lt;K, V\u0026gt;\u0026gt; set = super.entrySet(); Iterator\u0026lt;Map.Entry\u0026lt;K, V\u0026gt;\u0026gt; iterator = set.iterator(); while (iterator.hasNext()) { Map.Entry\u0026lt;K, V\u0026gt; entry = iterator.next(); if(checkExpiry(entry.getKey(), false)) { iterator.remove(); } } return set; } /** * * @Description: 是否过期 * @param expiryTime true 过期 * @param isRemoveSuper true super删除 * @return */ private boolean checkExpiry(Object key, boolean isRemoveSuper){ if(!expiryMap.containsKey(key)){ return Boolean.FALSE; } long expiryTime = expiryMap.get(key); boolean flag = System.currentTimeMillis() \u0026gt; expiryTime; if(flag){ if(isRemoveSuper) { super.remove(key); } expiryMap.remove(key); } return flag; } public boolean checkExpiry(Object key){ return checkExpiry(key, true); } } ","date":"2026-08-25T09:32:03+08:00","permalink":"/p/%E5%8F%AF%E4%BB%A5%E8%AE%BE%E7%BD%AE%E8%BF%87%E6%9C%9F%E6%97%B6%E9%97%B4%E7%9A%84java%E7%BC%93%E5%AD%98map/","title":"可以设置过期时间的Java缓存Map"},{"content":"https://blog.csdn.net/weixin_39973810/article/details/120965406\n","date":"2026-08-25T09:31:57+08:00","permalink":"/p/validation-failed-for-argument-0-%E5%8F%82%E6%95%B0%E6%A0%A1%E9%AA%8C%E5%A4%B1%E8%B4%A5%E7%9A%84%E8%A7%A3%E5%86%B3%E5%8A%9E%E6%B3%95/","title":"Validation failed for argument [0] 参数校验失败的解决办法"},{"content":"https://juejin.cn/post/6844904111570190349\n","date":"2026-08-25T09:31:52+08:00","permalink":"/p/yarn%E6%8A%A5%E6%96%87%E4%BB%B6%E5%90%8D%E7%9B%AE%E5%BD%95%E5%90%8D%E6%88%96%E5%8D%B7%E6%A0%87%E8%AF%AD%E6%B3%95%E4%B8%8D%E6%AD%A3%E7%A1%AE%E9%94%99%E8%AF%AF%E7%9A%84%E8%A7%A3%E5%86%B3%E6%96%B9%E6%A1%88/","title":"yarn报“文件名、目录名或卷标语法不正确”错误的解决方案"},{"content":"JAVA代码 package com.company.pms.pmsbase.utils; import javax.crypto.Cipher; import javax.crypto.spec.IvParameterSpec; import javax.crypto.spec.SecretKeySpec; import org.apache.commons.codec.binary.Base64; public class AesUtil { public static void main(String args[]) throws Exception { String content = \u0026#34;明文 123 abc\u0026#34;; //加密 String encrypted = encrypt(content, KEY, IV); //解密 String decrypted = decrypt(encrypted, KEY, IV); System.out.println(\u0026#34;加密前：\u0026#34; + content); System.out.println(\u0026#34;加密后：\u0026#34; + encrypted); System.out.println(\u0026#34;解密后：\u0026#34; + decrypted); } private static String KEY = \u0026#34;abcdef0123456789\u0026#34;; // 长度必须是 16 private static String IV = \u0026#34;abcdef0123456789\u0026#34;; // 长度必须是 16 /** * 加密返回的数据转换成 String 类型 * @param content 明文 * @param key 秘钥 * @param iv 初始化向量是16位长度的字符串 * @return * @throws Exception */ public static String encrypt(String content, String key, String iv) throws Exception { // 将返回的加密过的 byte[] 转换成Base64编码字符串 ！！！！很关键 return base64ToString(AES_CBC_Encrypt(content.getBytes(), key.getBytes(), iv.getBytes())); } /** * 将解密返回的数据转换成 String 类型 * @param content Base64编码的密文 * @param key 秘钥 * @param iv 初始化向量是16位长度的字符串 * @return * @throws Exception */ public static String decrypt(String content, String key, String iv) throws Exception { // stringToBase64() 将 Base64编码的字符串转换成 byte[] !!!与base64ToString(）配套使用 return new String(AES_CBC_Decrypt(stringToBase64(content), key.getBytes(), iv.getBytes())); } private static byte[] AES_CBC_Encrypt(byte[] content, byte[] keyBytes, byte[] iv){ try { SecretKeySpec key = new SecretKeySpec(keyBytes, \u0026#34;AES\u0026#34;); Cipher cipher = Cipher.getInstance(\u0026#34;AES/CBC/PKCS5Padding\u0026#34;); cipher.init(Cipher.ENCRYPT_MODE,key, new IvParameterSpec(iv)); byte[] result = cipher.doFinal(content); return result; } catch (Exception e) { System.out.println(\u0026#34;exception:\u0026#34;+e.toString()); } return null; } private static byte[] AES_CBC_Decrypt(byte[] content, byte[] keyBytes, byte[] iv){ try { SecretKeySpec key = new SecretKeySpec(keyBytes, \u0026#34;AES\u0026#34;); Cipher cipher = Cipher.getInstance(\u0026#34;AES/CBC/PKCS5Padding\u0026#34;); cipher.init(Cipher.DECRYPT_MODE,key, new IvParameterSpec(iv)); byte[] result = cipher.doFinal(content); return result; } catch (Exception e) { System.out.println(\u0026#34;exception:\u0026#34;+e.toString()); } return null; } /** * 字符串装换成 Base64 */ public static byte[] stringToBase64(String key) throws Exception { return Base64.decodeBase64(key.getBytes()); } /** * Base64装换成字符串 */ public static String base64ToString(byte[] key) throws Exception { return new Base64().encodeToString(key); } } 前端代码 function encodeAesString(data,key,iv){ var key = CryptoJS.enc.Utf8.parse(key); var iv = CryptoJS.enc.Utf8.parse(iv); var encrypted =CryptoJS.AES.encrypt(data,key,{ iv:iv, mode:CryptoJS.mode.CBC, padding:CryptoJS.pad.Pkcs7 }); //返回的是base64格式的密文 return encrypted; } // encrypted 为是base64格式的密文 function decodeAesString(encrypted,key,iv){ var key = CryptoJS.enc.Utf8.parse(key); var iv = CryptoJS.enc.Utf8.parse(iv); var decrypted =CryptoJS.AES.decrypt(encrypted,key,{ iv:iv, mode:CryptoJS.mode.CBC, padding:CryptoJS.pad.Pkcs7 }); return decrypted.toString(CryptoJS.enc.Utf8); } // 测试加、解密 function testAES(){ var data = \u0026#34;明文 123 abc\u0026#34;; // 明文 var key = \u0026#39;abcdef0123456789\u0026#39;; // 密钥 长度16 var iv = \u0026#39;abcdef0123456789\u0026#39;; // 密钥 长度16 console.log(\u0026#34;加密前：\u0026#34; + data); // 测试加密 var encrypted = encodeAesString(data,key,iv); // 密文 console.log(\u0026#34;加密后: \u0026#34; + encrypted); var decryptedStr = decodeAesString(encrypted,key,iv); console.log(\u0026#34;解密后: \u0026#34; + decryptedStr); } ","date":"2026-08-25T09:31:45+08:00","permalink":"/p/java%E5%8A%9F%E8%83%BD%E4%BB%A3%E7%A0%81-cryptojs%E4%B8%ADaes%E5%AE%9E%E7%8E%B0%E5%89%8D%E5%90%8E%E7%AB%AF%E9%80%9A%E7%94%A8%E5%8A%A0%E8%A7%A3%E5%AF%86%E6%8A%80%E6%9C%AF/","title":"JAVA功能代码-CryptoJS中AES实现前后端通用加解密技术"},{"content":"import java.io.File; import java.io.IOException; import java.net.URL; import java.net.URLClassLoader; import java.net.URLStreamHandlerFactory; public class CustomClassLoad extends URLClassLoader { public CustomClassLoad(){ this(getSystemClassLoader()); } public CustomClassLoad(ClassLoader parent) { super(new URL[] {}, null); } public void addURL(URL... urls) { if (urls != null) { for (URL url : urls) { super.addURL(url); } } } public void addFile(File... files) throws IOException { if (files != null) { for (File file : files) { if (file != null) { super.addURL(file.toURI().toURL()); } } } } } ","date":"2026-08-25T09:31:40+08:00","permalink":"/p/java%E5%8A%9F%E8%83%BD%E4%BB%A3%E7%A0%81-%E8%87%AA%E5%AE%9A%E4%B9%89%E7%B1%BB%E5%8A%A0%E8%BD%BD%E5%99%A8%E5%8A%A0%E8%BD%BD%E4%B8%8D%E5%90%8C%E7%89%88%E6%9C%AC%E7%9A%84jar/","title":"JAVA功能代码-自定义类加载器加载不同版本的jar"},{"content":"import java.io.File; import java.util.List; // 扫描文件夹 public class FilesUntil { public static List getFiles(String path, List\u0026lt;String\u0026gt; save) { File file = new File(path); File[] files = file.listFiles(); if(files==null){ return null; } for (int i = 0; i \u0026lt; files.length; i++) { if (files[i].isDirectory()) { getFiles(files[i].getPath(),save); } else { save.add(files[i].getAbsolutePath()); } } return save; } } ","date":"2026-08-25T09:31:36+08:00","permalink":"/p/java%E5%8A%9F%E8%83%BD%E4%BB%A3%E7%A0%81-%E6%89%AB%E6%8F%8F%E6%8C%87%E5%AE%9A%E6%96%87%E4%BB%B6%E4%B8%8B%E7%9A%84%E6%96%87%E4%BB%B6/","title":"JAVA功能代码-扫描指定文件下的文件"},{"content":"import java.io.BufferedReader; import java.io.File; import java.io.FileReader; import java.io.IOException; import java.nio.ByteBuffer; import java.nio.channels.FileChannel; import java.nio.charset.Charset; import java.nio.file.Files; import java.nio.file.Path; import java.nio.file.StandardOpenOption; /** * TODO * * @Author seems * @Date 2021/5/28 下午 09:07 */ public class FileUntils { // 高效读取txt文本 public static String getTxtContent(File file, Charset charset) throws IOException { Path path = file.toPath(); // 一个文本文件如果已经大于int最大值，这种文件一般来说很少见有可能是log文件 if (file.length() \u0026lt;= Integer.MAX_VALUE - 8) { // 使用nio提高读取速度 try (FileChannel in = FileChannel.open(path, StandardOpenOption.READ)) { ByteBuffer byteBuffer = ByteBuffer.allocate((int) in.size()); in.read(byteBuffer); in.close(); System.out.println(byteBuffer); System.out.println(byteBuffer.array()); return new String(byteBuffer.array(), charset); } } StringBuilder msg = new StringBuilder(); try (BufferedReader reader = Files.newBufferedReader(path, charset)) { for (; ; ) { String line = reader.readLine(); if (line == null) { break; } msg.append(line); } } return msg.toString(); } public static String getTxtContent(File file) throws IOException { FileReader fr = null; BufferedReader br = null; StringBuffer txt = new StringBuffer(); try { fr = new FileReader(file); br = new BufferedReader(fr); String line = null; while ((line = br.readLine()) != null) { txt.append(line); txt.append(\u0026#34;\\n\u0026#34;); } br.close(); fr.close(); } catch (IOException e) { e.printStackTrace(); } finally { if (br != null) { try { br.close(); } catch (IOException e) { e.printStackTrace(); } } if (fr != null) { try { fr.close(); } catch (IOException e) { e.printStackTrace(); } } } return txt.toString(); } // 读取文件名 public static void getFileName(String path){ // get file list where the path has File file = new File(path); // get the folder list File[] array = file.listFiles(); for(int i=0;i\u0026lt;array.length;i++){ if(array[i].isFile()){ System.out.println(array[i].getName()); System.out.println(array[i]); System.out.println(array[i].getPath()); }else if(array[i].isDirectory()){ getFileName(array[i].getPath()); } } } } ","date":"2026-08-25T09:31:31+08:00","permalink":"/p/java%E5%8A%9F%E8%83%BD%E4%BB%A3%E7%A0%81-%E9%AB%98%E6%95%88%E8%AF%BB%E5%8F%96txt%E6%96%87%E6%9C%AC/","title":"JAVA功能代码-高效读取txt文本"},{"content":"import java.io.UnsupportedEncodingException; public class ChineseToEn { private final static int[] secPosValue = { 1601,1637,1833,2078,2274,2302,2433,2594, 2787,3106,3212,3472,3635,3722,3730,3858, 4027,4086,4390,4558,4684,4925,5249,5590}; private final static String[] firstLetter = { \u0026#34;a\u0026#34;,\u0026#34;b\u0026#34;,\u0026#34;c\u0026#34;,\u0026#34;d\u0026#34;,\u0026#34;e\u0026#34;,\u0026#34;f\u0026#34;,\u0026#34;g\u0026#34;,\u0026#34;h\u0026#34;, \u0026#34;j\u0026#34;,\u0026#34;k\u0026#34;,\u0026#34;l\u0026#34;,\u0026#34;m\u0026#34;,\u0026#34;n\u0026#34;,\u0026#34;o\u0026#34;,\u0026#34;p\u0026#34;,\u0026#34;q\u0026#34;, \u0026#34;r\u0026#34;,\u0026#34;s\u0026#34;,\u0026#34;t\u0026#34;,\u0026#34;w\u0026#34;,\u0026#34;x\u0026#34;,\u0026#34;y\u0026#34;,\u0026#34;z\u0026#34; }; /** * 获取所有汉字首字母 * @param str * @return */ public String getAllFirstLetter(String str){ if (str == null || str.trim().length() == 0){ return \u0026#34;\u0026#34;; } String _str = \u0026#34;\u0026#34;; for (int i = 0; i \u0026lt; str.length(); i++) { _str = _str + this.getFirstLetter(str.substring(i,i+1)); } return _str; } /** * 获取第一个汉字首字母 * @param str * @return */ private String getFirstLetter(String str) { if (str == null || str.trim().length() == 0){ return \u0026#34;\u0026#34;; } str = this.conversionStr(str,\u0026#34;GB2312\u0026#34;,\u0026#34;ISO8859-1\u0026#34;); if (str.length() \u0026gt; 1){ int sectorCode =(int)str.charAt(0); int positionCode = (int)str.charAt(1); sectorCode = sectorCode - 160; positionCode = positionCode - 160; int secPosCode = sectorCode * 100 + positionCode; if(secPosCode \u0026gt; 1600 \u0026amp;\u0026amp; secPosCode \u0026lt; 5590){ for (int i = 0; i \u0026lt; 23; i++) { if (secPosCode \u0026gt;= secPosValue[i] \u0026amp;\u0026amp; secPosCode \u0026lt; secPosValue[i+1]){ str = firstLetter[i]; break; } } }else { str =this.conversionStr(str, \u0026#34;ISO8859-1\u0026#34;,\u0026#34;GB2312\u0026#34;); str = str.substring(0,1); } } return str; } /** * 转换编码 * @param str * @param oldchartset * @param chartset * @return */ private String conversionStr(String str, String oldchartset, String chartset) { try { str = new String(str.getBytes(oldchartset),chartset); }catch (UnsupportedEncodingException e){ System.out.println(\u0026#34;转换编码异常\u0026#34;+e.getMessage()); } return str; } } ","date":"2026-08-25T09:31:26+08:00","permalink":"/p/java%E5%8A%9F%E8%83%BD%E4%BB%A3%E7%A0%81-%E5%AD%97%E7%AC%A6%E4%B8%B2%E6%8F%90%E5%8F%96%E9%A6%96%E5%AD%97%E6%AF%8D/","title":"JAVA功能代码-字符串提取首字母"},{"content":" domain为IP地址，从startport端口开始，扫描到endport端口为止 public void test(String domain,int startport,int endport) { if (startport \u0026gt; endport){ System.out.println(\u0026#34;输入参数错误!\u0026#34;); return; } int flag=0; LinkedList\u0026lt;Thread\u0026gt; threadPool = new LinkedList\u0026lt;Thread\u0026gt;(); for (int i = startport ; i\u0026lt;endport ; i++ ){ int port = i; Socket socket = new Socket(); Runnable run = new Runnable() { @Override public void run() { try { socket.connect(new InetSocketAddress(domain,port)); System.out.println(\u0026#34;端口\u0026#34;+port+\u0026#34;:开放\u0026#34;); } catch (IOException e) { // System.out.println(\u0026#34;端口\u0026#34;+port+\u0026#34;:关闭\u0026#34;); } } }; flag++; Thread th = new Thread(run); th.start(); threadPool.add(th); } Runnable runobserv = new Runnable() { @Override public void run() { boolean alljobisover = false; while (!alljobisover){ alljobisover = true; for (Thread thread : threadPool){ if (thread.isAlive()){ alljobisover = false; break; } } } } }; Thread t1 = new Thread(runobserv); t1.start(); System.out.println(\u0026#34;flag:\u0026#34;+flag); } ","date":"2026-08-25T09:31:22+08:00","permalink":"/p/java%E5%8A%9F%E8%83%BD%E4%BB%A3%E7%A0%81-%E7%AB%AF%E5%8F%A3%E6%89%AB%E6%8F%8F/","title":"JAVA功能代码-端口扫描"},{"content":" 使用KSOAP2调用WebService 可按如下6步来调用WebService的方法。 1.指定WebService的命名空间和调用的方法名 SoapObject request = new SoapObject(\u0026#34;http://service\u0026#34;, \u0026#34;getName\u0026#34;); SoapObject类的第1个参数表示WebService的命名空间，可以从WSDL文档中找到WebService的命名空间。第2个参数表示要调用的WebService方法名。 2.设置调用方法的参数值，这一步是可选的，如果方法没有参数，可以省略这一步。 request.addProperty(\u0026#34;param1\u0026#34;, \u0026#34;value1\u0026#34;); 要注意的是，addProperty方法的第1个参数虽然表示调用方法的参数名，但该参数值并不一定与服务端的WebService类中的方法参数名一致，只要设置参数的顺序一致即可。 3.生成调用WebService方法的SOAP请求信息。该信息由SoapSerializationEnvelope对象描述 SoapSerializationEnvelope envelope = new SoapSerializationEnvelope(SoapEnvelope.VER11);envelope.bodyOut = request; 创建SoapSerializationEnvelope对象时需要通过SoapSerializationEnvelope类的构造方法设置SOAP协 议的版本号。该版本号需要根据服务端WebService的版本号设置。在创建SoapSerializationEnvelope对象后，不要忘了设置 SoapSerializationEnvelope类的bodyOut属性，该属性的值就是在第1步创建的SoapObject对象。 4.创建HttpTransportSE对象。通过HttpTransportSE类的构造方法可以指定WebService的WSDL文档的URL HttpTransportSE ht =new HttpTransportSE(\u0026#34;http://host:port/xx/SearchProductService?wsdl\u0026#34;); 5.使用call方法调用WebService方法 ht.call(null, envelope); call方法的第1个参数一般为null，第2个参数就是在第3步创建的SoapSerializationEnvelope对象。 6.使用getResponse方法获得WebService方法的返回结果 SoapObject soapObject = (SoapObject) envelope.getResponse(); ","date":"2026-08-25T09:31:17+08:00","permalink":"/p/%E4%BD%BF%E7%94%A8ksoap2%E8%B0%83%E7%94%A8webservice/","title":"使用KSOAP2调用WebService"},{"content":"在线安装1 下载 nginx下载地址：http://nginx.org/download/\nwget http://nginx.org/download/nginx-1.12.2.tar.gz 解压 tar -zxvf nginx.**.tgz\n编译ssl模块需要依赖 yum -y install openssl openssl-devel 编译 ./configure --prefix=/usr/java/nginx-1.12.2 --with-http_stub_status_module --with-http_ssl_module 出现错误 error:the HTTP gzip module requires the zlib library,直接yum安装yum install -y zlib-devel;也可能遇到的是关于pcre的问题,yum install pcre pcre-devel 安装 make\u0026amp;make install 启动 /usr/java/nginx-1.12.2/sbin/nginx -c /usr/java/nginx-1.12.2/conf/nginx.conf 重启 /usr/java/nginx-1.12.2/sbin/nginx -t || /app/nginx/sbin/nginx -t 在线安装2(推荐) 安装 sudo yum install nginx 启动 sudo systemctl restart nginx.service 配置文件在/etc/下 离线安装 (rpm安装nginx) 1.安装步骤： 1.打开rpm文件下载地址：rpm下载 2.选择 nginx-1.20.1-1.el7.ngx.x86_64.rpm 下载 3.命令安装 rpm -ivh nginx-*.rpm 安装完成之后的说明： 1.安装完成之后需要按照习惯将下方3个配置文件中的内容进行修改 2.默认文件位置及内容： 1.二进制文件(exe)：/lib/systemd/system/nginx.service [Unit] Description=nginx - high performance web server Documentation=http://nginx.org/en/docs/ After=network-online.target remote-fs.target nss-lookup.target Wants=network-online.target [Service] Type=forking PIDFile=/opt/nginx/logs/nginx.pid ExecStart=/usr/sbin/nginx -c /etc/nginx/nginx.conf ExecReload=/bin/sh -c \u0026#34;/bin/kill -s HUP $(/bin/cat /opt/nginx/logs/nginx.pid)\u0026#34; ExecStop=/bin/sh -c \u0026#34;/bin/kill -s TERM $(/bin/cat /opt/nginx/logs/nginx.pid)\u0026#34; [Install] WantedBy=multi-user.target 2.服务配置文件: /etc/init.d/nginx #!/bin/sh # # nginx - this script starts and stops the nginx daemon # # chkconfig: - 85 15 # description: NGINX is an HTTP(S) server, HTTP(S) reverse \\ # proxy and IMAP/POP3 proxy server # processname: nginx # config: /etc/nginx/nginx.conf # config: /etc/sysconfig/nginx # pidfile: /var/run/nginx.pid # Source function library. . /etc/rc.d/init.d/functions # Source networking configuration. . /etc/sysconfig/network # Check that networking is up. [ \u0026#34;$NETWORKING\u0026#34; = \u0026#34;no\u0026#34; ] \u0026amp;\u0026amp; exit 0 nginx=\u0026#34;/usr/sbin/nginx\u0026#34; prog=$(basename $nginx) NGINX_CONF_FILE=\u0026#34;/etc/nginx/nginx.conf\u0026#34; [ -f /etc/sysconfig/nginx ] \u0026amp;\u0026amp; . /etc/sysconfig/nginx lockfile=/var/lock/subsys/nginx make_dirs() { # make required directories user=`$nginx -V 2\u0026gt;\u0026amp;1 | grep \u0026#34;configure arguments:\u0026#34; | sed \u0026#39;s/[^*]*--user=\\([^ ]*\\).*/\\1/g\u0026#39; -` if [ -z \u0026#34;`grep $user /etc/passwd`\u0026#34; ]; then useradd -M -s /bin/nologin $user fi options=`$nginx -V 2\u0026gt;\u0026amp;1 | grep \u0026#39;configure arguments:\u0026#39;` for opt in $options; do if [ `echo $opt | grep \u0026#39;.*-temp-path\u0026#39;` ]; then value=`echo $opt | cut -d \u0026#34;=\u0026#34; -f 2` if [ ! -d \u0026#34;$value\u0026#34; ]; then # echo \u0026#34;creating\u0026#34; $value mkdir -p $value \u0026amp;\u0026amp; chown -R $user $value fi fi done } start() { [ -x $nginx ] || exit 5 [ -f $NGINX_CONF_FILE ] || exit 6 make_dirs echo -n $\u0026#34;Starting $prog: \u0026#34; daemon $nginx -c $NGINX_CONF_FILE retval=$? echo [ $retval -eq 0 ] \u0026amp;\u0026amp; touch $lockfile return $retval } stop() { echo -n $\u0026#34;Stopping $prog: \u0026#34; killproc $prog -QUIT retval=$? echo [ $retval -eq 0 ] \u0026amp;\u0026amp; rm -f $lockfile return $retval } restart() { configtest || return $? stop sleep 1 start } reload() { configtest || return $? echo -n $\u0026#34;Reloading $prog: \u0026#34; killproc $nginx -HUP RETVAL=$? echo } force_reload() { restart } configtest() { $nginx -t -c $NGINX_CONF_FILE } rh_status() { status $prog } rh_status_q() { rh_status \u0026gt;/dev/null 2\u0026gt;\u0026amp;1 } case \u0026#34;$1\u0026#34; in start) rh_status_q \u0026amp;\u0026amp; exit 0 $1 ;; stop) rh_status_q || exit 0 $1 ;; restart|configtest) $1 ;; reload) rh_status_q || exit 7 $1 ;; force-reload) force_reload ;; status) rh_status ;; condrestart|try-restart) rh_status_q || exit 0 ;; *) echo $\u0026#34;Usage: $0 {start|stop|status|restart|condrestart|try-restart|reload|force-reload|configtest}\u0026#34; exit 2 esac 3.应用配置文件：/etc/nginx/ 总模块\nuser nginx; worker_processes auto; error_log /opt/nginx/logs/error.log notice; pid /opt/nginx/logs/nginx.pid; events { worker_connections 1024; } http { include /etc/nginx/mime.types; default_type application/octet-stream; log_format main \u0026#39;$remote_addr - $remote_user [$time_local] \u0026#34;$request\u0026#34; \u0026#39; \u0026#39;$status $body_bytes_sent \u0026#34;$http_referer\u0026#34; \u0026#39; \u0026#39;\u0026#34;$http_user_agent\u0026#34; \u0026#34;$http_x_forwarded_for\u0026#34;\u0026#39;; access_log /opt/nginx/logs/access.log main; sendfile on; #tcp_nopush on; keepalive_timeout 65; #gzip on; include /opt/nginx/conf/*.conf; } 80端口\nserver { listen 80; server_name localhost; rewrite ^/(.*)$ https://domain:443/$1 permanent; } 443端口配置\nserver { listen 443 ssl http2; # 1.25.1之后写法 #listen [::]:443 ssl http2; server_name `your servename`; # 开启gz压缩 gzip on; gzip_disable \u0026#34;msie6\u0026#34;; gzip_vary on; gzip_proxied any; gzip_comp_level 8; gzip_buffers 16 8k; gzip_min_length 100; gzip_types text/plain application/javascript application/x-javascript text/css application/xml text/javascript application/x-httpd-php image/jpeg image/gif image/png; # 开启访问验证密码 #auth_basic \u0026#34;nginx basic auth\u0026#34;; #auth_basic_user_file /opt/nginx/nginx/conf/htpasswd; ssl_certificate /opt/nginx/ssl/ssl.pem; #证书地址 ssl_certificate_key /opt/nginx/ssl/ssl.key; #证书地址 ssl_session_cache shared:SSL:1m; ssl_session_timeout 5m; ssl_session_tickets off; ssl_ciphers \u0026#39;EECDH+AESGCM:EDH+AESGCM:AES256+EECDH:AES256+EDH\u0026#39;; ssl_prefer_server_ciphers on; ssl_protocols TLSv1.2 TLSv1.3; # 访问时不验证证书 ssl_stapling on; ssl_stapling_verify on; ssl_trusted_certificate /opt/nginx/ssl/ssl.pem; resolver 8.8.8.8 8.8.4.4 valid=300s; resolver_timeout 5s; ssl_buffer_size 4k; location / { root /opt/nginx/html/web_front/; index index.html index.htm; if (!-e $request_filename) { rewrite ^(.*)$ /index.html?s=$1 last; break; } } location /admin/ { alias /opt/nginx/html/admin_front/; index index.html index.htm; if (!-e $request_filename) { rewrite ^(.*)$ /index.html?s=$1 last; break; } } location ^~ /gg/ { client_max_body_size 50m; proxy_pass http://ip:port/gg/; proxy_set_header Host 127.0.0.1:80; proxy_set_header X-Real-IP $remote_addr; proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; } include other/*.conf; } 微信域名验证\nlocation ~ /WW_verify_(.*)\\.txt{ default_type text/html; return 200 $1; } 权限设置 chmod a+x /etc/init.d/nginx\n设置开机自启 chkconfig --add /etc/init.d/nginx chkconfig nginx on nginx服务命令 systemctl daemon-reload systemctl start nginx systemctl status nginx rpm命令\n查看安装依赖rpm -qa|grep nginx 卸载依赖rpm -e nginx\n","date":"2026-08-25T09:31:12+08:00","permalink":"/p/linux%E5%AE%89%E8%A3%85nginx/","title":"linux安装Nginx"},{"content":"在线安装 1.wget下载 下载 wget http://download.redis.io/releases/redis-6.0.8.tar.gz 解压 tar xzf redis-6.0.8.tar.gz 编译 (会需要gcc，如果版本不匹配会报错) cd redis-6.0.8 make 执行完 make 命令后，redis-6.0.8 的 src 目录下会出现编译后的 redis 服务程序 redis-server，还有用于测试的客户端程序 redis-cli： 启动 redis 服务： cd src ./redis-server 这种方式启动 redis 使用的是默认配置。也可以通过启动参数告诉 redis 使用指定配置文件使用下面命令启动。 cd src ./redis-server ../redis.conf redis.conf 是一个默认的配置文件。我们可以根据需要使用自己的配置文件。 启动 redis 服务进程后，就可以使用测试客户端程序 redis-cli 和 redis 服务交互了。 比如： cd src ./redis-cli -a 12345678 # 指定ip和端口连接 # redis-cli -h 127.0.0.1 -p 6380 -a \u0026#34;password\u0026#34; redis\u0026gt; set foo bar OK redis\u0026gt; get foo \u0026#34;bar\u0026#34; ","date":"2026-08-25T09:31:05+08:00","permalink":"/p/linux%E5%AE%89%E8%A3%85redis/","title":"linux安装Redis"},{"content":"在线安装1 1.查看是否安装 rpm -qa|grep mysql #无输出说明没有安装 2.下载地址 https://dev.mysql.com/downloads/repo/yum/ 3.下载和安装mysql源 wget https://dev.mysql.com/get/mysql80-community-release-el7-3.noarch.rpm # 压缩包 wget https://cdn.mysql.com//Downloads/MySQL-8.0/mysql-8.0.28-linux-glibc2.12-x86_64.tar 如果显示wget未找到命令，则需要先安装wget：yum -y install wget 然后再次执行上面命令 4.安装mysql源 sudo rpm -Uvh mysql80-community-release-el7-3.noarch.rpm 执行成功后会在/etc/yum.repos.d/目录下生成两个repo文件mysql-community.repo及 mysql-community-source.repo 若 出现 gpk 编辑文件/etc/yum.repos.d/mysql-community.repo 修改gpgkey=0 5.安装mysql sudo yum install mysql-community-server 安装之后配置文件在 /etc/my.cnf || vim /etc/my.cnf 8.0以上 首先设置表名忽略大小写 lower_case_table_names=1 跳过密码认证 skip-grant-tables = true 当出现 错误 ：The MySQL server is running with the --skip-grant-tables option so it cannot execute this statement 时,使用 flush privileges; 刷新数据库权限之后再修改密码 6.启动 启动：systemctl start mysqld.service 状态：systemctl status mysqld.service 停止：systemctl stop mysqld.service 重启：systemctl restart mysqld.service 查看端口：show global variables like \u0026lsquo;port\u0026rsquo;; 修改默认端口： #1、编辑/etc/my.cnf文件 vim /etc/my.cnf #2、添加port=2032; #3、重启mysql [root@localhost ~]# /etc/init.d/mysqld restart 7.修改密码及登录 MySQL第一次启动后会创建超级管理员账号root@localhost，初始密码存储在日志文件中 grep 'temporary password' /var/log/mysqld.log 修改默认密码 1.进行登录 mysql -uroot -p 2.修改密码：ALTER USER 'root'@'localhost' IDENTIFIED BY '123456'; 3.若修改出现错误，8.0以上设置密码复杂度为简单规则 set global validate_password.policy=0; set global validate_password.length=1; 之后修改密码ALTER USER 'root'@'localhost' IDENTIFIED WITH mysql_native_password BY '12345678'; 。最后FLUSH PRIVILEGES; #刷新权限\n8.查看编码 mysql\u0026gt; SHOW VARIABLES LIKE 'character%';\n设置编码 编辑/etc/my.cnf，[mysqld]节点增加以下代码 [mysqld] character_set_server=utf8 init-connect=\u0026#39;SET NAMES utf8\u0026#39; 9.允许远程登录（进入mysql命令行） use mysql; select host,user from user where user=\u0026#39;root\u0026#39;; update user set host = \u0026#39;%\u0026#39; where user=\u0026#39;root\u0026#39;; flush privileges; 设置开机自启systemctl enable mysqld 10.删除mysql(强迫症) 1.检查是否有mariadbrpm -qa|grep mariadb 2.删除mariadb rpm -e --nodeps mariadb-server rpm -e --nodeps mariadb rpm -e --nodeps mariadb-libs 3.检查mysqlrpm -qa|grep mysql 4.删除mysql依赖rpm -e --nodeps xxx ","date":"2026-08-25T09:30:37+08:00","permalink":"/p/linux%E5%AE%89%E8%A3%85mysql/","title":"linux安装Mysql"},{"content":"离线安装 1.官网下载jdk1.8： https://www.oracle.com/java/technologies/javase/javase-jdk8-downloads.html 2.创建文件夹 mkdir /usr/java/ 3.用rz命令将 jdk-8u144-linux-x64.tar.gz 文件上传到该目录下 tar -zxvf jdk-8u144-linux-x64.tar.gz 4.配置环境变量: vim /etc/profile # 最后一行添加 export JAVA_HOME=/usr/java/jdk1.8.0 export PATH=$JAVA_HOME/bin:$PATH export CLASSPATH=.:$JAVA_HOME/lib/dt.jar:$JAVA_HOME/lib/tools.jar 5.刷新环境变量 source /etc/profile 6.检查一下是否安装成功 java -version 出现了一个PATH错误问题,尝试修复 # 输入此命令来保证命令行命令可以暂时使用： export PATH=/usr/bin:/usr/sbin:/bin:/sbin:/usr/X11R6/bin # 输入命令进入环境变量配置文件中进行修改： vi ~/.bash_profile # 改正错误并执行\u0026#34;：wq\u0026#34; # 使配置生效： source ~/.bash_profile # 添加*.sh 命令权限 chmod u+x *.sh 在线安装 yum install java-1.8.0-openjdk-devel.x86_64 yum remove java-1.8.0-openjdk-devel.x86_64 ","date":"2026-08-25T09:30:33+08:00","permalink":"/p/linux%E5%AE%89%E8%A3%85jdk%E5%9C%A8%E7%BA%BF%E7%A6%BB%E7%BA%BF/","title":"linux安装jdk(在线、离线)"},{"content":"出现错误提示：\nError: could not open `C:\\Program Files\\Java\\jre7\\lib\\i386\\jvm.cfg\u0026#39; 修复过程： 清理注册表和缓存之后，仍然报错，重启也没用。\n直接删除system32中的3个java*.exe文件,在CMD中就正常了\nc:/windows/system32/java.exe c:/windows/system32/javaw.exe c:/windows/system32/javaws.exe ","date":"2026-08-25T09:30:28+08:00","permalink":"/p/jdk%E7%8E%AF%E5%A2%83%E5%8F%98%E9%87%8F%E7%BC%93%E5%AD%98%E9%97%AE%E9%A2%98/","title":"jdk环境变量缓存问题"},{"content":"1.jimmer-apt 2.jimmer-client 3.jimmer-core 4.jimmer-core-kotlin （kotlin） 5.jimmer-dto-complier (java+antlr) 6.jimmer-ksp（kotlin） 7.jimmer-mapstruct-apt 8.jimmer-spring-starter 9.jimmer-sql (java+antlr) 10.jimmer-sql-kotlin（kotlin） 一、 xxxRepository.findNullable()\n","date":"2026-08-25T09:30:22+08:00","permalink":"/p/jimmer%E5%AD%A6%E4%B9%A0/","title":"Jimmer学习"},{"content":"直接使用参数\n\u0026lt;?xml version=\u0026#34;1.0\u0026#34; encoding=\u0026#34;utf-8\u0026#34;?\u0026gt; \u0026lt;soap:Envelope xmlns:xsi=\u0026#34;http://www.w3.org/2001/XMLSchema-instance\u0026#34; xmlns:xsd=\u0026#34;http://www.w3.org/2001/XMLSchema\u0026#34; xmlns:soap=\u0026#34;http://schemas.xmlsoap.org/soap/envelope/\u0026#34;\u0026gt; \u0026lt;soap:Body\u0026gt; \u0026lt;getPermissionByPermid xmlns:n0=\u0026#34;http://service.rest2.cms.jeecms.com/\u0026#34;\u0026gt; \u0026lt;param\u0026gt;{PERMID: \u0026#34;005366933XK58121001\u0026#34;}\u0026lt;/param\u0026gt; \u0026lt;/getPermissionByPermid\u0026gt; \u0026lt;/soap:Body\u0026gt; \u0026lt;/soap:Envelope\u0026gt; ","date":"2026-08-25T09:30:17+08:00","permalink":"/p/postman-%E5%8F%91%E9%80%81webservice/","title":"postman 发送WebService"},{"content":"var timestamp=Math.round(new Date().getTime()); var app_key=\u0026#34;key\u0026#34;; var secretKey=\u0026#34;key\u0026#34;; //使用MD5加密 var str=secretKey+timestamp; var strmd5 = CryptoJS.MD5(str); var sign=strmd5; var url=\u0026#34;http://host:port/xxx/get-token?\u0026#34;+\u0026#34;timestamp=\u0026#34;+timestamp+\u0026#34;\u0026amp;app_key=\u0026#34;+app_key+\u0026#34;\u0026amp;sign=\u0026#34;+strmd5; pm.sendRequest(url,function(error,res){ if(res){ var token=res.json().access_token; pm.request.headers.add({ key: \u0026#39;Authorization\u0026#39;, value: \u0026#39;Basic \u0026#39;+token }); } }) ","date":"2026-08-25T09:30:12+08:00","permalink":"/p/postman-pre%E9%A2%84%E5%A4%84%E7%90%86%E8%AE%BE%E7%BD%AEtoken%E8%AF%B7%E6%B1%82%E5%A4%B4/","title":"postman pre预处理设置token请求头"},{"content":"1.将fork的项目克隆到本地 git clone https://******* 2.进入克隆的git项目文件中，将官方地址作为远程仓库 git remote add 项目名称 https://****** 3.查看是否成功 git remote -v # 成功显示 项目名称 https://******(fetch) 项目名称 https://******(push) 4.从远程获取所有更新 git fetch 项目名称 5.确保分支在master git rebase 项目名称/master 6.将记录推送到自己的远程仓库地址 git push -f origin master ","date":"2026-08-25T09:29:46+08:00","permalink":"/p/%E5%9C%A8github%E4%B8%8Afork%E9%A1%B9%E7%9B%AE%E5%90%8E%E5%A6%82%E4%BD%95%E4%B8%8E%E5%8E%9F%E4%BB%93%E5%BA%93%E5%90%8C%E6%AD%A5/","title":"在GitHub上fork项目后，如何与原仓库同步"},{"content":"1.引入依赖 \u0026lt;dependency\u0026gt; \u0026lt;groupId\u0026gt;io.debezium\u0026lt;/groupId\u0026gt; \u0026lt;artifactId\u0026gt;debezium-api\u0026lt;/artifactId\u0026gt; \u0026lt;version\u0026gt;1.5.2.Final\u0026lt;/version\u0026gt; \u0026lt;/dependency\u0026gt; \u0026lt;dependency\u0026gt; \u0026lt;groupId\u0026gt;io.debezium\u0026lt;/groupId\u0026gt; \u0026lt;artifactId\u0026gt;debezium-embedded\u0026lt;/artifactId\u0026gt; \u0026lt;version\u0026gt;1.5.2.Final\u0026lt;/version\u0026gt; \u0026lt;/dependency\u0026gt; \u0026lt;dependency\u0026gt; \u0026lt;groupId\u0026gt;io.debezium\u0026lt;/groupId\u0026gt; \u0026lt;artifactId\u0026gt;debezium-connector-mysql\u0026lt;/artifactId\u0026gt; \u0026lt;version\u0026gt;1.5.2.Final\u0026lt;/version\u0026gt; \u0026lt;/dependency\u0026gt; 2.java配置 /** * debezium 配置 * @return */ @Bean public io.debezium.config.Configuration testConnector(){ return io.debezium.config.Configuration.create() // 连接器的唯一名称 .with(\u0026#34;name\u0026#34;, \u0026#34;test-mysql-connector\u0026#34;) // 连接器的 Java 类的名称 Mysql连接器 .with(\u0026#34;connector.class\u0026#34;, \u0026#34;io.debezium.connector.mysql.MySqlConnector\u0026#34;) // MySQL 数据库服务器的 IP 地址或主机名。 .with(\u0026#34;database.hostname\u0026#34;, \u0026#34;127.0.0.1\u0026#34;) // MySQL 数据库服务器的整数端口号 .with(\u0026#34;database.port\u0026#34;, \u0026#34;3306\u0026#34;) // 连接到 MySQL 数据库服务器时要使用的 MySQL 用户的名称 .with(\u0026#34;database.user\u0026#34;, \u0026#34;root\u0026#34;) // 连接到 MySQL 数据库服务器时使用的密码 .with(\u0026#34;database.password\u0026#34;,\u0026#34;123456\u0026#34;) // 标识并为Debezium捕获更改的特定MySQL数据库服务器/集群提供命名空间的逻辑名称。 // 逻辑名称在所有其他连接器中应该是唯一的，因为它用作所有接收此连接器发出的事件的Kafka // 主题名称的前缀。此名称中只允许使用字母数字字符和下划线 .with(\u0026#34;database.server.name\u0026#34;,\u0026#34;test_001\u0026#34;) // 此数据库客户端的数字 ID，在 MySQL 集群中所有当前运行的数据库进程中必须是唯一的。 // 此连接器作为另一台服务器（具有此唯一 ID）加入 MySQL 数据库集群， // 以便它可以读取 binlog。默认情况下，会生成 5400 到 6400 之间的随机数， // 但建议明确设置一个值 .with(\u0026#34;database.server.id\u0026#34;, \u0026#34;5400\u0026#34;) .build(); } 3.实例化Debezium Engine private void handlePayload(List\u0026lt;RecordChangeEvent\u0026lt;SourceRecord\u0026gt;\u0026gt; recordChangeEvents, DebeziumEngine.RecordCommitter\u0026lt;RecordChangeEvent\u0026lt;SourceRecord\u0026gt;\u0026gt; recordCommitter) { recordChangeEvents.forEach(r -\u0026gt; { SourceRecord sourceRecord = r.record(); Struct sourceRecordChangeValue = (Struct) sourceRecord.value(); if (sourceRecordChangeValue != null) { // 判断操作的类型 过滤掉读 只处理增删改 这个其实可以在配置中设置 Envelope.Operation operation = Envelope.Operation.forCode((String) sourceRecordChangeValue.get(OPERATION)); if (operation != Envelope.Operation.READ) { String record = operation == Envelope.Operation.DELETE ? BEFORE : AFTER; // 获取增删改对应的结构体数据 Struct struct = (Struct) sourceRecordChangeValue.get(record); // 将变更的行封装为Map Map\u0026lt;String, Object\u0026gt; payload = struct.schema().fields().stream() .map(Field::name) .filter(fieldName -\u0026gt; struct.get(fieldName) != null) .map(fieldName -\u0026gt; Pair.of(fieldName, struct.get(fieldName))) .collect(toMap(Pair::getKey, Pair::getValue)); // 这里简单打印一下 System.out.println(\u0026#34;payload = \u0026#34; + payload); } } }); } ","date":"2026-08-25T09:29:41+08:00","permalink":"/p/springboot%E9%9B%86%E6%88%90debezium%E5%AE%9E%E6%97%B6%E7%9B%91%E6%8E%A7%E6%95%B0%E6%8D%AE%E5%BA%93%E5%8F%98%E5%8C%96/","title":"springboot集成debezium实时监控数据库变化"},{"content":"1.数据库删除重复数据 delete from 表名 a where a.rowid != ( select max(b.rowid) from 表名 b where a.字段1 = b.字段1 and a.字段2 = b.字段2 ) 2.通过dual查询(使用函数) select 7 from dual; 3.获取32位UUID SELECT REPLACE(uuid(), \u0026#39;-\u0026#39;, \u0026#39;\u0026#39;); ","date":"2026-08-25T09:29:36+08:00","permalink":"/p/oracle%E6%95%B0%E6%8D%AE%E5%BA%93%E6%93%8D%E4%BD%9C/","title":"ORACLE数据库操作"},{"content":"排除vue中引入的js，使用cdn加载\n// 排除打包，cdn加载 config.set(\u0026#39;externals\u0026#39;,{ Vue:\u0026#39;Vue\u0026#39;, \u0026#39;vue-router\u0026#39;:\u0026#39;VueRouter\u0026#39;, axios:\u0026#39;axios\u0026#39;, \u0026#39;vuex\u0026#39;:\u0026#39;Vuex\u0026#39;, }) // 依赖包名：对象名称 \u0026lt;script src=\u0026#34;https://cdn.bootcdn.net/ajax/libs/vue/2.6.10/vue.min.js\u0026#34;\u0026gt;\u0026lt;/script\u0026gt; \u0026lt;script src=\u0026#34;https://cdn.bootcdn.net/ajax/libs/vue-router/3.0.1/vue-router.min.js\u0026#34;\u0026gt;\u0026lt;/script\u0026gt; \u0026lt;script src=\u0026#34;https://cdn.bootcdn.net/ajax/libs/axios/1.6.3/axios.min.js\u0026#34;\u0026gt;\u0026lt;/script\u0026gt; ","date":"2026-08-25T09:29:31+08:00","permalink":"/p/%E6%8E%92%E9%99%A4vue%E4%B8%AD%E5%BC%95%E5%85%A5%E7%9A%84js%E4%BD%BF%E7%94%A8cdn%E5%8A%A0%E8%BD%BD/","title":"排除vue中引入的js，使用cdn加载"},{"content":"使用vue页面数据加载时出现{{}}代码片段\n\u0026lt;!--解决初次加载页面时会出现{{}}代码问题--\u0026gt; \u0026lt;!-- 第一步 定义CSS--\u0026gt; \u0026lt;style type=\u0026#34;text/css\u0026#34;\u0026gt; [v-cloak] { display: none; } \u0026lt;/style\u0026gt; \u0026lt;!-- 第二步 在vue上添加标签--\u0026gt; \u0026lt;div id=\u0026#34;app\u0026#34; v-cloak\u0026gt; ","date":"2026-08-25T09:29:25+08:00","permalink":"/p/%E4%BD%BF%E7%94%A8vue%E9%A1%B5%E9%9D%A2%E6%95%B0%E6%8D%AE%E5%8A%A0%E8%BD%BD%E6%97%B6%E5%87%BA%E7%8E%B0%E4%BB%A3%E7%A0%81%E7%89%87%E6%AE%B5/","title":"使用vue页面数据加载时出现{{}}代码片段"},{"content":"手机端使用console日志记录\n\u0026lt;script src=\u0026#34;https://unpkg.com/vconsole/dist/vconsole.min.js\u0026#34;\u0026gt;\u0026lt;/script\u0026gt; \u0026lt;script\u0026gt; // VConsole will be exported to `window.VConsole` by default. var vConsole = new window.VConsole(); \u0026lt;/script\u0026gt; d.min.css\u0026#34;\u0026gt;\u0026lt;/script\u0026gt; \u0026lt;script src=\u0026#34;https://cdn.bootcdn.net/ajax/libs/vuex/3.1.0/vuex.min.js\u0026#34;\u0026gt;\u0026lt;/script\u0026gt; \u0026lt;script src=\u0026#34;https://cdn.bootcdn.net/ajax/libs/jsoneditor/9.0.0/jsoneditor.min.js\u0026#34;\u0026gt;\u0026lt;/script\u0026gt; \u0026lt;script src=\u0026#34;https://cdn.bootcdn.net/ajax/libs/jsoneditor/9.0.0/jsoneditor.min.css\u0026#34;\u0026gt;\u0026lt;/script\u0026gt; ","date":"2026-08-25T09:29:18+08:00","permalink":"/p/%E6%89%8B%E6%9C%BA%E7%AB%AF%E4%BD%BF%E7%94%A8console%E6%97%A5%E5%BF%97%E8%AE%B0%E5%BD%95/","title":"手机端使用console日志记录"},{"content":"第一步、安装依赖 npm install jszip file-saver 第二步、引入方法： import JSZip from\u0026#39;jszip\u0026#39; import FileSaver from\u0026#39;file-saver\u0026#39; 第三步、按钮点击方法 downLoadUrl对象属性： file:下载链接 type： 文件类型\n2.依赖方法\ngetFile(url){ return new Promise((resolve, reject) =\u0026gt; { this.axios({ method:\u0026#39;get\u0026#39;, url, responseType: \u0026#39;blob\u0026#39; }).then(data =\u0026gt; { resolve(data) }).catch(error =\u0026gt; { reject(error.toString()) }) }) }, // 打压缩包下载 ## dataUrl:[{url,file_name}] handleBatchDownload(dataUrl) { let _this = this; const zip = new JSZip() // 创建一个JSZip实例 const cache = {} const promises = [] dataUrl.forEach(item =\u0026gt; { const promise = _this.getFile(item.url).then(data =\u0026gt; { // 下载文件, 并存成ArrayBuffer对象 let file_name = item.file_name // 获取文件名（数组最后一项） zip.file(file_name, data, { binary: true }) // 逐个添加文件 cache[file_name] = data }) promises.push(promise) }) Promise.all(promises).then(() =\u0026gt; { zip.generateAsync({type:\u0026#34;blob\u0026#34;}).then(content =\u0026gt; { // 生成二进制流 // 利用file-saver保存文件 _this.fileTableTitle是我压缩包名字 FileSaver.saveAs(content, _this.title + \u0026#34;.zip\u0026#34;) }) }) } } ","date":"2026-08-25T09:29:13+08:00","permalink":"/p/js%E6%89%B9%E9%87%8F%E6%89%93%E5%8C%85%E4%B8%8B%E8%BD%BD/","title":"js批量打包下载"},{"content":"python打包exe # 1.安装依赖 pip install pyinstaller # 2.在创建好的项目下输入命令 pyinstaller -F love.py #生成3个文件：build,dist和love.spec,dist文件夹下就会有love.exe可执行文件 #3.修改程序图标（项目路径下） pyinstaller -F -i lover.ico love.py 使用python搭建简单的文件局域共享 python -m http.server 9999 ","date":"2026-08-25T09:29:09+08:00","permalink":"/p/python%E5%8A%9F%E8%83%BD/","title":"python功能"},{"content":"# 添加远程分支 call git remote add jeecg https://gitee.com/jeecg/jeecg-boot.git # 拉取远程分支 call git fetch jeecg # 合并远程分 call git merge jeecg/master --allow-unrelated-histories # 推送记录到目的分支 call git push -f origin master ","date":"2026-08-25T09:28:43+08:00","permalink":"/p/git%E6%8B%89%E5%8F%96%E5%90%88%E5%B9%B6%E5%AE%98%E6%96%B9%E4%BB%A3%E7%A0%81/","title":"git拉取合并官方代码"},{"content":"1.防火墙 # 查看转态 systemctl status firewalld || firewall-cmd --state # 开启防火墙 systemctl start firewalld || service iptables start # 关闭 service firewalld stop || service iptables start #防火墙重启： firewall-cmd --reload || service iptables restart #查看防火墙规则 firewall-cmd --list-all || iptables -L -n #查看防火墙开放端口： firewall-cmd --list-ports #查询80端口是否开放： firewall-cmd --query-port=80/tcp #开放80端口： firewall-cmd --zone=public --add-port=80/tcp --permanent 2.软连接 将某个目录链接至系统目录，相当于快捷方式加环境变量：\nln -s /usr/local/mysql/bin/mysql /usr/bin　3.查看端口 查看当前所有tcp端口 netstat -ntlp 查看所有1935端口使用情况 netstat -ntulp |grep 1935 根据端口号查进程 pidlsof -i:portnetstat -nap|grep port 根据进程号查端口 netstat -nap|grep pid 4.服务状态(systemctl) vim /usr/lib/systemd/system/app.service # 编辑app服务的配置文件 systemctl daemon-reload # 重新加载服务的配置文件 systemctl start app # 启动app服务 systemctl status app # 查看app服务状态 systemctl enable app # 开机自启动 app systemctl disable app # 关闭开机自启动 app systemctl list-unit-files --type=service | grep enabled # 列出所有开机自启动的服务 5.生成jump日志文件 jmap -histo $PID \u0026gt; 2025.dump jmap -histo 1993577 \u0026gt; 2025.dump ","date":"2026-08-25T09:28:37+08:00","permalink":"/p/linux%E5%91%BD%E4%BB%A4%E5%90%88%E9%9B%86/","title":"linux命令合集"},{"content":"1.npm指定全局依赖安装路径 npm config set prefix \u0026#34;盘符:\\安装路径主目录\\node_global\u0026#34; npm config set cache \u0026#34;盘符:\\安装路径主目录\\node_cache\u0026#34; 2.npm版本依赖问题 查看某个modules的版本信息\nnpm view less-loader versions 查看某个modules所需要的依赖及其版本：\nnpm view less-loader@4.1.0 peerDependencies 3.openssl不兼容问题 set NODE_OPTIONS=--openssl-legacy-provider \u0026amp;\u0026amp; serve(| build) # set NODE_OPTIONS=--openssl-legacy-provider \u0026amp;\u0026amp; vue-cli-service serve ","date":"2026-08-25T09:28:32+08:00","permalink":"/p/node%E5%B8%B8%E7%94%A8%E5%91%BD%E4%BB%A4%E9%9B%86%E5%90%88/","title":"node常用命令集合"},{"content":"1. 批量插入 将一个表删除的数据插入到另一个表（备份）\ninsert into table_name_back select * from table_name a where a.id= ?; delete from table_name a where a.id= ? ; 从一个表获取数据，向另一个表插入数据，能够解决数据的重复问题\ninsert INTO test_demo (id,name) select distinct table_id,id from act_z_business -- 要插入的数据集 on duplicate key update create_by = \u0026#39;test\u0026#39;; 2. 查询重复数据 查询表中某一个字段的值相同的数据集\nselect id,`name`,count(1) as c from TABLE_NAME GROUP BY `name` HAVING c\u0026gt; 1 3. 批量修改Mysql表的字符集 SELECT CONCAT( \u0026#39;ALTER TABLE \u0026#39;, TABLE_NAME, \u0026#39; CONVERT TO CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci;\u0026#39; ) FROM information_schema.`TABLES` WHERE TABLE_SCHEMA = \u0026#39;mysql\u0026#39;; // TABLE_SCHEMA = \u0026#39;mysql\u0026#39; 4. 批量修改Mysql表字段的字符集 SELECT TABLE_SCHEMA \u0026#39;数据库\u0026#39;, TABLE_NAME \u0026#39;表\u0026#39;, COLUMN_NAME \u0026#39;字段\u0026#39;, CHARACTER_SET_NAME \u0026#39;原字符集\u0026#39;, COLLATION_NAME \u0026#39;原排序规则\u0026#39;, CONCAT( \u0026#39;ALTER TABLE `\u0026#39;, TABLE_SCHEMA, \u0026#39;`.`\u0026#39;, TABLE_NAME, \u0026#39;` MODIFY COLUMN `\u0026#39;, COLUMN_NAME, \u0026#39;` \u0026#39;, COLUMN_TYPE, \u0026#39; CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci;\u0026#39; ) \u0026#39;修正SQL\u0026#39; FROM information_schema.`COLUMNS` WHERE TABLE_SCHEMA RLIKE \u0026#39;DATABASE_NAME\u0026#39; and CHARACTER_SET_NAME is not null and (CHARACTER_SET_NAME != \u0026#39;utf8mb4\u0026#39; or COLLATION_NAME != \u0026#39;utf8mb4_general_ci\u0026#39;); 5.查询表所有字段 select column_name from information_schema.columns where table_schema=\u0026#39;DATABASE_NAME\u0026#39; and table_name=\u0026#39;TABLE_NAME\u0026#39;; 6.向表添加字段 在字段 field之后添加 IDS 字段\nALTER TABLE TABLE_NAME ADD COLUMN IDS int(11) DEFAULT NULL COMMENT \u0026#39;主键\u0026#39; AFTER field; 7.重新分析表索引 ANALYZE table test table_name; ANALYZE table test_11; 8.给角色加权限 CREATE USER canal IDENTIFIED BY \u0026#39;root\u0026#39;; GRANT SELECT, REPLICATION SLAVE, REPLICATION CLIENT ON *.* TO \u0026#39;root\u0026#39;@\u0026#39;%\u0026#39;; FLUSH PRIVILEGES; 9.sql_model修改 sql_mode=STRICT_TRANS_TABLES,NO_ZERO_IN_DATE,NO_ZERO_DATE,ERROR_FOR_DIVISION_BY_ZERO,NO_ENGINE_SUBSTITUTION 10.添加虚拟列(使用索引) # 1. 根据实体列的值创建一个虚拟列 ALTER TABLE `table_name` ; ADD COLUMN `field_name` CHAR(1) GENERATED ALWAYS AS (SUBSTR(projid, 16, 1)) STORED; # 2. 添加虚拟列索引 CREATE INDEX idx_field_name ON 表名(field_name); # 3. 查询索引 SELECT * FROM 表名 WHERE field_name = \u0026#39;A\u0026#39;; 11.查询锁表(block)进程并停止 select * from information_schema.INNODB_TRX; KILL 30009; 12.关闭事务自动提交(测试并发锁表) SHOW VARIABLES LIKE \u0026#39;autocommit\u0026#39;; SET autocommit = 0; select * from dec_declare_projid where unid = \u0026#39;410296008250910\u0026#39; for update; commit; ","date":"2026-08-25T09:28:26+08:00","permalink":"/p/mysql%E4%B8%9A%E5%8A%A1%E5%9C%BA%E6%99%AF%E5%A4%84%E7%90%86/","title":"MySql业务场景处理"},{"content":"1. 锁表场景 关闭死锁状态下的sessions\nSP_CLOSE_SESSION( SELECT distinct sess_id FROM V$sessions c left join v$lock l on l.trx_id = c.trx_id WHERE c.state = \u0026#39;ACTIVE\u0026#39; -- and c.name = \u0026#39;table_name\u0026#39; -- 某个表名称 LIMIT 0,1 ); SELECT * FROM V$sessions c WHERE trx_id IN (SELECT trx_id FROM v$lock ) AND c.state = \u0026#39;ACTIVE\u0026#39; 2.MERGE INTO 批量插入 能够解决主键冲突问题\nMERGE INTO TABLE_NAME1 T1 USING ( SELECT field1,field2 FROM TABLE_NAME2 LIMIT 0,100 ) T2 ON (T1.id = T2.id) -- 要插入的数据集 WHEN NOT MATCHED THEN -- 不重复时插入操作 INSERT(\u0026#39;field\u0026#39;,\u0026#39;field\u0026#39;) VALUES (T2.field1,field2) WHEN MATCHED THEN UPDATE SET T1.createtime = \u0026#39;\u0026#39;; -- 重复时随便给一个字段设置一个值，相当于更新 COMMIT; 3.达梦数据库linux磁盘分区挂载 # 查看磁盘分区情况 fdisk -l 4.设置数据库兼容格式(语法) select para_name,para_value,para_type from v$dm_ini where para_name=\u0026#39;COMPATIBLE_MODE\u0026#39;; -- 默认 para_value= 0:不兼容 -- 参数的方法：sp_set_para_value(范围，参数名称，参数值); -- 版本 8.1.3.37 以上 可以兼容反引号 sp_set_para_value(2,\u0026#39;COMPATIBLE_MODE\u0026#39;,4); 一、创建挂载点 mkdir /opt/dmdbms mkdir /dmdata mkdir /dmarch mkdir /dmbak mkdir /dmbak/dmcore 二、创建分区 pvcreate /dev/vdb vgcreate vg_dm /dev/vdb lvcreate -n vg_dmdbms -L 200G vg_dm lvcreate -n vg_dmdata -L 900G vg_dm lvcreate -n vg_dmarch -L 300G vg_dm lvcreate -n vg_dmbak -L 500G vg_dm lvcreate -n vg_dmcore -l 100%FREE vg_dm 三、格式化分区 mkfs.ext4 /dev/mapper/vg_dm-vg_dmdbms mkfs.ext4 /dev/mapper/vg_dm-vg_dmdata mkfs.ext4 /dev/mapper/vg_dm-vg_dmarch mkfs.ext4 /dev/mapper/vg_dm-vg_dmbak mkfs.ext4 /dev/mapper/vg_dm-vg_dmcore 四、挂载 mount /dev/mapper/vg_dm-vg_dmdbms /opt/dmdbms mount /dev/mapper/vg_dm-vg_dmdata /dmdata mount /dev/mapper/vg_dm-vg_dmarch /dmarch mount /dev/mapper/vg_dm-vg_dmbak /dmbak mount /dev/mapper/vg_dm-vg_dmcore /dmbak/dmcore 五、配置启动自动挂载 # 1.查看对应 id blkid # 2. 修改重启自动挂载配置 vim /etc/fstab UUID=b65a7a30-21b1-437f-b35d-ecb83f523f27 /dmdata ext4 defaults 0 0 UUID=a8312bca-961d-4dbb-b8f4-279b078dd41a /dmarch ext4 defaults 0 0 UUID=42bf3bd2-f4fe-4b2d-bf17-859d254dcade /dmbak ext4 defaults 0 0 UUID=044b17e1-d172-4918-acea-9e526a80ae64 /dmbak/dmcore ext4 defaults 0 0 UUID=57ba491a-d4a0-482c-83bf-dd10c28c5649 /opt/dmdbms ext4 defaults 0 0 六、磁盘扩容、删减 lvreduce -L 500G -f -r /dev/mapper/vg_dm-vg_dmbak #删减 lvreduce -L 900G -f -r /dev/mapper/vg_dm-vg_dmdata #删减 lvextend -L -500G /dev/mapper/vg_dm-vg_dmbak #扩容 lvextend -L +400G /dev/mapper/vg_dm-vg_dmdata #扩容 ","date":"2026-08-25T09:28:07+08:00","permalink":"/p/%E8%BE%BE%E6%A2%A6%E6%95%B0%E6%8D%AE%E5%BA%93%E4%B8%9A%E5%8A%A1%E5%9C%BA%E6%99%AF%E5%A4%84%E7%90%86/","title":"达梦数据库业务场景处理"},{"content":"idea在线激活码地址\n1.进入页面选择一个地址，下载激活工具，将config-jetbrains 、plugins-jetbrains 修改为config、plugins；\n2.修改idea64.exe.vmoptions，添加命令(不要中文/如果使用scripts/install-all-users.vbs,可以忽略此步骤) ：\n--add-opens=java.base/jdk.internal.org.objectweb.asm=ALL-UNNAMED --add-opens=java.base/jdk.internal.org.objectweb.asm.tree=ALL-UNNAMED -javaagent:D:\\文件路径\\ja-netfilter-all\\ja-netfilter.jar 3.复制网页上对应软件的激活码；\n4.启动软件之后选择激活码激活，将复制的激活码填写到对应的窗口中。\n","date":"2026-08-25T09:27:40+08:00","permalink":"/p/idea%E5%B7%A5%E5%85%B7%E5%9C%A8%E7%BA%BF%E6%BF%80%E6%B4%BB%E6%AD%A5%E9%AA%A4/","title":"IDEA工具在线激活步骤"},{"content":"1.获取ip ipconfig 2.获取MAC getmac || ipconf all 3.获取cpu序列号 wmic CPU get ProcessorID 4.获取主板序列 wmic baseboard get serialnumber 5.查询端口占用 netstat -ano 6.开机自启 # 一、WIN+R cmd窗口 shell:startup # 二、将快捷命令放入，开机自动启动 7.重置网络状态 netsh winsock reset 8.端口转发 ## 添加一个端口转发 netsh interface portproxy add v4tov4 listenaddress=127.0.0.1 listenport=6379 \\ connectaddress=192.168.1.1 connectport=6379 # 查看端口转发 netsh interface portproxy show all #删除端口转发 netsh interface portproxy delete v4tov4 listenaddress=127.0.0.1 listenport=6379 ","date":"2026-08-25T09:26:57+08:00","permalink":"/p/windows%E5%B8%B8%E7%94%A8%E5%91%BD%E4%BB%A4/","title":"Windows常用命令"},{"content":"在CentOS 7使用yum下载报错，源地址错误问题\nCould not retrieve mirrorlist http://mirrorlist.centos.org/?release=7\u0026amp;arch= 问题原因 出现这个错误是因为使用的 CentOS 7 仓库已经被归档，当前的镜像地址无法找到所需的文件。CentOS 7 的官方支持已经结束，部分仓库已被移至归档库。这导致了yum 命令无法找到所需的元数据文件。CentOS 7 的官方仓库在 2024 年 6 月 30 日之后已经停止维护。因此，使用最新的 CentOS 7 官方仓库可能会遇到问题。\n解决方法 手动修改配置 进入/etc/yum.repos.d目录下找到 CentOS-Base.repo\ncd /etc/yum.repos.d 之后依次执行：\ncp CentOS-Base.repo CentOS-Base.repo.backup vi CentOS-Base.repo 进入后改为：\n# CentOS-Base.repo # # The mirror system uses the connecting IP address of the client and the # update status of each mirror to pick mirrors that are updated to and # geographically close to the client. You should use this for CentOS updates # unless you are manually picking other mirrors. # # If the mirrorlist= does not work for you, as a fall back you can try the # remarked out baseurl= line instead. # # [base] name=CentOS-$releasever - Base #mirrorlist=http://mirrorlist.centos.org/?release=$releasever\u0026amp;arch=$basearch\u0026amp;repo=os\u0026amp;infra=$infra #baseurl=http://mirror.centos.org/centos/$releasever/os/$basearch/ #baseurl=http://vault.centos.org/7.9.2009/x86_64/os/ baseurl=http://vault.centos.org/7.9.2009/os/$basearch/ gpgcheck=1 gpgkey=file:///etc/pki/rpm-gpg/RPM-GPG-KEY-CentOS-7 #released updates [updates] name=CentOS-$releasever - Updates #mirrorlist=http://mirrorlist.centos.org/?release=$releasever\u0026amp;arch=$basearch\u0026amp;repo=updates\u0026amp;infra=$infra #baseurl=http://mirror.centos.org/centos/$releasever/updates/$basearch/ #baseurl=http://vault.centos.org/7.9.2009/x86_64/os/ baseurl=http://vault.centos.org/7.9.2009/updates/$basearch/ gpgcheck=1 gpgkey=file:///etc/pki/rpm-gpg/RPM-GPG-KEY-CentOS-7 #additional packages that may be useful [extras] name=CentOS-$releasever - Extras #mirrorlist=http://mirrorlist.centos.org/?release=$releasever\u0026amp;arch=$basearch\u0026amp;repo=extras\u0026amp;infra=$infra #$baseurl=http://mirror.centos.org/centos/$releasever/extras/$basearch/ #baseurl=http://vault.centos.org/7.9.2009/x86_64/os/ baseurl=http://vault.centos.org/7.9.2009/extras/$basearch/ gpgcheck=1 gpgkey=file:///etc/pki/rpm-gpg/RPM-GPG-KEY-CentOS-7 #additional packages that extend functionality of existing packages [centosplus] name=CentOS-$releasever - Plus #mirrorlist=http://mirrorlist.centos.org/?release=$releasever\u0026amp;arch=$basearch\u0026amp;repo=centosplus\u0026amp;infra=$infra #baseurl=http://mirror.centos.org/centos/$releasever/centosplus/$basearch/ #baseurl=http://vault.centos.org/7.9.2009/x86_64/os/ baseurl=http://vault.centos.org/7.9.2009/centosplus/$basearch/ gpgcheck=1 enabled=0 gpgkey=file:///etc/pki/rpm-gpg/RPM-GPG-KEY-CentOS-7 然后wq保存下，依次执行：\nsudo yum clean all sudo yum makecache 使用阿里云镜像源 下载并替换本地配置\ncurl -o /etc/yum.repos.d/CentOS-Base.repo https://mirrors.aliyun.com/repo/Centos-7.repo # 或者 wget -O /etc/yum.repos.d/CentOS-Base.repo https://mirrors.aliyun.com/repo/Centos-7.repo 刷新\nsudo yum clean all sudo yum makecache ","date":"2026-08-25T01:34:40+08:00","permalink":"/p/centos-7-yum%E6%8A%A5%E9%94%99/","title":"CentOS 7 yum报错"},{"content":"在生产环境中，服务器一般是在内网环境下，所以这里记录离线安装docker以及本地docker镜像制作和加载。\n一.下载docekr安装包 https://download.docker.com/linux/static/stable/ #通过uanme -m查看服务器架构 [root@localhost ~]# uname -m x86_64 #选择x86_64目录下对应的版本 https://download.docker.com/linux/static/stable/x86_64/docker-27.5.0.tgz 二.安装docker 1.上传docker压缩包到服务器并解压 [root@localhost opt]# ls docker-27.5.0.tgz [root@localhost opt]# tar -zxvf docker-27.5.0.tgz docker/ docker/runc docker/containerd docker/docker-init docker/dockerd docker/containerd-shim-runc-v2 docker/docker-proxy docker/docker docker/ctr [root@localhost opt]# ls docker docker-27.5.0.tgz 2.将docker可执行文件移动到环境变量路径 # 通过该命令可以看到当前的环境变量 [root@localhost opt]# echo $PATH /root/.local/bin:/root/bin:/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin # 将非系统自带的可执行文件放到/usr/local/bin/目录下 [root@localhost opt]# mv docker/* /usr/local/bin/ 3.使用systemd管理docker服务 创建服务文件docker.service\ncat \u0026gt; /etc/systemd/system/docker.service \u0026lt;\u0026lt;EOF [Unit] Description=Docker Application Container Engine Documentation=https://docs.docker.com After=network.target [Service] ExecStart=/usr/local/bin/dockerd ExecReload=/bin/kill -s HUP $MAINPID LimitNOFILE=1048576 LimitNPROC=512 TimeoutSec=0 Restart=always RestartSec=2 [Install] WantedBy=multi-user.target EOF # 重新加载服务配置文件 systemctl daemon-reload # 启动docker服务 systemctl start docker # 开机自启docker服务 systemctl enable docker 三、安装docker compose 1.下载地址 https://github.com/docker/compose/releases/download/v2.32.4/docker-compose-linux-x86_64 2.上传到服务器 [root@localhost opt]# ls docker-compose-linux-x86_64 docker-compose-linux-x86_64 3.移动到docker插件目录下 [root@localhost opt]# mkdir -p /usr/local/lib/docker/cli-plugins/ [root@localhost opt]# chmod +x docker-compose-linux-x86_64 [root@localhost opt]# mv docker-compose-linux-x86_64 /usr/local/lib/docker/cli-plugins/docker-compose 4.验证 [root@localhost opt]# docker compose version Docker Compose version v2.32.4 四、镜像的导入和导出 1.从能联网的机器拉取需要的镜像 #我这里拉取了nginx:1.27 [root@localhost ~]# docker pull nginx:1.27 1.27: Pulling from library/nginx af302e5c37e9: Pull complete 207b812743af: Pull complete 841e383b441e: Pull complete 0256c04a8d84: Pull complete 38e992d287c5: Pull complete 9e9aab598f58: Pull complete 4de87b37f4ad: Pull complete Digest: sha256:0a399eb16751829e1af26fea27b20c3ec28d7ab1fb72182879dcae1cca21206a Status: Downloaded newer image for nginx:1.27 docker.io/library/nginx:1.27 [root@localhost ~]# docker images REPOSITORY TAG IMAGE ID CREATED SIZE nginx 1.27 9bea9f2796e2 8 weeks ago 192MB 2.导出镜像 #将nginx:1.27导出到本地，名称为nginx:1.27:tar [root@localhost ~]# docker save -o nginx:1.27.tar nginx:1.27 [root@localhost ~]# ls anaconda-ks.cfg nginx:1.27.tar 3.上传镜像到不能联网的docker服务器并导入镜像 [root@localhost ~]# docker images REPOSITORY TAG IMAGE ID CREATED SIZE [root@localhost ~]# ls anaconda-ks.cfg nginx:1.27.tar #导入nginx:1.27镜像 [root@localhost ~]# docker load -i nginx\\:1.27.tar f5fe472da253: Loading layer [==================================================\u0026gt;] 77.83MB/77.83MB 88ebb510d2fb: Loading layer [==================================================\u0026gt;] 118MB/118MB 943132143199: Loading layer [==================================================\u0026gt;] 3.584kB/3.584kB 32c977818204: Loading layer [==================================================\u0026gt;] 4.608kB/4.608kB 541cf9cf006d: Loading layer [==================================================\u0026gt;] 2.56kB/2.56kB 58045dd06e5b: Loading layer [==================================================\u0026gt;] 5.12kB/5.12kB b57b5eac2941: Loading layer [==================================================\u0026gt;] 7.168kB/7.168kB Loaded image: nginx:1.27 #查看 [root@localhost ~]# docker images REPOSITORY TAG IMAGE ID CREATED SIZE nginx 1.27 9bea9f2796e2 8 weeks ago 192MB 4.运行nginx容器测试 #运行nginx容器 [root@localhost ~]# docker run --name nginx -p 80:80 -d nginx:1.27 e5fabdea277c467e910a767d4f295cec4c19b5b6fda52a7b336d7e7c8c2f8a32 #查看当前运行的容器 [root@localhost ~]# docker ps CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES e5fabdea277c nginx:1.27 \u0026#34;/docker-entrypoint.…\u0026#34; 3 seconds ago Up 2 seconds 0.0.0.0:80-\u0026gt;80/tcp, :::80-\u0026gt;80/tcp nginx #访问测试 [root@localhost ~]# curl -I localhost HTTP/1.1 200 OK Server: nginx/1.27.3 Date: Wed, 22 Jan 2025 07:06:14 GMT Content-Type: text/html Content-Length: 615 Last-Modified: Tue, 26 Nov 2024 15:55:00 GMT Connection: keep-alive ETag: \u0026#34;6745ef54-267\u0026#34; Accept-Ranges: bytes ","date":"2026-08-25T01:34:28+08:00","permalink":"/p/docker-%E7%A6%BB%E7%BA%BF%E5%AE%89%E8%A3%85/","title":"docker 离线安装"},{"content":" 一.搭建MSYS2环境 官网/清华源 下载exe并安装。 给MSYS2换源 修改 /etc/pacman.d/mirrorilist.mingw32、mingw64、msys,**https://mirrors.tuna.tsinghua.edu.cn**开头的地址放到列表的第一位。\n更新Msys2 打开msys2.exe，执行更新命令\npacman -Sy 安装 gcc 和make pacman -S gcc make 二.下载Redis编译包 github地址下载对应版本\n三.编译准备 修改Dl_info类型 修改usr/include/dlfcn.h ,删除Dl_info的定义\n编译Redis所需依赖(使用mingw64.exe终端) cd /d/redis-6.2.6/deps make hiredis linenoise lua hdr_histogram 回到Redis目录，开始编译 # 加上输出目录为 d:/redis make PREFIX=/d/redis install 编译完成，复制文件 从MSYS2安装目录下拷贝msys-2.0.dll，从redis源码目录拷贝redis.conf、sentinel.conf到输出的redis目录下，双击redis-server.exe 启动。\n四.可能存在的问题 msys编译的文件会要求exe在多层目录下执行，否则可能存在启动错误。(如d:/redis/bin/.exe可以启动，d:.exe不能启动) ","date":"2026-08-25T01:33:44+08:00","permalink":"/p/msys2%E7%BC%96%E8%AF%91redis-6.0windows%E7%89%88/","title":"Msys2编译Redis 6.0(windows版)"},{"content":"概念：要调试的APT代码为APT工程，要编译的代码为项目工程\ngradle 在项目工程中引用的APT工程的AbstractProcessor类的init/process设置断点 在项目工程中的主目录gradle.properties文件设置gradle daemon端口和JVM参数，该文件不存在则创建一个 # 设置守护线程 org.gradle.daemon=true # 设置debugger调试端口 org.gradle.jvmargs=-agentlib:jdwp=transport=dt_socket,server=y,suspend=n,address=5005 在打开项目工程中的IDEA中设置远程调试 并运行 编译运行项目工程中的代码 命令行运行gradle clean assemble 或者 IDEA Gradle管理工具运行assemble\nmaven 与gradle相似 无 与gradle相似 命令行运行maven clean 或者IDEA Maven管理工具运行构建 ","date":"2026-08-25T01:32:40+08:00","permalink":"/p/idea%E8%B0%83%E8%AF%95apt/","title":"IDEA调试APT"}]