AMD X670E-Plus Wifi 主板启动错误日志处理 硬件信息 主板: AMD X670E-Plus Wifi CPU: AMD Ryzen 9 7950X GPU: AMD Radeon RX 6950 XT 内存: 64GB 系统信息 OS: Gentoo 2.15 Kernel: 6.6.47-gentoo_x86_64 问题描述 Aug 31 00:32:54 gentoo kernel: hub 12-0:1.0: config failed, hub doesn't have any ports! (err -19) Aug 31 00:32:54 gentoo (udev-worker)[1324]: event15: Failed to call EVIOCSKEYCODE with scan code 0x7c, and key code 190: Invalid argument Aug 31 00:32:55 gentoo kernel: ucsi_ccg 4-0008: failed to get FW build information Aug 31 00:33:00 gentoo kernel: ucsi_ccg 4-0008: failed to reset PPM!

Spring Retry

- 1 min read

Series: spring-boot

Spring Retry 在日常开发中,我们经常会遇到一些需要重试的场景,比如调用第三方服务时,由于网络等原因导致调用失败,这时我们可以通过重试的方式来提高成功率。Spring Retry 是 Spring 的一个子项目,它提供了一种简单的重试机制,可以帮助我们在调用失败时进行重试。 依赖 <dependency> <groupId>org.springframework.retry</groupId> <artifactId>spring-retry</artifactId> </dependency> <!-- 如果使用注解方式需要 aop 相关依赖--> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-aop</artifactId> </dependency> 使用 1. 注解方式 import org.springframework.retry.annotation.Recover; import org.springframework.retry.annotation.Retryable; import org.springframework.stereotype.Service; /** * RetryService */ @Service public class RetryService { /** * 重试方法 * retryFor: 出现异常时重试 * maxAttempts: 最大重试次数 * @param t */ @Retryable(retryFor = RuntimeException.class, maxAttempts = 3) public void sayHi(boolean t) { System.out.println("say hi"); if (t) { throw new RuntimeException("error"); } } /** * 重试失败后执行的方法 * @param e */ @Recover public void recover(RuntimeException e) { System.

NVIM java dependency

- 1 min read

Series: neovim

NVIM java dependency 在使用nvim开发 java 时, 我有时需要查看项目依赖和源码目录结构, 我通常使用mvn dependency:tree查看依赖, 但是这样不够方便, 为了方便查看, 我写了一个插件nvim-java-dependency, 用于查看java项目的依赖和源码目录结构. 安装 lazy.nvim { "JavaHello/java-deps.nvim", lazy = true, ft = "java", dependencies = "mfussenegger/nvim-jdtls", config = function() require("java-deps").setup({}) end, } 配置 jdtls init_options, 将 vscode-java-dependency 的 jar 包添加到 jdtls_config[“init_options”].bundles 中 local jdtls_config = {} local bundles = {} -- ... local java_dependency_bundle = vim.split( vim.fn.glob( "/path?/vscode-java-dependency/jdtls.ext/com.microsoft.jdtls.ext.core/target/com.microsoft.jdtls.ext.core-*.jar" ), "\n" ) jdtls_config["init_options"] = { bundles = bundles, } 使用 :lua require('java-deps').

AI 去除背景

- 1 min read
AI 去除背景 使用 RMBG 库,基于 ONNX 模型,实现 AI 去除背景。 模型下载地址 model.onnx use rmbg::Rmbg; fn main() -> anyhow::Result<()> { // 加载模型 let rmbg = Rmbg::new("./model.onnx")?; // 读取原始图像 let original_img = image::open("./image.png")?; // 移除背景 let img_without_bg = rmbg.remove_background(&original_img)?; // 保存结果 img_without_bg.save("./out.png")?; Ok(()) } 去除前后对比 原始图像 去除背景后

Dubbo matedate 使用记录

- 1 min read
使用 remote matedate 为什么使用 remote matedate?在服务器之间配置了端口限制,使用原有的自省模式会导致 dubbo 服务相互无法获取元数据,所以使用 remote matedate。 自省模式直接使用 dubbo 协议获取元数据 provider1 限制只允许 consumer1 访问,consumer2 无法获取元数据 ┌────────────┐ ┌───────────┐ │ │◄─────┤ provider1 │◄─┬─┐ │ zookeeper │ └───────────┘ │ │ │ │ │ │ │ /services/ │ ┌───────────┐ │ │ │ /dubbo/ │◄─────┤ consumer1 ├──┘ │ MetadataService │ mapping/ │ └───────────┘ │ │ │ │ │ │ ┌───────────┐ │ │ │◄─────┤ consumer2 ├────┘ └────────────┘ └───────────┘ remote 模式 dubbo 服务会上报 metadata 数据到 zookeeper, 其他客户端直接在 zookeeper 中获取元数据 provider1 限制只允许 consumer1 访问,consumer1,2 读取 zookeeper 中的元数据 ┌────────────┐ ┌───────────┐ │ │◄────►│ provider1 │ │ zookeeper │ └───────────┘ │ │ │ /services/ │ ┌───────────┐ │ /dubbo/ │◄────►│ consumer1 │ │ metadata/ │ └───────────┘ │ provider1│ │ │ ┌───────────┐ │ │◄────►│ consumer2 │ └────────────┘ └───────────┘ 应用配置 dubbo: application: metadata-type: remote # 上报元数据到远程,消费端去远程获取元数据 metadata-report: address: zookeeper://zookeeper01:2181 # 使用 zookeeper 作为元数据中心

1. 两数之和

- 2 mins read
1. 两数之和 LeetCode 1. 两数之和 题目描述 给定一个整数数组 nums 和一个整数目标值 target,请你在该数组中找出 和为目标值 target 的那 两个 整数,并返回它们的数组下标。 你可以假设每种输入只会对应一个答案。但是,数组中同一个元素在答案里不能重复出现。 你可以按任意顺序返回答案。 示例 示例 1 输入:nums = [2,7,11,15], target = 9 输出:[0,1] 解释:因为 nums[0] + nums[1] == 9 ,返回 [0, 1] 。 示例 2 输入:nums = [3,2,4], target = 6 输出:[1,2] 示例 3 输入:nums = [3,3], target = 6 输出:[0,1] 解题模版 int* twoSum(int* nums, int numsSize, int target, int* returnSize){ } 解题思路 使用一个HASH表结构,遍历数组nums. 使用 c = target - nums[i] 在 HASH表中查找。 没有找到将key = nums[i], value = i添加到HASH表 如果找到,返回当前下标和查找到的下标 解答 typedef struct { int key; int value; UT_hash_handle hh; } HashNode; void put(HashNode **hash_map, int key, int value) { HashNode *tmp = NULL; tmp = (HashNode*)malloc(sizeof(HashNode)); tmp->key = key; tmp->value = value; HASH_ADD_INT(*hash_map, key, tmp); } void delete(HashNode **hash_map, HashNode *t) { HASH_DEL(*hash_map, t); free(t); t = NULL; } HashNode* find(HashNode **hash_map, int key) { HashNode *tmp = NULL; HASH_FIND_INT(*hash_map, &key, tmp); return tmp; } void clean_all(HashNode **hash_map) { HashNode *s, *tmp; HASH_ITER(hh, *hash_map, s, tmp) { delete(hash_map, s); } } /** * Note: The returned array must be malloced, assume caller calls free().
20. 有效的括号 LeetCode 20. 有效的括号 题目描述 给定一个只包括 (,),{,},[,] 的字符串 s ,判断字符串是否有效。 有效字符串需满足: 左括号必须用相同类型的右括号闭合。 左括号必须以正确的顺序闭合。 示例 示例 1 输入: s = “()” 输出: true 示例 2 输入: “()[]{}” 输出: true 示例 3 输入: s = “(]” 输出: false 示例 4 输入: s = “([)]” 输出: false 示例 5 输入: s = “{[]}” 输出: true 解题模版 bool isValid(char * s){ } 解题思路 使用一个栈结构StackNode,遍历字符s遇到(, [, {将对应的闭合字符push到栈中。 遇到非(, [, {的字符执行pop操作,判断栈顶字符是否与当前字符匹配,匹配pop,否则返回false. 最后堆栈如果为空返回true 解答 struct StackNode { char v; struct StackNode* next; }; struct StackNode* ifPop(struct StackNode* head, char c) { if(!
206. 反转链表 LeetCode 206. 反转链表 题目描述 给你单链表的头节点 head ,请你反转链表,并返回反转后的链表。 示例 输入: head = [1,2,3,4,5] 输出: [5,4,3,2,1] 解题模版 /** * Definition for singly-linked list. * struct ListNode { * int val; * struct ListNode *next; * }; */ struct ListNode* reverseList(struct ListNode* head){ } 解题思路 遍历每个节点, 将节点next指向上一个节点。 解答 /** * Definition for singly-linked list. * struct ListNode { * int val; * struct ListNode *next; * }; */ struct ListNode* reverseList(struct ListNode* head){ struct ListNode *p = NULL; struct ListNode *c = head; while(c) { struct ListNode *t = c; c = c->next; t->next = p; p = t; } return p; }
26. 删除有序数组中的重复项 LeetCode 26. 删除有序数组中的重复项 题目描述 给你一个 升序排列 的数组nums ,请你 原地 删除重复出现的元素,使每个元素 只出现一次 ,返回删除后数组的新长度。元素的 相对顺序 应该保持 一致 。 由于在某些语言中不能改变数组的长度,所以必须将结果放在数组nums的第一部分。更规范地说,如果在删除重复项之后有 k 个元素,那么 nums 的前 k 个元素应该保存最终结果。 将最终结果插入 nums 的前 k 个位置后返回 k 。 不要使用额外的空间,你必须在 原地 修改输入数组 并在使用 O(1) 额外空间的条件下完成。 判题标准: 系统会用下面的代码来测试你的题解: int[] nums = [...]; // 输入数组 int[] expectedNums = [...]; // 长度正确的期望答案 int k = removeDuplicates(nums); // 调用 assert k == expectedNums.length; for (int i = 0; i < k; i++) { assert nums[i] == expectedNums[i]; } 如果所有断言都通过,那么您的题解将被 通过。

27. 移除元素

- 2 mins read
27. 移除元素 LeetCode 27. 移除元素 题目描述 给你一个数组 nums 和一个值 val,你需要 原地 移除所有数值等于 val 的元素,并返回移除后数组的新长度。 不要使用额外的数组空间,你必须仅使用 O(1) 额外空间并 原地 修改输入数组。 元素的顺序可以改变。你不需要考虑数组中超出新长度后面的元素。 说明: 为什么返回数值是整数,但输出的答案是数组呢? 请注意,输入数组是以「引用」方式传递的,这意味着在函数里修改输入数组对于调用者是可见的。 你可以想象内部操作如下: // nums 是以“引用”方式传递的。也就是说,不对实参作任何拷贝 int len = removeElement(nums, val); // 在函数里修改输入数组对于调用者是可见的。 // 根据你的函数返回的长度, 它会打印出数组中 该长度范围内 的所有元素。 for (int i = 0; i < len; i++) { print(nums[i]); } 示例 示例 1 输入:nums = [3,2,2,3], val = 3 输出:2, nums = [2,2] 解释:函数应该返回新的长度 2, 并且 nums 中的前两个元素均为 2。你不需要考虑数组中超出新长度后面的元素。例如,函数返回的新长度为 2 ,而 nums = [2,2,3,3] 或 nums = [2,2,0,0],也会被视作正确答案。 示例 2