跳转到内容

小天管理

管理员
  • 注册日期

  • 最后上线

小天管理 发表的所有内容

  1. 大概是从四年级还是五年级做自己的项目开始,感觉好像就隐隐约约有倾向想要在 commit 里面写越来越多东西。一开始只是写比如从哪个 Stackoverflow 讨论串找到的参考资料,后来到一些算法或者设计上的东西,然后发现自己的 commit 标题越来越长,感觉长过头了就写进了 message 里面,然后就在 message 里面写 markdown 了。 上班后感觉好像这个倾向又被强化了,一方面摸鱼写的代码的 commit 很容易一个 commit 里面覆盖多个内容,而不是像写自己的项目那样细粒度到一两个文件,另一方面又总是担心意图没解释清楚别人难以理解自己的代码。 所以 commit 有时候就会长这样: ```markdown [Core] (fix) Sorting algorithm, XXX Page, YYY Service - Designed an algorithm to sort a certain dataset according to some requirements and constraints - Included this algorithm into XXX page - Extracted several methods to YYY service - Removed deprecated codes - Added test suite for subjects mentioned above The algorithm scans the incoming dataset, which should conform to ..., at a first pass, it will ... Some code has been refactored and reformatted. ``` 不过也不总是这么长就是,如果 commit 改变的东西不多的话,那倒是经常一两个 bullet 就完了。 另外也感觉发 PR 的时候好像我总喜欢写得像 GitHub 的 readme 一样。 不过也听说是不是说长 commit 是新手的普遍操作,senior 的 commit 普遍一句话带过。
  2. ✨官方公告 OpenAI 最新推出 GPT-4o mini 模型,小而巧! 新模型目前在聊天偏好上表现优于 GPT-4 模型,并在大规模多任务语言理解( MMLU )测试中获得了 82%的得分。 价格方面,GPT-4o mini 的成本为每百万输入 Token 为 0.15 美元、每百万输出 Token 为 0.6 美元,比 GPT-3.5 Turbo 便宜超过 60%。 官方介绍: https://openai.com/index/gpt-4o-mini-advancing-cost-efficient-intelligence/ 注意:OpenKey.Cloud 平台将于近期开始评估并适配。
  3. 如何实现异步通知的重试机制 工作中经常要和第三方做对接,比如支付、电子合同等系统。操作成功之后,第三方会发送异步的通知,返回最终的处理结果,使用异步而不是使用同步通知,是为了加快系统响应速度,防止线程阻塞。任务处理完成后通过异步的通知,发送给对应的服务端。之前对接微信支付,完成支付后,微信发送一个异步通知给服务端,服务端根据支付通知修改状态,通知规则看到以下的一段话。 其中有段话: 重新发送通知,直到成功为止(在通知一直不成功的情况下,微信总共会发起多次通知,通知频率为 15s/15s/30s/3m/10m/20m/30m/30m/30m/60m/3h/3h/3h/6h/6h - 总计 24h4m ) 微信为何要这么设计 微信结果通知本质就是发送一个网络请求到不同的服务器上,既然是一个网络请求,就可能因为各种原因导致请求超时或者失败,比如: 请求的服务器挂了 网络发生了波动 服务器响应异常 以上原因都会导致支付结果通知接收失败,也就无法通知给用户。为了解决上述的问题,就需要引入重试机制,当请求无法应答时,就需要重试几次,保证请求能确认发送。 异步通知的重试机制 从微信支付通知可以引申到所有的异步通知,或者和第三方对接时。如果要确保通知能被成功的接收,就需要考虑请求失败的情况,大部分都是需要使用重试机制。而重试机制是隔段时间不是固定的,是越来越大的,这是考虑到重试时,由于网络故障或者服务器故障重启设备需要花一段时间,而间隔时间越来越长就可以更大的保证请求可以被成功接收。 重复请求,接口需要考虑重复请求的情况,要设计成一个幂等性接口,多次请求和请求一次的效果是一致的。 重试机制的实现 重试机制就是一个定时器,隔一段时间执行一次,没有预期的效果就再重复执行一次。 实现的难点就在于,间隔的时间是不一致的,如果时间的间隔是固定的话,就可以使用定时任务。 方案一:定时任务(不可行) 使用定时器,每隔一段时间执行一次任务。在 SpringBoot 启动类添加 @EnableScheduling 注解,然后在执行的方法添加 @Scheduled 注解。 @Scheduled(fixedDelay = 1000*2) public void test2() { Date date = new Date(); System.out.println("tesk2 " + date); } 以上表示每隔 2 秒执行一次。间隔时间都是固定的,这个不符合预期,因为要求的时间间隔是依次增加的。 如果是间隔时间是固定的,那定时任务就符合条件吗? 如果是只有一条任务在执行,执行不成功,存放在 Redis 中,然后定时执行任务,如果任务执行成功,就去掉任务。但是定时器还是会定时执行。 如果执行的任务很多的话,前面的任务要等待后续的任务执行,那延迟就很严重了,就需要使用到多线程,开启多个线程,在《阿里 Java 开发手册》有一条: 线程资源必须通过线程池提供,不允许在应用中自行显式创建线程。 定时任务有以下几个缺点不满足: 时间间隔固定。 只能单线程处理任务,任务越多,延迟性越久。 方案二:线程池 + 定时任务 (不可行) 既然使用单线程会产生延迟,就使用线程池来降低延迟,因为发起请求属于 IO 密集型,所以线程数设置成 CPU 个数的两倍,在 SpringBoot 自定义一个线程池: @Configuration public class ThreadPoolConfig { // 线程存活时间 private static int keepAliveTime = 10; // 调用线程运行多余任务 RejectedExecutionHandler handler = new ThreadPoolExecutor.CallerRunsPolicy(); @Bean("customerTaskExecutor") public TaskExecutor taskExecutor() { // 核心线程数 int cores = Runtime.getRuntime().availableProcessors()*2; ThreadPoolTaskExecutor executor = new ThreadPoolTaskExecutor(); executor.setCorePoolSize(cores); executor.setMaxPoolSize(cores); executor.setKeepAliveSeconds(keepAliveTime); executor.setRejectedExecutionHandler(handler); executor.setThreadNamePrefix("Custom-"); // 线程名前缀 executor.initialize(); return executor; } } 其中核心线程数和最大线程数设置成一致,拒绝策略使用调用线程运行多余的任务,确保每个任务都能执行。然后添加一个异步方法. public interface AsyncService { void executeAsync(); } @Service @Slf4j public class AsyncServiceImpl implements AsyncService { @Override @Async("customerTaskExecutor") public void executeAsync() { log.info(" [开始执行任务] "); // 延迟几秒 try { Thread.sleep(500); } catch (InterruptedException e) { e.printStackTrace(); } log.info(" [结束执行任务] "); } } 使用 sleep 方法延迟,模拟请求,使用压测工具,发起 100 次请求,控制台输出如下: 2023-10-31 18:00:32.792 INFO 53009 --- [ Custom-1] com.jeremy.threadpool.AsyncServiceImpl : [开始执行任务] 2023-10-31 18:00:32.811 INFO 53009 --- [ Custom-2] com.jeremy.threadpool.AsyncServiceImpl : [开始执行任务] 2023-10-31 18:00:32.813 INFO 53009 --- [ Custom-3] com.jeremy.threadpool.AsyncServiceImpl : [开始执行任务] 2023-10-31 18:00:32.814 INFO 53009 --- [ Custom-4] com.jeremy.threadpool.AsyncServiceImpl : [开始执行任务] 2023-10-31 18:00:32.816 INFO 53009 --- [ Custom-5] com.jeremy.threadpool.AsyncServiceImpl : [开始执行任务] 2023-10-31 18:00:32.817 INFO 53009 --- [ Custom-6] com.jeremy.threadpool.AsyncServiceImpl : [开始执行任务] 2023-10-31 18:00:32.819 INFO 53009 --- [ Custom-7] com.jeremy.threadpool.AsyncServiceImpl : [开始执行任务] 2023-10-31 18:00:32.820 INFO 53009 --- [ Custom-8] com.jeremy.threadpool.AsyncServiceImpl : [开始执行任务] 2023-10-31 18:00:32.821 INFO 53009 --- [ Custom-9] com.jeremy.threadpool.AsyncServiceImpl : [开始执行任务] 2023-10-31 18:00:32.823 INFO 53009 --- [ Custom-10] com.jeremy.threadpool.AsyncServiceImpl : [开始执行任务] 2023-10-31 18:00:32.824 INFO 53009 --- [ Custom-11] com.jeremy.threadpool.AsyncServiceImpl : [开始执行任务] 2023-10-31 18:00:32.825 INFO 53009 --- [ Custom-12] com.jeremy.threadpool.AsyncServiceImpl : [开始执行任务] 2023-10-31 18:00:33.296 INFO 53009 --- [ Custom-1] com.jeremy.threadpool.AsyncServiceImpl : [结束执行任务] 2023-10-31 18:00:33.296 INFO 53009 --- [ Custom-1] com.jeremy.threadpool.AsyncServiceImpl : [开始执行任务] 采用线程池执行的任务,多个线程同时执行任务,能有效的降低了任务的延迟性。定时任务间隔固定时间从数据库 Mysql 或者 Redis 获取需要请求的数据,同时执行请求。 这样就有几个问题: 间隔是固定的。 空闲的时候没有请求执行,到了执行时间,大量的请求在执行,导致闲的时候闲死,忙的时候忙死。资源得不到很好的利用。 除了定时器,还有什么组件可以解决上面问题,那就是使用消息中间件了。 方案三:消息中间件 + 线程池(可行) 使用线程池的方式开启多个线程运行。那针对固定时间间隔和只能同时执行的问题使用消息中间件就能很好的解决问题,消息中间件采用生产+消费模型实现消息的生产和消费, 延迟队列 本文使用消息中间件 RabbitMQ 实现延迟队列,具体实现可以看我的另外一篇文章延迟队列实现订单超时自动取消,具体实现流程图试下如下。 请求发送失败之后,调用生产者发送消息,经过设定的时间间隔之后,发送给消费者,消费端再次发起请求,如果请求失败,再调用生产者发送消息,并设置好下一次的时间间隔,其中消费端发起任务使用线程池发起请求。 下载 RabbitMQ 延迟消息的插件 delayed_message_exchange , 在Github 官网找到对应的版本,我选择的是 3.8.17: 配置延迟队列: @Configuration public class XDelayedMessageConfig { /** * 延迟交换机 */ public static final String DELAYED_EXCHANGE = "exchange.delayed"; /** * 重试队列 */ public static final String RETRY_QUEUE = "queue.retry"; /** * 重试 routing key */ public static final String RETRY_ROUTING_KEY = "routingKey.bind.retry"; @Bean public Queue retryQueue() { return new Queue(RETRY_QUEUE,true); } /** * 定义延迟交换机 * 交换机的类型为 x-delayed-message * @return */ @Bean public CustomExchange delayedExchange() { Map<String,Object> map = new HashMap<>(); map.put("x-delayed-type","direct"); return new CustomExchange(DELAYED_EXCHANGE,"x-delayed-message",true,false,map); } @Bean public Binding retryQueueBinding() { return BindingBuilder.bind(retryQueue()).to(delayedExchange()).with(RETRY_ROUTING_KEY).noargs(); } } 在发送端模拟重试机制,设置时间间隔 5 、10 、30 秒。 @Autowired private RabbitTemplate rabbitTemplate; private final int[] INTERVAL_ARRAY= {5,10,30}; @GetMapping("/retry") public String retry(int index) { if (index >= 0 && index <= 2) { send(index +",延迟" + INTERVAL_ARRAY[index] + "s",INTERVAL_ARRAY[index]); } return "ok"; } private void send(String message,Integer delayTime) { message = message + " " + DateUtil.dateFormat(new Date()); System.out.println(" [发送消息] " + message); rabbitTemplate.convertAndSend(XDelayedMessageConfig.DELAYED_EXCHANGE,XDelayedMessageConfig.RETRY_ROUTING_KEY, message, message1 -> { message1.getMessageProperties().setDelay(delayTime*1000); return message1; }); } 接收端: @RabbitListener(queues = XDelayedMessageConfig.RETRY_QUEUE) public void delayProcess(String msg, Channel channel, Message message) { System.out.println(" [接收消息] " + msg + " 当前时间" + DateUtil.dateFormat(new Date())); try { channel.basicAck(message.getMessageProperties().getDeliveryTag(),false); } catch (IOException e) { e.printStackTrace(); } int index = Integer.parseInt(msg.split(",")[0]); retry(++index); } 控制台输出: [发送消息] 0,延迟 5s 10:59:29 [接收消息] 0,延迟 5s 10:59:29 当前时间 10:59:33 [发送消息] 1,延迟 10s 10:59:33 [接收消息] 1,延迟 10s 10:59:33 当前时间 10:59:43 [发送消息] 2,延迟 30s 10:59:43 [接收消息] 2,延迟 30s 10:59:43 当前时间 11:00:10 其中 0 、1 、2 表示重试的次数。通过延迟消息的方式,重试发送信息。每个任务作为一个消息进行消费。和定时服务相比,有以下几个优点: 支持动态间隔 任务不是同时执行,降低服务器的压力。 总结 在发送一些异步通知时候,需要考虑到通知可能接收失败的情况,比如: 请求的服务器挂了。 网络发生了波动。 服务器响应异常,服务重启。 此时无法正确的及时推送通知,无法保证通知的可靠性。这个时候就需要重试多次,而且间隔要依次增加,因为服务启动或者网络的卡顿在经过一段时间就恢复了。后续重试成功的概率就更高了。 定时重试 定时重试首先不符合变化的间隔时间,间隔的时间是固定的,重试的任务都堆积在一起请求,这样也会给服务器造成很大的压力。而空闲的时候,服务器的利用率有比较低。 同时请求,只能一个一个同步执行任务,同时执行的任务越多,延迟就越严重。 定时任务 + 线程池 为了解决同时处理任务,添加了自定义的线程池,因为请求属于 IO 密集型,所以设置线程数为 CPU 核数的两倍。 多个任务执行,降低了延迟性。 无法满足动态间隔时间的问题,而且同时请求服务器压力大。 延迟队列 + 线程池 延迟时间请求可以使用到延迟队列,每个任务都作为一个消息。每次处理不成功,就发送消息到延迟队列中,到达时间间隔之后,再消费消息。如果请求失败再重复以上操作。 消费者处理消息,使用线程池处理,加快处理速度。也可以开启多台服务器分发处理任务,加快处理速度,降低任务的延迟性。 如果感觉写的不错的,欢迎关注我的公众号
  4. 老婆怀孕四个多月,我一直以为自己想要闺女,因为家里男孩比较多,但是有次老婆和我说可能是个闺女,她自己在医院工作,可能看到了,我心里却有一点小失落,现在真不太清楚自己想要儿子还是闺女了
  5. 之前续费,有个 V 友帮我提取了一个可以享受折扣的链接,我试过可以。 现在主要是保号,所以想尽量少花钱,超级 VIP 也不用了,打算续个普通会员就好,有知道省钱办法的可以告知一下。
  6. 在 Legion Zone 里关了之后过段时间又会自己打开。 后来我重装了系统,都没有安装 Legion Zone ,刚重装完系统是关闭的,现在又自己打开了。 网上搜了一下说按 fn+L ,我按了电脑就直接睡眠了,灯也没关掉。 请教大佬有没有永久关闭的方法,这玩意太烦人了。
  7. 看完丑丑的头像有感而发 哈哈哈
  8. 现在大家的手机性能应该比 2016 年要强悍不少,甚至可以说过剩了。 那么我有个问题,大家对于手机 app 端 web 套壳以前是非常厌恶的,那现在你还讨厌 web 套壳吗?会不会因为性能跟上来了+前端技术飞速发展,甚至察觉不到某个应用其实是 web 套壳? 我想知道 2024 年有没有类似的 app 存在,很想去体验一下
  9. 前几天莫名其妙搜了下“失业、咖啡馆”,出来大量的报道,像是发现了一个突然出现的群体。 👉 Google:失业+咖啡馆 我自己最近半年一直在 remote 工作,有时也会跑去书店蹭一下场地,其实也是咖啡馆和书店办公大军的一员。 今天跟几个朋友侃大山,突然一冲动又想开咖啡馆了(开过三家),定位就是:失业者的办公咖啡馆。解决下我们自己的办公室需求,也顺便解决下这个越来越大的群体的特殊需求。 我们一合计,名字就叫 Rework Cafe,不知道的人以为是“重新工作咖啡馆”,懂的人一看就知道是《重来》这本创业书,不管什么意思,我们一致觉得:太 TM 励志了。 甚至我们还简单幻想了下商业模式: - 一天 100 块钱,包含 2 杯咖啡 2 个三明治,免费停车,一个卡座,千兆网络。 - 优先考虑失业人群、35 岁以上的中年人,写作业的免进。 - 免费办再就业、创业、AI 讲座,代售成人教育课程、公司代账、注册地址等等。。。 反正,就是咖啡、办公、就业创业学习的混搭。 越聊越 Hi ,朋友反手就注册了个域名 rework.cafe ,准备先整理一个《办公咖啡馆和书店清单》 老哥们怎么样,冲吗?
  10. 楼主情况如下: 安装了 OpenAI 原生 Mac App,使用体验良好,但经过 v 友和推友的安利,试水了 claude3.5,发现确实在多个领域比 gpt4o 的回答更好,因此萌生了使用 claude API 的想法 但无奈找不到一款美观的 Mac 客户端,主要使用场景为大段对话(订阅了 Raycast,一些简单的任务直接快捷键提问) 希望大家能推荐一些好用的客户端/其他解决方案,如果是 SwiftUI 一类 apple 风格的就更好了,感谢大家 !
  11. 985 本美硕,校招入职某中厂之后被组内卷度吓到了 能不能求朋友们给个机会,就想找个不那么卷的工作 目前岗位是 Java 后端开发,全栈我也能做,不限城市 spring, docker, aws 之类的都有经验! 可以联系我发您简历 vx: d2VjaGF0OiAxNTMxNjA5ODk5Nw== email: aW0uYmFpaHlAZ21haWwuY29t
  12. 对于某个很重要且不频繁打开的账号密码,可以找取这个文件的md5值或者其他特征(一串字符),然后 使用 base64/md5/sha256 进行加密(编码可能更准确)或者你自己指定一个固定的、属于自己的加密方案,这样保证了密码自己不会遗忘,同时加密等级又很高。 最主要一个点,加密的方案只有自己知道,而且要固定下来。 PS:只针对特别敏感的密码
  13. 前端开发,11 年工作经验,base 广州 技能树 * 熟悉 Typescript ,2018 年开始在团队内部推行 Typescript ,日常工作中有强烈的类型规范强迫症; * 熟悉 React ,有丰富的 React 生态开发和状态管理经验; * 熟悉 Vue@2.x 源码及生态实践,并为前团队定制了渲染分支( https://github.com/Ddder-FE/vue/commits/ddder/); * 熟悉基于 webpack 的工程构建,熟悉 Plugin 、Loader 开发,有丰富的 Module Federation 开发和管理经验; * 熟悉 Git 工作流,对大型工程的协同开发、分支管理和上线流程等都有较深刻的最佳实践; * 熟悉前端性能优化的实现,包括构建时的工程优化,和运行时的资源策略和业务场景优化; * 了解 Golang ,在 BFF 层有丰富接口开发、工程架构管理、流程规范的实践经验; * 熟悉前端单元测试的编写,熟悉基于 React Testing Library 的 React 组件单元测试用例编写; * 熟悉跨境电商中物流、订单、履约、售后模块的前端业务逻辑; 好久没更新的 github 地址哈: https://github.com/SamHwang1990 如果对小弟的技能树感兴趣,留言或邮件沟通可好哈:ZnVubnllY2hvQGZveG1haWwuY29t 感谢大伙的阅读。
  14. 注册了账号,也充了费,有没有交流群可以加,使用 gpt-4o-all,gpt-4-all 都无法绘图,dall-e-3 说这个模型不存在 @cnhh
  15. 事情起因是:因为小画报,进了 AI 出海群 ,然后进了一个 “接单互助④|九旬&卡卡(448)”,里面 都是小单子(懂的都懂)。 事件:前几天看到了一个小的 钉钉消息的单子,刚好自己要用就接了。然后按引导进了一个 加入了 一个 企业微信,研究了一下能搞 ,开始说 PYTHON 开发,没说要源码,后来说要源码。我后来想想算了,给就给吧,在那个企业微信群里给需求方确认,然后群管理让发源码,我本来想着说确认下需求方需求在给他。 结果:然后群也没有了,也不知道 啥情况。 然后我去问群主啥情况,群主把我删了,然后群也删了,哈哈 聊天记录 https://imgur.com/a/N90x8Dn https://imgur.com/a/tz9tjVF https://imgur.com/a/ti1jHN6 本论坛帖子 https://www.v2ex.com/t/1042606
  16. 我的团队负责的是蚂蚁数仓的调度引擎,类似 DolphinScheduler 。目前系统已经走过了初期建设阶段,当下主要在一些前沿方向进行探索,比如运筹优化领域,如何在一张有千万级任务组成的 DAG 上实现全局最优;比如 AI 智能体领域,如果让系统能自动适应各类异常情况并始终稳定运行。 如果你不满足于做一个 CURD boy ,想在一些技术领域做出不一样的东西,非常欢迎有技术热情的人加入! mail: mingzhi.lk@antgroup.com JD: https://talent.antgroup.com/off-campus-position?positionId=1960002&qrCode=A6PX3Z1H%2F8pHC%2FwtNmu3ysqSl4METzwH2_sM1_joM6op3sFfs_b9VeyLeo0OvrX6T2UA0KAfRY7%2FdzJ4Pngk7g%3D%3D
  17. 需求 手机请求用户输入并记录时间、用途、金额和币种等信息。 快速实现 请求输入(文本)获取用途; 请求输入(数字)获取金额; 从列表中选取币种(可省略); 合并当前日期、用途、金额和币种; 追加到文本文件。 快捷指令说明 黄色部分获取用途和金额。想要一次性输入多个时,用空格分隔输入的用途,重复部分会遍历每一个用途并请求输入金额存在词典中(用途: 金额); 绿色部分获取所选的币种(可忽略); 遍历词典的每一个键(用途)并获取值(金额),合并时间、用途(重复项目/键)、金额(键值)和币种(2 选取的项目),追加到 txt 文本的的末尾。 实现结果 2024-07-06, 音响, 40, CNY 2024-07-06, 射灯, 24.88, CNY 2024-07-08, 理发, 10, CNY 2024-07-09, 水浸卫士, 50.5, CNY 2024-07-12, 薏仁水, 4.9, CNY 2024-07-13, 辣条, 5, CNY 2024-07-14, 辣条, 5, CNY 2024-07-14, 啤酒, 2.5, CNY 2024-07-16, 泡面, 2.8, CNY 2024-07-16, 雪糕, 0.8, CNY 2024-07-18, 辣条, 5, CNY 如何分析 有了格式化的原始数据,一次性在每一个小类别后追加一个大类,如三餐、出行、零食、虚拟产品和电子产品等(熟悉个人的支出情况可以每次直接提供大类的选项),之后可以用任何你喜欢的软件进行可视化。当然亦可以用快捷指令实现,目前写了另一个快捷指令每天对当月花费求和并在晚上发送通知。
  18. 千兆联通宽带,用 pikpak 满速下载的时候,光猫就死机给你看, 这玩意是光猫设置问题,还是质量问题,光猫和路由器是桥接。
  19. 最近得知家中长辈疑似患上了渐冻症,感觉像天塌下来了一样,唉。
  20. 已知的途径有,国外亲朋好友买了,然后发 ups 到国内。 还有其他方法吗
  21. 从毕业到现在,一直混迹于小公司,做着一份毫无成长,没有什么意思的工作,面试也不顺利,跳槽也没跳出去,曾幻想到大公司去工作,现在看来也已经不可能了,也没什么社交圈,周末就到星巴克办公,要么就宅在出租屋了,母单到现在,家里人也一直催婚,感觉真的倦了,想要逃离却没有办法,有时候都不知道为啥要过着这样的生活,如此生活三十年,感觉大厦已经崩塌了,前两份工作都是被裁离场,现在公司又快不行了
  22. 我注册了一个新加坡区账号,绑定国内 visa 卡,添加信用卡的瞬间亚马逊网页就打不开了(网络是正常的,新加坡区奈飞照常看),prime video 的 APP 可以打开,但是原本满屏的聚集只剩下个位数,像是账号本身被拉黑了一样,想问问正确的步骤和条件,手机号和信用卡有什么要求