小米正式官宣开源!杀疯了!
最近,和往常一样在刷 GitHub Trending 热榜时,突然看到又一个开源项目冲上了 Trending 榜单。
一天之内就狂揽数千 star,仅仅用两三天时间,star 数就迅速破万,增长曲线都快干垂直了!
出于好奇,点进去看了看。
好家伙,这居然还是小米开源的项目,相信不少小伙伴也刷到了。
这个项目名为:ha_xiaomi_home。
全称:Xiaomi Home Integration for Home Assistant。
原来这就是小米开源的 Home Assistant 米家集成,一个由小米官方提供支持的 Home Assistant 集成组件,它可以让用户在 Home Assistant 平台中使用和管理小米 IoT 智能设备。
Home Assistant 大家知道,这是一款开源的家庭自动化智能家居平台,以其开放性和兼容性著称,其允许用户将家中的智能设备集成到一个统一的系统中进行管理和控制,同时支持多种协议和平台。
通过 Home Assistant,用户可以轻松地实现智能家居的自动化控制,如智能灯光、智能安防、智能温控等,所以是不少智能家居爱好者的选择。
另外通过安装集成(Integration),用户可以在 Home Assistant 上实现家居设备的自动化场景创建,并且还提供了丰富的自定义功能,所以一直比较受 DIY 爱好者们的喜爱。
大家知道,小米在智能家居领域的战略布局一直还挺大的,IoT 平台的连接设备更是数以亿记,大到各种家电、电器,小到各种摄像头、灯光、开关、传感器,产品面铺得非常广。
那这次小米开源的这个所谓的米家集成组件,讲白了就是给 Home Assistant 提供官方角度的支持。
而这对于很多喜欢折腾智能家居或者 IoT 物联网设备的小伙伴来说,无疑也算是一个不错的消息。
ha_xiaomi_home 的安装方法有好几种,包括直接 clone 安装,借助 HACS 安装,或者通过 Samba 或 FTPS 来手动安装等。
但是官方是推荐直接使用 git clone 命令来下载并安装。
cd config
git clone https://github.com/XiaoMi/ha_xiaomi_home.git
cd ha_xiaomi_home
./install.sh /config
原因是,这样一来当用户想要更新至特定版本时,只需要切换相应 Tag 即可,这样会比较方便。
比如,想要更新米家集成版本至 v1.0.0,只需要如下操作即可。
cd config/ha_xiaomi_home
git checkout v1.0.0
./install.sh /config
安装完成之后就可以去 Home Assistant 的设置里面去添加集成了,然后使用小米账号登录即可。
其实在这次小米官方推出 Home Assistant 米家集成之前,市面上也有一些第三方的米家设备集成,但是多多少少会有一些不完美的地方,典型的比如设备状态响应延时,所以导致体验并不是最佳。
与这些第三方集成相比,小米这次新推出的官方米家集成无论是性能还是安全性都可以更期待一下。
如官方所言,Home Assistant 米家集成提供了官方的 OAuth 2.0 登录方式,并不会在 Home Assistant 中保存用户的账号密码,同时账号密码也不再需提供给第三方,因此也就避免了账号密码泄露的风险。
但是这里面仍然有一个问题需要注意,项目官方也说得很明确:虽说 Home Assistant 米家集成提供了 OAuth 的登录方式,但由于 Home Assistant 平台的限制,登录成功后,用户的小米用户信息(包括设备信息、证书、 token 等)会明文保存在 Home Assistant 的配置文件中。因此用户需要保管好自己的 Home Assistant 配置文件,确保不要泄露。
这个项目开源之后,在网上还是相当受欢迎的,当然讨论的声音也有很多。
小米作为一家商业公司,既然专门搞了这样一个开源项目来做 HA 米家集成,这对于他们来说不管是商业还是产品,肯定都是有利的。
不过话说回来,有了这样一个由官方推出的开源集成组件,不论是用户体验还是可玩性都会有所提升,这对于用户来说也未尝不是一件好事。
那关于这次小米官方开源的 Home Assistant 米家集成项目,大家怎么看呢?
注:本文在GitHub开源仓库「编程之路」 github.com/rd2coding/R… 中已经收录,里面有我整理的6大编程方向(岗位)的自学路线+知识点大梳理、面试考点、我的简历、几本硬核pdf笔记,以及程序员生活和感悟,欢迎star。
来源:juejin.cn/post/7454170332712386572
离开大厂一年后的牛马,又回到了草原
牛马终究还是回到了草原
大家好呀,今天开始继续更新文章了,最近一个月因为换了城市,调整状态花了不少时间,现在才有些动力继续更新,今天来聊聊最近一年多的经历
1.回二线城市
23年12月的时候,我从北京阿里离职了,回到离家近的武汉,拿了一个国企的offer,也是在那家国企待了一年多的时间。
至于为什么会选择回武汉,主要觉得在一线城市买不起房,而且长期在外离家远,漂泊感太重,还不如早点回二线城市定居下来,免得以后年龄大了更不好回来。所以,当时看武汉的机会主要找稳定的工作,除了国企offer,还拿过高校,以及其他偏稳定的公司offer。综合考虑后,才选的国企
回来之后没到两月,就有些后悔了。虽然回来之前做好了心理预期,工资会降低,只是国企的工资也低的过于少了吧,开始几个月工资只有原来的零头。而且,呆了一段时间后发现,这个国企在北京才是研发中心,武汉这边作为分中心,只是北京的“内包”而已。
项目经理都是在北京,很多还都是校招进去工作才两三年的,就让管武汉这边几个人的工作。这些人也没啥管理经验,就只是不停给底下人施压。而且经常搞的操作就是,项目都是有时间要求的,开始的时候不拉人进来干活,等到时间比较紧的时候,才拉人进来,这就导致武汉的人收到任务时,都是重要且紧急的工作。又或者正常工作日没安排活,等到要放假,或者下班之前,才给安排活,让自行加班完成,故意恶心人
2.上着北京的班,拿着武汉的工资
这个事在24年的时候,已经发过吐槽了,就发张截图看看
3.成长的焦虑
我在北京的时候,除了阿里,之前也呆过一家互联网公司。裁员是比较常见的事情,虽然我还没被裁过。
国企这边虽然说相对比较稳定,但是自从我这批大概20个人入职后,感觉在走下坡路了,不仅福利变少,而且也变卷了,还传出后面也要搞末尾淘汰的事。我呆了一年的时候,感觉比在一线时更害怕,假如我在这里被裁了,或者呆满三年不续签了,可能很难再找到合适的工作了,自身成长和工作年限严重不匹配,想到这,我终于还是下了决定再去一线城市
找下家的经历并不顺利,国企的项目可以说就是玩具而已,完全拿不出手。只能拿之前阿里的项目去讲。有些一线互联网大厂,面试了好几轮,好不容易都过了。在焦急等待了数周后,最后给我说横向比较有更合适的了,就不考虑了。其实大家也都明白是因为啥原因不给发。
4.空窗期
经历了几个月的找工作经历后,终于是拿到上海一家公司offer,于是也就顺理成章准备跑路了。趁着中间有半个月的空闲时间,去西边青海和西藏游玩了一次。那边景点之间距离远,在携程上报跟团游就行,价钱不高,比较推荐去青海游玩,那的牛肉和羊肉非常新鲜,值得尝试,3天的时间,每天都能看不一样的风景。
5.上海
已经到上海快两个月,开始逐渐习惯天天下雨的节奏,现在下班还是比较早的,下班的时候还能见着落日,比较WLB,没有互联网大厂那么的卷,却也是有些压力的。下面是第一周下班时路上的照片
今天就写到这吧,下次有新鲜事再分享~
来源:juejin.cn/post/7522315126491856923
AI一定会淘汰程序员,并且已经开始淘汰程序员
昨儿中午吃着饭,不知道为啥突然和同事聊起来AI发展的事儿了。虽然我们只是"🐂🐎",但是不妨碍咱们坐井观天,瞎扯淡聊聊天。
他的主要观点是:现阶段的AI绝对无法取代程序员,大家有点过度恐慌了。AI是程序员的工具,就像从记事本升级到IDE一样。
我的主要观点是:AI一定会取代大量的程序员,尤其是初级程序员。后续程序员岗将在软件公司内的比重降低,取而代之的是产品、需求和算法岗。
诚然,他说的也有一定的道理,就目前AI发展的速度和质量来看,其实大家的确有点儿过度恐慌了。
AI的确在一定程度上替代的程序员的工作,但是大多内容仍然是程序员群体在产出,这个是不容否认的事实。
不过另一个不容否认的事实是,我们越来越依赖AI了。原来大家写代码一般都是啥不会了,就直接去网上搜。比如说js怎么截断从第2位到最后一位,想不起来了,搜一搜。
现在有了AI,一般的操作都是在上面写个注释,然后回车一下,AI会自动帮你补全代码,连搜的功夫都省了。
由此俺也big胆的预言一把,CSD*、掘*、百*这些资讯类,尤其是做程序员这个方向的资讯网站会越来越没落。
原因是:有了问题,但是没有了搜索。没有搜索就没有共享解决方案的必要,因为没人看。没人看所以不再有人分享,最后Over。
Ps:或许我被啪啪打脸呢?
之前的AI编码工具我就有在用,包括阿里的通义,百度的文心,或者是IDEA里面内嵌的编码助手,以及之前CodeGeex等等吧,确确实实是提高了效率的。
这个阶段其实重点提升的是搜索的效率,有问题直接问AI,AI直接给出答案。95%的答案都是正确的,不必再去网上费劲巴拉的找了。
后来更上一层楼,Claude2、3直接翻倍的提升了开发效率。我不必再实现了,我只需要阐述需求,AI会自动给出答案。我需要的是把内容Copy下来,然后整合进我的工程里面。
后面的工作就还是原来的老步骤了,测试一下,没啥问题的话就发版,提测了。
但是现在这个阶段又进步了,TREA2.0 SOLO出道直接整合了全流程,整个过程直接变成了"智能体"把控,不再需要我的干涉了。
我需要做的工作就是阐述清楚我的需求,然后让TREA去实现。这个过程中可能也就只需要我关注一下实现的方向不要有太大的偏差,及时纠正一下(但是到目前为止没遇到过需要纠正的情况)。
也就是说,现在AI已经从原来的片面生成代码,到后面的理解需求生成单文件代码,到现在生成工程化代码了。
而我们的角色也从一个砌墙工人,拿到了一把能自动打灰的铲子
。
到后面变成一个小组长,拿着尺子和吊锤看他们盖的墙有没有问题
。
到现在变成包工头看着手底下的工人一层层的盖起大楼
。
但是!
你说工地上是工人多,还是组长多,还是包工头多?真的需要这么多包工头嘛?
来源:juejin.cn/post/7530570160840458250
奋斗在创业路上的老开发
前言
一个老🐮🐴的吐槽。 水水文章。不喜勿喷~
现状
看过我之前帖子的小伙伴了解过 我现在在创业的路上越走越远。痛苦面具又带上了。 每天就是处理不完的事情。层出不穷的状况。各种乱七八糟的电话。处理不完的工作。在这个过程中学到了很多技术之外的东西。看到了以前看不到的东西。同样的。也渐渐放弃了属于一个开发者的身份
自己做了这么多年的技术。回头看看其他同期的小伙伴。要么已经开始玩鸿蒙。或者小程序。或者其他的等等等。
自己其实很早就涉猎。但是绝对谈不上精通。现在年纪也大了。发现精力真的有限。而且也发觉学不动了。渐渐的就变成了守护自己的一亩三分地。 技术也在降低。
有心想去学习一下鸿蒙。感觉不难。第一是没系统的时间去专门学习。二是认为如果发展需要。可以选择招聘动这个技术的人去完成这部分工作。自己没必要去学。
碎碎念
公司现在也慢慢开始扩招。算是慢慢走上正轨。业务页越来越多。同样的压力页越来越大。毕竟咱现在可没那么好运气。有人愿意给我钱让我去玩。都是自己的真金白银。出现任何的问题都可能是致命的。
说道招聘 。哎。最近一周都是在面试。一直找不到合适的人。或者遇到合适的 人家瞧不上咱这小门小庙的。属于是难。
写在最后
作为技术出生的牛马。对于技术始终是热爱的。然而显示就是现在就是慢慢的脱离了技术的身份。有更多需要我去做的事情。也有更多值得我去做的事情。 希望财富自由。漫漫长路。还远的很啊~
给年轻人建议
有点装大尾巴狼了。 勿喷哈。 因为最近一直在面试。其实也有很多应届生。我是不反对应届生的。相反我很喜欢带小朋友。而且也带过不少小朋友。
但是很多应届生给我的感觉就是。虽说咱这行收入相比其他行业要好一点。但咱这小门小庙的 也不是应届生张口8K咱能用得起的啊。毕竟小公司。我比较穷。。
不少应届生给我的感觉是心浮气躁。并没有对技术的敬畏。与之带来的是基础的不扎实。这很大程度上限制了自己的上限的。
来源:juejin.cn/post/7529799737702826022
一个“全局变量”引发的线上事故
你正在给一家 SaaS 客户做「企业级仪表盘」项目。
需求很简单:把 20 多个子系统的实时指标汇总到一张大屏。
为了“图省事”,你在入口文件里顺手写了这么一段:
// main.js
window.dashboard = {}; // 🔍 全局缓存
window.dashboard.cache = new Map(); // 🔍 存接口数据
window.dashboard.refresh = () => { // 🔍 供子系统调用
fetch('/api/metrics').then(r => r.json())
.then(data => window.dashboard.cache = new Map(data));
};
上线两周后,客户反馈:
“切到别的标签页再回来,大屏偶尔会白屏,刷新又好了。”
排查发现,Chrome 在内存紧张时会 回收后台标签页的 JS 堆,但 window
对象属于宿主环境,不会被回收。
结果:
- 旧的
dashboard
引用还在,但闭包里的Map
被 GC 清掉,变成空壳; - 子系统继续调用
window.dashboard.refresh
,拿到的永远是空数据; - 页面逻辑崩溃,白屏。
解决方案:三层防护,把风险降到 0
1. 表面用法:用 WeakMap
做“软引用”
// 把全局缓存改成弱引用
const cache = new WeakMap(); // 🔍 不阻止 GC
window.dashboard = {
get data() { return cache.get(document); }, // 🔍 与当前文档生命周期绑定
set data(v) { cache.set(document, v); }
};
这样当用户切走标签页、文档被卸载时,cache
自动释放,切回来重新初始化,白屏消失。
2. 底层机制:为什么 window
不会被 GC?
层级 | 角色 | 生命周期 | 是否可被 GC |
---|---|---|---|
JS 堆 | 闭包、普通对象 | 无引用即回收 | ✅ |
Host 环境 | window | 与标签页同生同灭 | ❌ |
渲染进程 | GPU 纹理、DOM | 标签页关闭后统一清理 | ✅ |
结论:window
是宿主对象,生命周期长于 JS 堆,挂上去的东西如果强引用 JS 对象,会导致“僵尸引用”。
3. 设计哲学:把“全局”变成“注入”
与其在 window
上挂变量,不如用 依赖注入 把作用域限制在模块内部:
// dashboard.js
export const createDashboard = () => {
const cache = new Map(); // 🔍 私有状态
return {
refresh: () => fetch('/api/metrics')
.then(r => r.json())
.then(data => cache.clear() && data.forEach(d => cache.set(d.id, d)))
};
};
// main.js
import { createDashboard } from './dashboard.js';
const dashboard = createDashboard(); // 🔍 生命周期由模块控制
应用扩展:可复用的配置片段
如果你的项目必须暴露全局 API(比如给第三方脚本调用),可以用 命名空间 + Symbol 双保险:
// global-api.js
const NAMESPACE = Symbol.for('__corp_dashboard__');
window[NAMESPACE] = { // 🔍 避免命名冲突
version: '2.1.0',
createDashboard
};
环境适配说明:
- 浏览器:Symbol 在 IE11 需 polyfill;
- Node:同构渲染时
window
不存在,用globalThis[NAMESPACE]
兜底。
举一反三:3 个变体场景
- 微前端基座
用window.__MICRO_APP_STORE__
传递状态,但内部用Proxy
做读写拦截,防止子应用直接篡改。 - Chrome 插件 content-script
通过window.postMessage
与页面通信,避免污染宿主全局。 - Electron 主进程/渲染进程
用contextBridge.exposeInMainWorld('api', safeApi)
把 API 注入到隔离上下文,防止 Node 权限泄露。
小结:
把 window
当“公告栏”可以,但别把“保险箱”也挂上去。
用弱引用、模块化和依赖注入,才能把全局变量的风险真正关进笼子里。
来源:juejin.cn/post/7530893865550675968
拥有自由的人,会想什么是自由吗?
拥有自由的人,会想什么是自由吗?
这个问题很动人。
就像从不缺氧的人,不会意识到自己在呼吸;只有气压骤降、肺部抽痛、窒息临近,你才突然意识:空气原来不是理所当然的东西。
自由也是一样的。它真正被觉察的时候,往往是在你被拿走的时候。
不是所有人都有幸拥有“思考自由”的资格——更大的现实是,大多数人连“自由”这个词,在生活中都用不上。
但更残酷的问题是:一旦你开始思考自由,你可能就已经不再自由了。
意识是自由的开始,还是终结?
我们都羡慕小孩的自由,羡慕他们想哭就哭、想跑就跑。那是因为他们没有太多意识,不懂责任,不预设后果。他们拥有的,某种程度上就是我们说的“纯粹的自由”。
但我们一旦有了意识,就不得不开始自我规训。
你不能说错话,不能做错事,不能轻易违背别人的期待,也不能轻易违背自己的设定。这时候,自由就变成了一个带着锁链的词——它不再是“你想干嘛就干嘛”,而是“你要先知道你干嘛,然后想清楚值不值得干”。
你开始意识它,珍惜它,运用它。听上去很高尚,但自由就没那么轻盈了。你得为每一个选择负责。你得考虑代价。你得思考背后有没有人被伤害,代价是否能承受。那时候你拥有的自由,不再是“想干嘛就干嘛”,而是“想清楚还能不能干”。
于是我们陷入悖论:越意识自由,就越离自由远。
真自由,是不是只能不想自由?
也许真自由的极致状态,就是你不再思考自由。
你骑车穿过黄昏,不想目标,不管导航,只有风。那一刻你自由得像只鸟——不是因为你想清楚“我现在自由”,而是因为你根本没想。
但人做不到这一点。
人思考,自我意识,把自己从自然的状态中拉出来。他要赋予意义,要预测后果,要制定计划、要写年中总结。“思考”是人成为人的标志,但恰恰是这种人性,把自由给污染了。
你可以试着淡化思考和责任,去贴近那种“纯粹的自由”。
但走到尽头,你会发现,那个状态更像动物,或者神明——不是人。
佛陀顿悟时抛弃自我,道家讲“无为而无不为”,他们都靠剥离世俗意义、剥离责任来获得自由。但代价是:你不再是你了。你不再参与、不再牵挂、不再卷入——你从人间抽身而出。
那还是你想要的吗?
你想要的自由,真的是那种不思考、不负责、无我无念的“纯粹自由”吗?还是你其实想要的是“有方向、有意义、有选择权的自由”?
那就不是“纯粹的自由”,而是“人的自由”了。
被命名,被负重,被理性打磨过的一种自由。
成年人的自由,成熟还是无奈?
很多人问:我们活在这种“既不能无意识、又不能无限选择”的自由状态里,算不算一种折中?
是深刻的选择,还是没办法的接受?
我想,这两种说法都对。
是选择的深刻,是因为我们终于知道,自由不是想干嘛就干嘛,而是想清楚干嘛还敢干。我们学会了在有限中谋局,在责任中行事,在约束中寻找空间。
是无奈的接受,是因为这世界本就不为个体设计。你生而有父母、有文化、有制度、有边界,你不是赤条条的自由人,而是注定被驯服的社会动物。
所以这就是我们大多数人的状态:在责任和意义之间拉扯,在妥协与坚持中微调。我们既不彻底自由,也没有完全被束缚。我们像在悬崖边站着,一边看风景,一边找落脚点。
真自由的瞬间:不解释、无恐惧、自己买单
有没有真正自由的时刻?有。
也许它不是持续性的,不是状态,而是一个个“瞬间”:
- 你做了一个决定,没有任何人强迫,也没有任何人能为你负责,但你依然选了它。
- 你拒绝了别人的定义,不害怕后果,不需要解释,也不留退路。
- 你明知代价高昂,但你还是咬牙说:“是我选的。”
这些时刻,就是成年人的自由瞬间。它不一定光鲜,但它是真实的。
不是没有限制,而是你在限制中还敢动,还想选,还愿意承担结果。
小时候我们追求的自由,是不要规则、不要约束。
长大后我们追求的自由,是在规则中拥有自己的边界感,在约束中活出自己的形状。
我们不会再轻易喊口号,也不会高谈“我要自由”。因为我们知道,自由并不是要来讲的,而是用来活的。
自由从来不是站在天台上的呼喊,而是你在清晨醒来,决定今天以什么方式活。
有些人一生都在寻找自由,却不知:
你敢为自由付出代价的那一刻,你就已经自由了。
推荐阅读
什么是好婚姻?一场人类与AI直指婚姻本质的深度对话,带你认清自己
互联网打工人如何构建稳定的社会身份?——从腾讯离职到圈层断崖的思考
互联网人,为什么你越来越能干,路却越走越窄?换个体制内视角看看
从“奶妈”的消失看“母职外包”:自由是建立在别人无法选择的人生之上
来源:juejin.cn/post/7526820622878572587
程序员如何在家庭、工作、健康之间努力找平衡
程序员如何在家庭、工作、健康之间努力找平衡
前言
作为程序员,我们每天都要面对 工作、家庭、健康 的三重压力。加班是常态,学习新技术是必须,家人的期待也不能忽视,而自己的身体却在无声抗议……
如何在代码、生活和健康之间找到平衡? 今天,我想分享自己的实践心得——时间管理、高效工作(甚至合理摸鱼)、坚持运动和培养爱好,让生活不再只有996。
1. 时间分配:你不是没时间,只是没规划
很多人抱怨"太忙了,根本没时间",但其实:
- 时间就像海绵里的水,挤一挤总会有
- 关键在于优先级,而不是时长
(1)工作日时间分配(参考)
时间段 | 安排 | 核心原则 |
---|---|---|
7:00-8:00 | 早起1小时 | 运动/阅读/学习(不碰手机) |
9:00-12:00 | 高效工作 | 处理复杂任务(大脑最清醒) |
12:00-13:30 | 午休 | 吃饭+小睡20分钟(不刷短视频!) |
14:00-18:00 | 工作+摸鱼 | 穿插休息,避免久坐(后文讲摸鱼技巧) |
19:00-21:00 | 家庭时间 | 陪家人,带娃儿出去耍(儿子现在一岁一个月)) |
21:00-22:30 | 自我提升/放松 | 学习、兴趣、轻度运动 |
23:00前 | 睡觉 | 保证7小时睡眠 |
关键点:
- 早起1小时 > 熬夜3小时(效率更高,不影响健康)
- 午休小睡能提升下午效率(NASA研究证实)
- 晚上固定家庭时间(让家人感受到你的存在)
2. 上班摸鱼的正确姿势(高效工作法)
摸鱼 ≠ 偷懒,而是 科学调整工作节奏,避免 burnout(职业倦怠)。
(1)合理摸鱼技巧
✅ 番茄工作法:25分钟专注 + 5分钟休息(刷掘金、喝水、拉伸)
✅ 每1小时起身活动:接水、上厕所、简单拉伸(预防颈椎病)
✅ 利用自动化工具:写脚本省时间(比如自动生成周报、批量处理数据)
✅ 学会"战略性拖延":非紧急需求先放一放,等PM改需求(你懂的)
(2)减少无效加班
❌ 无意义会议:能异步沟通的绝不开会
❌ 过度追求完美:代码能跑就行,别陷入"过度优化陷阱"
❌ 盲目卷工时:效率 > 工作时长,早点干完早点走
摸鱼的核心是:用更少的时间完成工作,把省下的时间留给生活。
3. 下班后:运动 + 兴趣,找回生活掌控感
(1)运动:程序员最值得的投资
- 每天10分钟拉伸(改善肩颈酸痛)
- 每周3次有氧运动(跑步、游泳、骑行)
- 利用通勤时间运动(骑车上班、步行回家)
(亲测有效) 自从坚持运动,我的腰不酸了,debug效率都提高了!
(2)培养兴趣爱好,对抗职业倦怠
- 学一门非技术技能(摄影、吉他、烹饪)
- 参加线下活动(技术沙龙、运动社群)
- 每周留出"无屏幕时间"(比如读书、拼乐高)
生活不能只有代码,否则你会变成一个无聊的人。
4. 家庭时间:质量 > 数量
- 每天30分钟专注陪伴(不刷手机,认真听家人说话)
- 周末至少半天家庭日(哪怕只是逛超市、一起做饭)
- 重要日子提前安排(生日、纪念日,绝不缺席)
孩子不会记住你加了多少班,但会记住你是否陪他踢过球。
结语:平衡是动态的,不是完美的
程序员的生活就像 多线程编程——工作、家庭、健康,每个线程都要分配好资源,否则就会死锁。
我的经验是:
- 工作时间高效摸鱼,减少无效加班
- 下班后运动+兴趣,保持身心健康
- 家庭时间全心投入,不让代码侵占生活
掘友们,你们是如何平衡工作、家庭和健康的?欢迎在评论区分享你的经验!
(如果觉得有用,点个赞吧~ 🚀 你的支持是我分享的动力!)
关于作者
一个拒绝996的程序员,相信 代码是为了更好的生活,而不是取代生活。
关注我,了解更多程序员成长 & 生活平衡技巧!
来源:juejin.cn/post/7520066847707643915
你有多久,没敢“浪费”点时间了?
引言
前两天有个朋友劝我:“你写作一年半了,再不搞点产品变现,继续写作两三年,可能还是原地踏步。”
写了一年半,80多篇文章,没涨粉、没变现、也没10w+。很多人觉着我白干了,可我反而觉着,这是我这几年做的最对的一件事情。
现在回头看看,真正让我成长的,恰恰是那些“什么都没做”的时光。
浪费时间才能感受到自由且主观的愿望
我们这一代人对时间的利用,已经开发到了极致,有着极强的目的性。
高中时,排队打饭背单词,午休趴在床上背公式。
大学毕业,为了面试背八股文、刷算法。
在大厂,一空下来就去研究新技术、优化工作流......
我从未停下来过,连休息都像在为下一次奔跑而准备。
我们太怕浪费时间了。
怕没成果,怕落后,怕被这个飞速发展的社会淘汰掉。
可你想想,我们来到这个世界,不应该是来探索和体验的吗,我们看似高效利用了时间,可有多少时间是真的为了你自己呢。
上篇文章我提到,回到济南之后,相比在北京有了更多空闲时间,并且开始“补偿性浪费”,刷短视频、打游戏、炒股,算得上不务正业。
有一天孩子睡觉后,我从8点刷抖音刷到凌晨,但没有记住任何内容,那一刻我有一种无所事事的空虚感。
于是我开始换口味,刷一些技术社区、公众号文章。偶尔点进一些作者的首页,我发现他们很多并不是大V,也没有露脸,但写的文字有一种特别的力量。
他们写自己的经历、认知的变化、对技术和生活的思考,字里行间有诚意也有深度,我有点羡慕,也有点触动。
既然他们可以写,我也可以。
那一刻我才想起来,我好像很早之前就喜欢写东西,只不过后来成家立业,一路奔波,把这件事丢在了脑后而已。
这么多年,我总是忙着成为别人期待的样子,却很少问自己一句:我到底喜欢什么?
于是我开始尝试着表达自己,一开始不为流量也不为变现,就只是为了找回一点属于自己的空间,
现在回头看,那段“虚度光阴”的日子,并不是浪费,而是我停下来,等到了那个被遗忘很久的自己。
时间看似浪费,但是在塑造你
有一次晚上睡觉前,随手打开了一篇去年写下的文章。
看着看着感到睡意全无,逻辑混乱、语句稚嫩,没有原创的观点,更没有什么进步,可怕的是这样的文章我重复了这么多遍,我忍不住怀疑自己这一年到底在干些什么。
还有一次我花了4、5天写下了3000字,写完读了一遍,发现整个逻辑有些牵强,于是我把写下的内容挪到了“回收站”里,那一刻我感觉我自己浪费了好几天的时间。
这些文章,没有涨粉,也没有变现,也没写出个10w+,那种感觉我自己都很难说清楚,明明花了时间和精力,却有一种什么都没留下的“无力感”。
有几个一起做公众号的朋友,已经走通了自己的商业闭环,而我却连个精准的定位都没有。有一段时间我经常会陷入自我怀疑,我这样的坚持到底有没有意义。
一直以来好像都很着急,我习惯了“投入—产出—收益”的闭环,反倒忘了有些事情短期就是看不到结果。
可就是在这样反复挣扎的过程中,我好像有了一点变化,并不是我变得更高效了,而是我越来越清楚自己想表达些什么,想成为什么样的人。
我做自媒体之初并没有定位,可慢慢的我在过去80多篇文章中,我慢慢发现了几条主线。
比如作为这个时代的一个普通人,我喜欢分析一下时代困局,比如越来越卷的互联网,比如AI飞速发展下,我们面临的存在主义危机;
我热衷谈论认知提升的话题,如果我们要和那些优秀的人去对比,我们会发现除了财富和见识,差距最大的可能是认知边界;
我会谈论一些写作相关的东西,因为写作在这个人人都可以是一个品牌的时代,写作本身就是竞争力。
这几个方向不是我刻意设计出来的,而是过去敲下的每一个字塑造出来的。
我想起乔布斯在斯坦福大学演讲时分享的故事,乔布斯曾在大学退学后,痴迷于书法,选修 了一门看似“无用”的课程:书法美学。
直到十年后,他在打造第一代 Macint0sh 时,那些关于字体的记忆突然涌上心头。他让电脑第一次有了漂亮的字体系统,正是这件“没用的事”,让 Apple 成为了极少数“兼具科技与艺术”的品牌。
很多事情只有回头看,点才会连接成线,你想想是不是这样。
而这一切的前提是:你愿意为此“浪费时间”。
我现在怎么与时间相处的
最后一点想聊聊提升效率这回事——真正的高效,不是把时间填满,而是敢于浪费一些时间。
有孩子的人一定都有体会,娃绝对算的上是一个「时间剥夺兽」。
我为了抢夺时间,做了特别多的尝试:比如孩子一安静下来,我就赶紧打开手机看篇文章;给娃刷奶瓶刷碗的时候,我就打开听书;甚至陪孩子的时候,嘴上给他讲着故事,脑海里还不停的想一些自己的事情。
我一直试图绷紧脑海里的一根弦,觉着只要把时间用满了,就没有浪费。
但现实是,我越来越累,状态越来越差,效率越来越低。
其实我们没必要给自己较劲。
直到读了《超高效》这本书,我才意识到,大脑的原始设定,并不是持续“高负荷”的,而是分成了三种运行状态,符合幂律分布的节奏。
横坐标代表了工作强度,纵坐标代表频率。书里面列举了很多人类学家对原始部落的观察:那些采集、狩猎为生的人,绝大部分时间都是在放松,走走停停,一点也不忙碌。只有在必要的情况下,才会去长时间奔跑去追踪一个猎物,而且干一次得休息好几天。
大部分时间做轻松的事情,偶尔上个强度,才是我们人类天然适合的状态。
而我们日常的工作和生活却反过来了,试图每小时都高产,每天都有 产出,哪怕放假都不敢停歇。
你想想是不是很多人都这样?多少大厂的程序员,被一个bug卡住半天,却死盯着屏幕不愿站起身。明明已经困的上下眼皮打架,还是逼着自己熬夜敲着代码。领导看着没完成的工作量很大,就强迫大家周六周日加班赶进度。
你想想你身边是不是还有另一种人?
你在工位磨磨蹭蹭写代码的时候,同事下楼散散步,买了杯咖啡,再次坐回工位上时,一个小时的工作量比你半天的还要多。
更讽刺的是,代码质量还比你高。
我们为什么不允许自己休息休息呢,让自己“浪费”点时间呢?
后来我做出了个改变,我再带孩子出去玩的时候,试着清空大脑,绝不再想下一篇文章的选题,也不想工作上的事情,就是专心的陪着孩子玩。他跑我就追,他笑我便笑,他想要只小虫子,我就抓只蚂蚁放到他手里。
看似一整天我都“没干正事”,可大脑深度放松之后,迅速让我进入高效状态。有时候写着写着没思路了,下楼转一圈卡点就能被解开。
我突然认识到,娃哪是“时间剥夺兽”,而是一个提醒我“别太紧绷”的小天使。
你也可以当自己的小天使。
如果你感到很累,就去看会轻松的小说、看看搞笑的短视频吧,只要让自己的注意力放松下来就好。如果你很累,还对工作和生活的事很担心,就出去跑一圈、打局游戏或者正念冥想,先把那个担心放下再说。
更简单的方法是订一个闹钟,千万别让自己持续工作超过90分钟,15分钟的小睡能让你迅速恢复精力。
你需要停一停,你值得等一等。
说在最后
现在越来越多的年轻人,哪怕是换份工作,都不敢在这个时候多休息几天。比如我自己,几次跳槽,从来都是今天离职,明天入职。
“浪费时间”说起来容易,可我们心理的的确确存在一些不安全感:怕别人说自己躺平,怕简历又多出一个空档期,更害怕自己没有薪资无法证明自己的价值。
可你知道吗,这些不安全感,并不是我们自身的问题,而是这个时代的结构性压力。
教育体系从小把“高效”描述成美德,互联网把内卷和35岁危机当成噱头大肆宣传,自媒体正贩卖着“日入过万”、“自由职业”的焦虑。
可丁可卯,做每一件事都只注重效率绝不浪费时间,一天到晚跟打仗一样连说闲话的时间都没有,很难做真正重要的事,高水平工作需要浪费时间。
你有多久,没允许自己浪费点时间了?
这是东东拿铁的第83篇原创文章,欢迎关注。
来源:juejin.cn/post/7522187483761950771
技术越来越好,但快乐越来越少
引言
你还记得,上一次真正感受到快乐,是在什么时候吗?
认真想了想,我好像很久没有体会过那种真正让人开心的时刻了。朋友和家人问我最近怎么样,我会回答“还行”、“还不错”,但实际上家庭的琐事,工作的压力,对未来的焦虑,让我连半刻的放松都是一种“奢侈”。
这种状态不只我一个人,身边的朋友也是如此,日常聊天里被越来越多的烦、忙、累填满,有时候甚至“无聊”都成为了一种常态。
可我们小时候,一件新衣服、一个新游戏、一集刚更新的《火影忍者》就能让自己兴奋得整夜睡不着觉。
而现在,曾经喜欢的游戏懒得打开;过去喜欢约上三五好友聚会,现在休息的时候只想窝在家里;哪怕是自己最喜欢的动漫和电影,也没有按下播放键的冲动。
是因为我们长大了、变成熟了,身上的担子越来越重,以至于连快乐都无处安放了吗?
如果你对凡事都提不起兴趣,找不到快乐的方向,那得小心了——心理学上有一个术语,叫做「快感缺乏症」。长期的快感缺失会让我们失去对生活的敏感度,不仅难以感受快乐,还容易陷入负面情绪无法自拔,还有可能导致抑郁。
那么——快乐为什么消失了?我们又该如何找回它?
要找回快乐,就要从我们那个既熟悉又陌生的名字说起:多巴胺。
多巴胺不是快乐源泉
很多人以为,多巴胺是“快乐荷尔蒙”,但其实,它并不直接带来快乐,而是——激励。它并不会让你沉浸在此刻的满足,而是让你对现状“不满足”。它让我们不满足于现状,而是不断前进。
多巴胺能强烈驱动动机,但是它的激励效应转瞬即逝。一旦我们吃饱喝足、或者满足了我们的什么愿望之后,多巴胺的奖励作用就会消失,促使着我们去寻找下一份刺激。
在远古时代,这对于人类来说是一个非常重要的生存机制。因为食物短缺,安全难求,原始人几乎需要用80%的时间去觅食和寻找庇护上。大脑通过分泌多巴胺,促使他们保持求生欲,永不停歇。
然而到了现代社会,我们的生活方式彻底发生转变,而大脑的运作方式没有得到进化。于是大脑的多巴胺通路被频繁激活,远超我们所能接受的频率。
除了食物和性这些本能,酒精、电子游戏、网购,甚至是社交媒体的点赞,都在无时无刻挑动着我们体内的多巴胺。原始人辛苦一天才能换回的一丝快感,我们轻而易举的就能让它泛滥。
快乐太容易得到了,于是它反而越来越难感受到了。
多巴胺会激活「D2」型受体, 它的特点是收到太多多巴胺之后会产生“脱敏”,并且还会启动抑制机制,一旦被过度刺激,就会容易“疲劳”,最终让我们变得迟钝、不再敏感。
其实还有另一个罪魁祸首是「皮质醇」,它由肾上腺分泌,能够加速我们的代谢和心跳,让我们随时应对可能出现的威胁,让我们处于专注紧张的状态,但是它会抑制多巴胺的释放。
其实这也是远古时期人类的一种自保机制,可是现代社会节奏忙碌紧张,我们时刻都在为某些事情感到焦虑,比如学习成绩没能提高,工作迟迟没有涨薪,甚至是领导安排的任务马上到了Dead Line。
人体的压力系统,本身是为了突发事件而准备的,并不适合现代社会全天候的压力输入,在随时随地都能接收到各种信息的智能时代,我们的压力系统也被滥用了。
最终结果就是,即使身边的事物都在营造愉悦感,我们也很难感受到愉悦了。
重拾快乐
有一本书叫《消失的多巴胺》,作者在书中给我们提供了一个治愈快感缺乏症的方法,叫做「行为激活法」,这个方法非常简单,用一句话总结就是:记录情绪,列出快乐清单,开始行动,感受快乐,锁定美好。
那具体怎么做呢?首先你要先记录下自己的情绪的初始情况,然后持续记录变化,当你看到变化的发生,你就会有坚持的动力。
然后,找到自己喜欢的事情。你可以为自己列一份快乐清单,比如看电影、逛街,甚至是浇花、换一身新衣服,或者是去买一杯自己喜欢的咖啡,都可以。
接着就是按照清单来行动了,可我们不开心的时候有一个表现就是只想躺平,没有做事的动力。作者告诉我们,在没有做事动力的时候,做事本身就能打破缺乏动力的循环,你应该打消那些让你退缩的念头,说了就去做!
一旦有了行动,心情就可能得到改善,这时候我们就要抓住快乐。方法非常简单,因为我们的大脑一次只能处理一个想法,我们在感受到快乐的时候,集中注意力,在快乐的时刻什么都不想,用心去感受这种体验。
就是在你感受到快乐的时候,别想领导安排的工作,别想马上要还的信用卡和房贷,就感受当下的快乐。
一项研究发现,大脑腹侧纹状体区域的长时间激活与维持积极情绪和奖励直接相关,通过集中精力体会奖励时刻,可以保持高水平的心理健康,同时降低皮质醇的分泌量。
最后一步就是锁定美好时刻,最简单的做法就是感恩。有一种非常流行的方法是写感恩日记,在一天结束时,写下今天你所感激的经历。许多研究都表明,感恩可以增加大脑奖励通路中多巴胺的分泌,大脑会鼓励里去寻找更值得感恩的事物,产生正反馈。
写到这里,我感觉有点疲惫,于是我下楼,站到了阳光底下。
阳光很刺眼,我下意识闭上了眼睛,任由太阳铺满脸庞。阳光有些刺眼、有些灼热,但那一刻,但似乎有某种能量慢慢渗到身体内,驱散了心里的疲惫。
我不和同事说话,不考虑手头的工作,也不去想生活的琐事。只是站在那里,感受阳光,感受微风拂过脸颊,感受自己活在当下。
几分钟而已,心里好像解开了某个结,整个人都变得放松下来。
重拾快乐,其实并不难,其实并不是快乐离我们远去了,而是我们被快节奏的生活裹挟,忘记了如何该寻找它。
到这里,你或许已经从烦躁的情绪中脱身,重新感受到生活中久违的松弛和愉悦。但故事还没有结束——你值得拥有的,不只是回归日常的小快乐,更是那种深层次、持续、更高级的快乐。
更高级的快乐
刚刚提到感恩,可以增加大脑中多巴胺的分泌,也许你会有疑问,现代社会不是多巴胺泛滥了吗?刷短视频、打游戏一样可以获得多巴胺,那感恩带来的多巴胺有什么不一样呢?
当然不一样,不过我们先聊一句我们从小听到大的“金句”——做难而正确的事情。
许多成功者特别喜欢说这句话,那到底怎么做呢?是靠意志力和吃苦吗,是吃得苦中苦,方为人上人吗?是书山有路勤为径,学海无涯苦作舟吗?
成功者没有告诉我们的是,他们做那些难而正确的事情,他们「乐」在其中。这个乐,就来自于多巴胺,而多巴胺分为了「快多巴胺」和「慢多巴胺」。
还记得在介绍多巴胺之前,我说过多巴胺的作用吗?多巴胺并不带给我们快乐,而带给我们的是激励,是让我们兴致勃勃的做事,是一种追逐的快乐。
快多巴胺的触发模式是预测->实现,抽烟、喝酒、打游戏、刷短视频,你预测到了这些行为带给你的奖励,立刻就感受到快乐,简单直接。但是快多巴胺释放门槛低,可重复性高,来得快去的也快。
而慢多巴胺触发的模式是努力->进展。比如跑完今天的五公里,就会感受到今天一天都神清气爽;完成一篇文章,你感觉你的写作和思考能力都加深了一层。你必须先努力一番取得进展,它才能释放。慢多巴胺来得慢,去的也慢。
在字节的时候,有一次和10几个同事封闭在会议室开发一个大项目,临近项目上线的那几天,几乎都到2、3点才下班。每当0点以后都是大家最累的时候,虽然每个人脸上充满困意和疲惫,但是看着项目逐渐成型,功能越来越完善,每个人依然干劲十足。
我们或许都有做大项目的经历,在项目即将完成前,你会叫苦叫累吗?你的目标就在眼前,你做事充满动力,这才是健康的状态。做难而正确的事情,是很爽的。
这段经历过去好多年了,说实话当时做的什么项目我都记不清了,但是我记得一群人在会议室里,一同为项目上线熬夜到凌晨的那几个夜晚。
简单说:快多巴胺是“高起点、小波动、快消退”;慢多巴胺是“低起点、慢上升、慢消退”。两种多巴胺最重要的区别,是它们在大脑中的“接收区”不同,我们的感受也不同。
快多巴胺让我们成瘾,慢多巴胺可以给我们赋能。 我们应该防止自己沉溺于快多巴胺,多来点慢多巴胺。
理解了快多巴胺和慢多巴胺的原理,我们就能明白一个道理,为什么人生需要一个长远的目标。
有目标才能有行动,有行动就会有进展,追逐目标的过程能够带来慢多巴胺,而慢多巴胺对我们而言多多益善。
说在最后
所以,快乐并没有从我们身边消失,它只是在等着我们把它找回。
我们需要的不是更快的满足,也不是更高频的刺激,而是更沉浸的体验和更深入的积累。
“还行、还不错”不是标准答案,“很好、很开心”才是你的原本色彩,你永远值得拥有那种不焦虑、不躁动,却一直点亮我们生活的快乐。
那么你呢,你今天开心吗?
这是东东拿铁的第79篇原创文章,欢迎关注。
来源:juejin.cn/post/7506417928787968010
Jetbrains正式宣布免费,有点猛啊!
提到 Jetbrains 这家公司,相信搞开发的同学应该都不陌生。
该公司盛产各种编程 IDE 和开发工具,虽然2000年才成立,到现在却已经发布了超 30 款世界顶级的编程软件,同时也收获了来自全球范围内开发者和用户的青睐。
众所周知,在去年10月份的时候,Jetbrains 曾经搞过一个大动作,那就是:
官宣 WebStorm 和 Rider 这两款强大的 IDE 对非商业用途全面免费!
当时这个消息出来的时候,就曾在开发者圈子里引起了一阵轰动和讨论。
而且我清楚地记得,在当时的评论区,还有小伙伴这样问道:
“啥时候轮到 CLion 也免费呢?”
这不,好消息再次来临了!!
最近 Jetbrains 再度官宣:
CLion 从现在开始,对非商业用途全面免费!
众所周知,CLion 是由 JetBrains 设计开发的跨平台 C/C++ 集成开发环境,通过智能代码补全、深度代码分析和集成调试工具,为开发者提供高效、现代化的 C 语言和 C++ 开发体验。
然而,CLion 一直以来的高昂授权费用也让不少初学者和开源爱好者为之望而却步。
因此这回消息一出,又再次在开发者圈子里引起了一阵热烈的讨论,不少网友直呼 Jetbrains 这波格局打开了。
看到这里,相信大家也挺好奇,那他们这里所说的 「非商业用途免费」具体指的是哪些情形呢?
对此,Jetbrains 官方也给出了对应的说明,目前的非商业用途情形包括像:学习、自我教育、开源项目开发、内容创作、业余爱好开发等场景就可以免费使用这个 IDE 。
所以现在无论是学生、Arduino 开发者,还是无惧 C 语言和 C++ 重重挑战的忠实爱好者,只要使用场景不涉及商业活动,都可以来免费使用 CLion 进行开发。
说到这里,那具体的非商业用途免费版 CLion 怎么申请和使用呢?
操作其实也非常简单。
1、首先,去官网下载 CLion 安装包并安装。
不过这里要注意的是,用户需要确保下载的 IDE 版本是支持非商业许可证的最新版本即可。
2、启动运行 IDE 后,将会看到一个许可证对话框。
在该对话框中,用户可以在其中选择 Non-commercial use(非商业用途)选项。
3、登录自己的 JetBrains Account 或创建一个新的帐户。
4、登录完成后,用户需要接受 Toolbox 非商业用途订阅协议。
5、尽情享受在 IDE 中的开发。
包括如果用户已经开始了试用期或使用付费许可证激活了自己的 IDE,也仍然可以改用非商业订阅,只需要转到帮助|注册里,并在打开的窗口中点击 Remove License(移除许可证)按钮,然后再选择 Non-commercial use(非商业用途)就行了。
不过这里依然还有两个点需要格外注意。
第一点,也是官方公告里明确所说的。
如果用户选择使用 Non-commercial use 非商业用途的免费版,那软件是有可能会向 JetBrains 发送 IDE 遥测信息的,包括像:框架、产品中使用的文件模板、调用的操作,以及与产品功能的其他交互,但是官方提到不会包含个人数据。
另外还有一点需要注意的是,虽说免费版本的 IDE 在功能上与付费版本并无二致,但在某些特定功能上可能存在一定的限制。例如,免费版本的 Code With Me 功能将仅限于 Community 版本。
不过对于大多数非商业用途的开发者们来说,这些限制并不会对日常开发工作造成太大的影响。
所以总而言之,JetBrains 推出的这些非商业用途免费使用政策,虽说有一些要求,但是总体来说还是极大地降低了 JetBrains IDE 的使用门槛。
同时也会让更广泛的用户群体更容易获取并使用,从而鼓励更多的人投身于编程学习,参与到开源项目的建设,共同推动技术的进步与发展。
文章的最后,我们也不妨再次大胆憧憬一下:
既然目前的 WebStorm、Rider 以及 CLion 都已经开放了非商业用途的免费使用,那么接下来像: GoLand、IntelliJ IDEA 等的免费开放还会不会远呢?
再次期待 Jetbrains 的下一步操作。
注:本文在GitHub开源仓库「编程之路」 github.com/rd2coding/R… 中已经收录,里面有我整理的6大编程方向(岗位)的自学路线+知识点大梳理、面试考点、我的简历、几本硬核pdf笔记,以及程序员生活和感悟,欢迎star。
来源:juejin.cn/post/7504491526363856934
知名开源项目AList疑似被卖,玩家炸锅了!!
这是昨天发生在开源圈子里的一件事情,在不少开发者论坛和社区里也炸开了锅,相信不少同学也刷到了。
具体怎么回事呢?
原来是知名开源项目 Alist 被爆疑似悄悄出售,原开发者退出了项目。
注意,这里有一个词,是“悄悄”。
原来就在之前的某一天,有细心的网友突然发现,该项目的中文文档开始出现不寻常的修改,比如添加了商业化信息,新增了QQ群和VIP技术支持的内容。
再后来,有网友发现其项目官网域名完成了切换,并且这一变更也没有任何官方声明,从而引发了社区的警觉和质疑。
而事件再进一步升级的导火索则是有社区开发者在项目 PR 中发现了可疑的代码提交。
一位用户提交了包含用户数据收集功能的代码,该代码片段旨在收集用户操作系统信息并上报,尽管该 PR 最终被拒绝合入,但社区不少开发者担心这仅仅是冰山一角。
当社区质疑声浪日渐高涨,就在昨天,Alist 项目原开发者 Xhofe 在订阅频道发布公告,称:
“项目已交由公司运营,之后我会帮忙审查开源版本仓库的代码,以及确保 release 的分发由 ci 自动构建,main 分支已开启分支保护,后续所有的提交都会经过 pr 审核。”
至此,社区正式炸锅了...
众所周知,AList 是一个基于 Go 语言编写的开源文件列表与 WebDAV 程序,可能有不少同学都用过。
AList 提供了一个统一的云存储管理解决方案,支持多平台文件挂载、预览以及操作。
在此次风波爆发之前,AList 在开发者圈是不少同学的必备工具。
不仅如此,甚至还有不少相关的软件或服务是基于 AList 来做的。
这款开源项目支持几十款主流网盘的一站式管理,提供统一的网页界面,能实现跨平台文件管理、在线视频播放等功能。
从该项目的 GitHub 主页上也可以看到,目前 Alist 收获了近 50000 颗的 star 星标,这也足以说明了其在开发者圈子中的受欢迎程度。
按照作者的回应,既然 Alist 项目是被公司所接手了,那它的买家到底是哪家公司呢?
有细心的网友发现,从其官网的定价页面尝试联系下去发现,该公司正是贵州bg科技。
没错,这个公司正是之前收购 Java工具库 Hutool(A set of tools that keep Java sweet)的那个公司。
至于其在开发者圈子里的一些评论,这里就不作过多评述了。
目前,AList 项目的 Issues 区基本是沦陷了,不少开发者们都在这里输出了自己的意见与不满。
聊到开源项目被收购的事情,其实早就不是第一次发生了。
正如网友们所讨论的,商业化其实无可厚非,开发者的心血也需要回报,不同的开源项目作者可以有不同的选择。
但是如果在开源的商业化过程中存在一些让用户不明就里的暗手操盘,那事情往往就会开始变得微妙起来,毕竟开源项目的背后就是广大的用户和社区,大家时刻都在注视和监督着。
文章的最后,这里还想再聊一聊有关开源作者的生存现状。
我不知道本文被收购项目 AList 的作者是不是在全职独立做开源项目,但是在我自己的圈子里,我私下就认识好几个独立维护开源项目的朋友。
有一说一,个人开源作者其实挺不容易的,像上面这样的开源项目被公司收购的毕竟是少数个例,其实好多个人的开源项目到后期由于各种主客观原因,渐渐都停止更新和维护了。
大家都知道,伴随着这两年互联网行业的寒意,软件产业里的不少环节也受到了波动,行业不景气,连开源项目的主动维护也变得越来越少了。
毕竟连企业也要降本增效,而开源往往并不能带来快速直接的实际效益,付出了如果没有回报,便会很难坚持下去。
而如果从一名学习者的角度来看,参与开源项目的意义则是不言而喻的。
参与开源项目除了可以提升自身技术能力,收获项目开发经验之外,还可以让自己保持与开源社区其他优秀开发者之间的联系与沟通,并建立自己的技术影响力,另外参与优秀开源项目的经历也会成为自己求职简历上的一大亮点。
所以如果精力允许,利用业余时间来参与一些开源项目,这对技术开发者来说,也未尝不是一段难得的经历。
来源:juejin.cn/post/7514528800731676711
“满门被裁”,只剩下老妈还在上班
古有“满门抄斩”,今有“满门被裁”。
这不是段子,这是一个正在我们身边发生的、充满黑色幽默的现实。
最近,一位网友在论坛上发的帖子,看得人心里五味杂陈。
他说,2025年,像被下了降头。
- 3月份,他爸所在的国企解散,被裁员。
- 5月份,他自己合同到期,公司不再续签。
- 6月份,他媳妇在的部门,整个被“优化”了。
短短三个月,一家四口,三个劳动力,相继失业。全家唯一的经济来源,只剩下他那位还在工作的、本该是全家工资最低的老妈。
他说,现在家里开会,老妈的腰杆挺得最直,说话底气最足。因为她,是全家唯一的“在职员工”。
听起来有点荒诞,但当你点开评论区,看到那一排排“我也是”的留言时,还真是五味杂陈。
- 网友A: “我爸去年5月被裁,我去年6月被裁,我老公今年过年前也被裁。本来我妈工资是全家最低的,现在她是我们家的经济支柱,哈哈哈哈哈哈!”
- 网友B: “49岁。4月底,我老公国企20年被裁,今年儿子被裁,剩我一个苦苦支撑。”
每一个留言背后,都是一个正在经历风暴的家庭。
“失业”这个词,在过去,可能只是个人的不幸。但在今天,它正在演变成一种“系统性风险”,以“家庭”为单位,进行无差别的攻击。
当一个家庭的经济支柱,从三根,突然变成一根时,那种灭顶之灾般的焦虑和恐慌,足以压垮任何一个普通人。
那么,当风暴来临时,我们这些普通人,到底该怎么办?
今天,我们不讲道理,我们只讲一个真实的、可供参考的“求生案例”。
一个40岁女人的“硬核自救”
这也是一位粉丝的真实分享。
她40岁,单身,一个人住在一室一厅的房子里,背着每月2000多元的房贷。去年,她也失业了。
她花了将近一年的时间,才找到下一份工作。
在这一年里,她没有崩溃,没有躺平,而是用一种极其理性、甚至可以说是“冷酷”的方式,为自己打赢了这场“生存保卫战”。
她的方法,总结下来,就是四块“压舱石”。
第一块压舱石:不让“收入”归零
失业,不等于丧失赚钱的能力。
她做的第一件事,就是立刻盘点自己所有的“手艺”,然后把它们变成能赚小钱的“产品”。
她利用自己多年的互联网运营经验,在网上接一些零散的活儿:帮小公司写公众号文章,替人做PPT,甚至在淘宝上帮人做简历优化。
这些小钱,虽然不多,但足以覆盖她每个月的生活费和社保。这确保了她的“现金流”没有断,也让她在心理上,没有彻底沦为一个“无用的人”。
第二块压舱石:砍掉所有“虚假需求”
她做的第二件事,是立刻对自己的生活,进行一次“成本优化”。
- 消费降级: 停掉所有不必要的外出吃饭,自己做饭。她发现,当自己动手后,每天的伙食成本,可以轻易地控制在20块钱以内,而且有肉有菜。
- 关闭会员: 关掉所有视频、音乐、购物平台的自动续费。
- 戒掉“拿铁因子”: 不再喝咖啡,不再点奶茶。
她发现,当砍掉所有被消费主义制造出来的“虚假需求”后,一个人的生存成本,可以低到超乎想象。
第三块压舱石:把“时间”投资在自己身上
她做的第三件事,是把失业后多出来的、大把的时间,当成一种“资产”,而不是一种“负债”。
保持学习: 她没有整天躺在床上刷短视频,而是系统地学习了自己一直想学的英语,和能提升职场竞争力的PPT制作技能。
保持规律: 她坚持每周至少运动两次,跑步、骑行,不让自己陷入颓废、昼夜颠倒的恶性循环。
最终,正是她在这段“空窗期”里学习的英语,成了她找到下一份外企工作的“敲门砖”。
第四块、也是最重要的一块压舱石:存款
她在失业前,手里有23万的存款。
她说:“这23万,才是我敢于用一年的时间,去慢慢找工作、去学习、去生活的,最大的底气。”
它是在你被全世界抛弃时,唯一能给你安全感的东西。
在人生的牌桌上,你永远不知道下一张会发给你什么牌。你唯一能做的,就是在晴天的时候,多备几块能让你在暴风雨中不被饿死的“干粮”,和一块能让你不被大浪打翻的“压舱石”。
技术多久没有进步了?
很久没有写东西了,这个选题正好聊一下。
对于这个问题,我的答案是 1 年左右——我进外包的日子。
在外包中,我的工作日常就是搞业务,天天 CRUD,有人会讲,CRUD 也能玩出花来,只能是你自己对技术没有了追求。我承认,也确实是这样,外包的业务很多,每天 CRUD,很简单,但还是很忙,忙到不想敲代码了,忙到对技术没啥追求了。
外包确实不适合自控力太差的人,不适合自我调节能力不行的人。
为什么这样说呢?我待的外包,说它加班很多吗?其实并没有,至少工作日 5.30 下班最多也就待到 5.45 就走了,周末加班也只有比较着急的时候,次数不多,所以很少的加班,甚至比我之前待着的两家自研加班都少,为啥下班就走的的我,没有时间去深造技术了呢?
我也还在思考。目前我的答案大概还是跟业务有关。
自研会有一种成就感,尤其在我第一家公司尤甚,那时候对自己做的第一个产品确实非常上心,项目上要做的功能和遇到的问题都会进行深度思考,去结合成熟的方案来形成自己的实现方案和解决方案,但是在外包呢,天天各种项目组的人来找你,自己手里有好多个“外包前辈”的项目,继承它们的“代码遗产”,鄙视他们的代码并有优化的心思,但突如其来的项目和很少能自己评开发时间的原因,让我也“放纵”和“加入”了“他们”,每天完成了任务也仅仅是完成了任务,很少有自己的思考,也变没有了什么成就感,对代码变成了“贤者”,没有了“兴趣”,下班后的生活变成了综艺/游戏/抖音,沉浸在这样的“快乐”中。
写到这里了,也想说一下,你技术突飞猛进的时候是一个什么样的时期或状态呢?
上面也说到了,就是第一家公司,除了对自己的“初恋”产品认真外,还有就是那时候是刚从培训班出来,刚找到的第一家公司,怕过不了试用期,所以刚开始每天回家自己敲代码敲到晚上,技术成长非常快,还有就是第二家公司,用的 React 技术栈,当时我是 Vue 技术栈找的 React 技术栈,虽然当时第二家公司说给时间从 Vue 过渡到 React,但也有一种紧迫感,还有也是很想学 React 了,所以技术上也有很大进步。
技术这么久没长进了,是外包公司的问题吗?
其实不是,上面也说了,虽然都是 CRUD,虽然业务比较多,但其实加班都不多,这些都不是理由,下班后的时间其实是比较多的,都是我能掌控的,只是我没有调整好心态,对自己太过放纵罢了,游戏,小说,综艺,抖音填满了我下班后的生活,沉浸在一种虚假的快乐中,其实并不快乐。
把想说的都说出来了,挺好,后面,如果自己不想继续这么混的话,就一块一块改吧。一下全改我都不相信我能做到(三分钟的热度更可怕),一块一块来,不把自己逼的太紧,养成习惯最好,就先这样。
来源:juejin.cn/post/7494489664385548297
半数清华,8 位华人 AI 天团集体投奔 Meta!奥特曼:砸钱抢人不如培养死忠
【新智元导读】硅谷挖角戏码升级!相比 Meta3 亿美元「血本挖角」,OpenAI 来了波反向操作——选择培养人才,奥特曼悄然推进一个名为「驻留计划」(Residency Program)的项目。这个项目有何神秘之处?奥特曼的底气到底从何而来?
二十一世纪什么最贵?
人才!
最近几个月,Meta 在硅谷发起的、动辄上亿美元签字费的挖角戏码,成了史上最疯狂的人才争夺战。
不得不说,扎克伯格的「氪金」策略相当成功。
一大批来自 OpenAI、谷歌、Anthropic 甚至是 SSI 的核心研究员纷纷投入 Meta 旗下。
OpenAI 的首席研究官 Mark Chen 难掩失落地说:「这感觉就像有人闯进了我们家,偷走了我们的东西。」
面对这种近乎釜底抽薪似的挖角行为,奥特曼的反应则略显轻蔑:「Meta 的行事方式,让人感觉有些不体面」。
那么,奥特曼的底气来自哪里?
当扎克伯格在牌桌上疯狂加码时,奥特曼在牌桌之下,进行着一场完全不同维度的布局。
不挖天才,我们培养天才
当所有人的目光都聚焦在 Meta 的天价支票上时,OpenAI 正在悄然推进一个名为「驻留计划」(Residency Program)的项目。
这个项目,可以说是 OpenAI 应对人才战争的核心战略,也是理解其企业文化的一把钥匙。
OpenAI Residency 是一个为期六个月的全职带薪项目,但它的招生对象,却出人意料。
Residency 项目经理 Jackie Hehir 明确表示,他们寻找的,不是那些正在攻读机器学习或 AI 博士学位的天之骄子,也不是来自其他 AI 实验室的资深员工。
恰恰相反,他们将橄榄枝伸向了那些「邻近领域」的顶尖大脑——比如物理学家、神经科学家、数学家。
虽然没有严格的学历或工作经验要求,但设有一个极高的技术门槛,尤其是在数学和编程方面,其标准与全职员工等同。
你不需要拥有高等数学学位,但必须对高等数学概念非常自如。
「他们对这个领域(AI)充满了真正的热情,」Hehir 说。
这背后是一套极其精明的逻辑。
这场从零培养的战略,至少带来了三个层面的深远优势。
首先就是成本上的「降维打击」。
驻留研究员的年薪是 21 万美元,意味着在这六个月里,OpenAI 的支出大约是 10.5 万美元。
这个数字,足以让参与者跻身美国收入前 5% 的行列。
但在动辄千万、上亿美元签字费的 AI 顶级人才市场,这简直就是白菜价。
用极小的代价,获得了一批拥有顶级科研素养和巨大潜力的「璞玉」。
其次,是对企业文化基因的深度植入。
面对小扎的疯狂抢人,奥特曼就曾评论道:「在我看来,Meta 的所作所为将导致非常深刻的文化问题」。
而在 OpenAI,一位前员工向 Business Insider 透露,他们公司的内部文化是「对创造 AGI 的使命感到痴迷」。
通过驻留计划,OpenAI 可以在一张白纸上,从一开始就将这种使命感深深烙印在这些未来核心员工的脑海里。
他们共同学习、共同攻关,建立的不仅是工作关系,更是对共同事业的「信仰共同体」。
这与简单地用金钱挖来的雇佣兵有着本质区别。
Meta 用金钱这种最直接的外部激励,虽然见效快,但可能存在边际效应递减的风险,并且容易塑造一种唯利是图的文化。
相比之下,OpenAI 的策略则更侧重于构建内在动机:
通过赋予一个宏大的、改变世界的使命(创造 AGI),它满足了员工对归属感的渴望;
通过从零培养,让跨界人才在新领域找到自己的位置,它满足了「胜任感」的成长需求;
通过相对宽松和专注的科研环境,满足了对自主性的追求。
「传教士将打败雇佣兵」,奥特曼在内部备忘录中,写下了这句提振士气的话。
最后,是极高的忠诚度与****转化率。
数据显示,几乎每一个在驻留计划中表现出色的成员,都会收到 OpenAI 全职 offer。
迄今为止,所有收到 offer 的人都选择了接受。
每年,这个项目会迎来大约 30 名新成员,他们就像新鲜的血液,持续不断地为 OpenAI 提供能量。
OpenAI Residency 的「播种」策略,更像是一场耐心的耕耘。
它可能没法像 Meta 那样立即招到顶尖专家,但却可以培养出一片忠于自己使命、文化高度统一、且具备持续造血能力的「人才森林」。
这场发生在硅谷的人才战争,早已超越了商业竞争的范畴。
它是一场关于组织灵魂、动机和未来信念的宏大实验。
而实验的结果,不仅将决定这两家公司的命运,更将深刻地影响我们正在迈入的 AGI 时代。
最后,让我们再来回顾一下 Meta 这两个月的骚操作。
史上最疯狂人才争夺战
据估计全球有能力推动大语言模型和前沿 AI 研究的顶尖人才,只有区区 2000 人左右。
这场人才争夺战的激烈程度,未来只会不断升级。
Meta 为了 AI 顶尖人才可谓是下了「血本」。
被业内人士调侃为,「竞赛之夏的错失恐惧症(summer of comp FOMO)」。
据统计,Meta 在四年间,为 AI 顶尖人才准备了高达 3 亿美元薪酬方案,创下了行业记录。
那 Meta 这「3 亿美元薪酬」到底招了哪些顶尖人才呢?
2025 年 6 月
核心人物:Alexandr Wang(28 岁)
**背景:**2016 年,19 岁的 Alexandr Wang MIT 辍学与 Lucy Guo 共同创立「数据标注」公司 Scale AI,并于同年获得著名创业孵化器 Y Combinator 启动资金支持。顶级 AI 科技巨头:微软、Meta、OpenAI 等提供模型训练数据。
**押注金:**143 亿美元
**原职位:**Scale AI 创始人
**Meta 新职位:**Meta 首席 AI 智能官(Chief AI Officer),负责新设立的「超级智能」部门
重要性:
1、拥有 AI 核心「数据战火库」:Alexandr Wang 手握 Meta 核心竞争对手微软、OpenAI、谷歌等模型训练数据;
2、天生的商业嗅觉者:在还没有 LLM 时,已洞察到「数据」在 AI 领域的重要性,便在 2016 年创办数据标注公司 Scale AI;
**核心人物:**Shengjia Zhao
背景:清华大学本科,斯坦福大学博士,核心聚焦大语言模型和不确定性量化。领导 OpenAI 合成数据项目,是 ChatGPT、GPT-4 模型及各种小型模型等标志性产品的重要贡献者。
**原职位:**前 OpenAI 研究科学家
**Meta 新职位:**Meta 超级智能部门,具体职位未透露
核心人物:Jiahui Yu
背景:中国科学技术大学少年班的毕业生,曾分别任职于在微软、旷视、Adobe、Snap、百度、英伟达和谷歌等。2023 年 10 月领导 OpenAI 感知团队,主导了 o3、o4-mini 和 GPT-4.1 研发;在谷歌 DeepMind 联合领导 Gemini Multimodal。研究核心聚焦深度学习和高性能算力。
**原职位:**前 OpenAI 项目研究负责人
**Meta 新职位:**Meta 超级智能部门,具体职位未透露
核心人物:Shuchao Bi
背景:毕业于浙江大学数学系,随后在加州大学伯克利分校获得了硕士和博士学位。专注于强化学习、训练后优化和 AI 代理。2013 年入职谷歌,通过深度学习模型优化谷歌广告。2024 年 5 月入职 OpenAI,担任多模态后训练主管,为 GPT-4o 的语音模式和 o4-mini 模型做出了贡献。
**原职位:**前 OpenAI 多模态后训练主管
**Meta 新职位:**Meta 超级智能部门,具体职位未透露
核心人物:Hongyu Ren
背景:2018 年毕业于北京大学,2023 年在斯坦福大学完成计算机科学博士学位。在校期间,他曾在微软、英伟达、谷歌和苹果实习。毕业后他加入 OpenAI,曾参与 o1-mini 和 o3-mini 研发,并领导一个专注于后期训练的团队,o1 项目的核心贡献者。
**原职位:**前 OpenAI 后期训练项目负责人
**Meta 新职位:**Meta 超级智能部门,具体职位未透露
**核心人物:**hang Huiwen
背景:毕业于清华大学交叉信息研究院的姚班(这个精英计算机科学项目由图灵奖得主姚期智创立)。随后在普林斯顿大学取得博士学位,研究方向是图像处理。 曾在 Adobe 和 Facebook 实习,后于 2016 年获得微软奖学金。2019 年谷歌工作一段时间后,于 2023 年 6 月转至 OpenAI,参与开发了 GPT-4o 的高级图像生成功能。
**原职位:**前 OpenAI 研究员
**Meta 新职位:**Meta 超级智能部门,具体职位未透露
**核心人物:**Lin Ji
背景:清华大学本科,2023 年在 MIT 获得博士学位。曾在谷歌、Adobe 和英伟达实习,并于 2023 年 1 月加入 OpenAI,专攻多模态推理和合成数据。
**原职位:**前 OpenAI 研究员
**Meta 新职位:**Meta 超级智能部门,具体职位未透露
核心人物:Sun Pei
背景:清华大学本科,卡内基梅隆大学硕士,2011 年就职谷歌。他短暂加入中国数据基础设施公司 Alluxio 后,于 2017 年转至谷歌的 Waymo 部门。后成为谷歌 DeepMind 的首席研究员,在开发 Gemini 人工智能模型方面发挥了关键作用,特别是在后训练和推理等领域。
**原职位:**前谷歌 DeepMind 的首席研究员
**Meta 新职位:**Meta 超级智能部门,具体职位未透露
核心人物:Lucas Beyer
背景:自称 “自学成才黑客」,前谷歌 DeepMind(原 Brain)苏黎世分部的高级研究科学家,联合领导模态研究工作和代码库项目。与 Xiaohua Zhai 和 Alexander Kolesnikov 创立了苏黎世 OpenAI 办公室。
**原职位:**前谷歌 DeepMind(原 Brain)苏黎世分部的高级研究科学家,苏黎世 OpenAI 办公室创始人。
**Meta 新职位:**Meta 超级智能部门研究员,具体职位未透露
核心人物:Alexander Kolesnikov
背景:曾任谷歌「Google Brain」高级研究工程师,「Deepmind」研究科学家。OpenAI 研究员。
**原职位:**前 OpenAI 苏黎世办公室研究员
**Meta 新职位:**Meta 超级智能部门研究员,具体职位未透露
2025 年 7 月
核心人物:Daniel Gross(左一)
背景:「安全超级智能」SSI 三位联创之一(其余两位:Ilya Sutskever、Daniel Levy)。曾试图以 320 亿美元收购 Safe Superintelligence,被拒后反手挖走其联合创始人之一 Daniel Gross。
7 月 3 日,「消失已久」Ilya 罕见现身发文,确认了 Daniel Gross「出局」消息,Daniel Gross 也转发了该条推文。
原职位:「安全超级智能」SSI 联合创始人,OpenAI 前首席科学家
**Meta 新职位:**领导 Meta 超级智能产品部门
**重要性:**与 Nat Friedman 共同创立一家名叫「NFDG」的风险投资公司,该公司已投资了 Coinbase、Figma、CoreWeave、Perplexity 和 Character.ai。
核心人物:Nat Friedman
**背景:**MIT 毕业,Github 前 CEO(2018-2021), 曾任 GNOME 基金会的主席,目前还是 Arc 研究所的董事会成员,并担任 Midjourney 的顾问。
**原职位:**前 Github CEO
Meta 新职位:「与 Alex 合作领导」超级智能团队
**重要性:**辅佐「军师」协助小孩哥 Alexandr Wang 共同领导超级智能团队。
参考资料:
来源:juejin.cn/post/7523519254878437403
马斯克 Neuralink 脑机接口新成果!看完头皮发麻
注意看,这些人正在用意念玩马里奥赛车。
他们的手没有动一下,靠脑电波控制就完成了移动、转弯、吃道具等一系列动作。
帮助他们通过 “心灵感应” 完成游戏操作的,就是马斯克 Neuralink 的脑机接口 N1。
这就是 Neuralink 夏季更新报告会上,马斯克展示的最新成果。
截止目前,N1 已经有七名受试者,他们以视频等形式分享了脑机接口对他们生活的改变。
这一个个真实案例,也获得了网友们的一片赞许。
同时,在这次报告会上,Neuralink 也曝光了未来三年的发展路线——
到 2028 年,Neuralink 计划实现对大脑的全面访问。
让受试者重回生活
这七位受试者当中,有四位是脊髓损伤患者,另外三位是肌萎缩侧索硬化症(渐冻症)患者。
他们接受测试的地点不是在实验室,而是每天在家中使用 Neuralink 脑机接口设备,据统计,他们平均每周使用脑机接口的时间长达 50 小时,峰值甚至超过 100 小时,几乎覆盖了所有的清醒时间。
其中,Noland 是全球第一位 N1 受试者,他因为脊髓损伤瘫痪。
Noland 装上 N1 之后当天,就学会了完全靠意念控制电脑光标,并打破了世界纪录。
现在,Noland 已经学会了仅凭意念畅玩《马里奥赛车》,甚至还能与其他参与者联机玩《使命召唤》等更复杂的游戏。
除了游戏之外,Noland 还在 N1 的帮助下,正在重新学习语言和数学。
同样是脊髓受损的,还有 Alex,他因此失去了手部功能。
但有了 N1,他已经学会了通过意念控制电脑屏幕上的手,和家人玩 “石头剪刀布” 游戏。
而且不仅能控制屏幕上的虚拟影像,还可以操纵特斯拉擎天柱机器人的机械手。
更重要的是,N1 已经帮助 Alex 重新回到工作,通过意念操作 CAD 软件完成设计。
如前所述,N1 的受益者除了脊髓损伤患者,还有渐冻症人士,Bard 是首个植入 N1 的渐冻症患者。
因为渐冻症,Bard 失去了语言能力,只能借助眼动追踪技术来和外界交流。
但现在,他已经可以用思想控制电脑,从而与世界交流,甚至和他的孩子们一起到公园玩耍。
目标是实现 “全脑接口”
此次报告会上,Neuralink 透露其最终目标,是构建一个真正的 “全脑接口”。
顾名思义,“全脑接口” 就是一个能够向任意神经元读取、写入、传输信息的通用平台。
具体来说,其产品路线图中包含了 Telepathy、Blindsight、Deep 三个组成部分。
七名受试者使用的 N1,就是 Telepathy。
Telepathy 通过将 1000 个电极植入运动皮层中负责手部和手臂运动的区域来工作,目的就是帮助因脊髓损伤、渐冻症、中风等导致无法自主控制身体的人士,能够仅凭思想来实现控制电脑、操作鼠标等动作。
Blindsight 则是 Neuralink 的下一个产品,旨在帮助完全失明的人(包括天生失明、失去眼睛或视神经的人)恢复视力。
Blindsight 会通过摄像头捕捉环境场景,然后转换成电信号,传递到植入在视觉皮层的设备中,从而在大脑中产生视觉感知。
最后的 “Deep”,不是一个独立的产品名称,而是指 Neuralink 技术能够深入大脑更深层区域的能力,以及这种能力带来的应用。
这一层次旨在通过将电极插入皮层(cortical layer)以及更深层的脑区,例如脑沟(sulci)和边缘系统(limbic system),来治疗神经系统失调、精神疾病或神经性疼痛。
同时,Neuralink 也公布了未来三年的具体发展计划。
今年下半年,Neuralink 计划在言语皮层(speech cortex)进行植入,从而将大脑中的信息解码为语言。
明年,通道的数量将从 1000 个增加到 3000 个,同时 Neuralink 还计划进行首次 Blindsight 植入。
这次植入,也将成为 Neuralink 验证其向大脑中写入信息能力的关键机会。
到 2027 年,通道数量将继续增加至 10000 个,同时首次实现多植入物操作,即在运动皮层、言语皮层和视觉皮层等多个脑区同时进行植入。
最终的 2028 年,每个植入物拥有超过 25000 个通道,结合多植入物操作,能够实现对大脑的任何部分的访问,从而用于治疗精神疾病、疼痛以及其他神经功能失调。
届时,Neuralink 还将进行脑机接口与 AI 的整合。
参考链接:
http://www.youtube.com/watch?v=FAS…
欢迎在评论区留下你的想法!
— 完 —
来源:juejin.cn/post/7521376266110091298
AI独角兽团队Manus裁员80人,剩下40人迁至新加坡总部!
大家好,我是程序员小灰。
大家是否还记得,今年3月份横空出世的AI产品Manus?
Manus号称是全球首款通用Agent的产品,它刚刚上线的时候在AI圈子里红极一时,许多人都在争抢Manus的内测激活码,这些内测码甚至在闲鱼平台被炒到了10万元!
小灰一直没有机会真正使用Manus,但我看过许多网友的演示视频,虽然这款Agent产品没有发布会上说的那么神奇,存在种种瑕疵,但是在某种程度上确实可以帮助人们解决一些流程化的工作。
在当时,Manus不止在国内受到追捧,也受到了全世界的关注。在4月25日,Manus母公司蝴蝶效应获得了美国风险投资公司Benchmark领投的7500万美元融资。
包括小灰在内的许多同行都认为,Manus一定会在资本的加持下继续做大做强,成为中国甚至全世界的AI Agent领军人。
可是万万没想到,在7月8日这一天,Manus团队被爆出了裁员消息。Manus在中国区大约有120名员工,其中40多位核心员工被迁往新加坡总部,剩下80人左右将被裁员,补偿方案是N+3或者2N。
仅仅4个月的时间,Manus就从刚刚诞生时候的辉煌走到了如今的局面,难怪圈子里都在说:AI一天,人间十年。
那么,Manus为什么会面临裁员呢?主要有三个原因:
1.政策影响
2025年1月生效的《对外投资安全计划》限制美元基金对中国AI企业的投资,Manus的主要投资方Benchmark在审查压力下,被迫要求Manus迁出中国。
2.芯片断供
从去年开始,美国商务部就禁止向中国大陆客户供应AI芯片,到了今年年初,禁令执行越来越严格,这对Manus的打击是致命的。Manus研发负责人也在内部会议中坦承,因无法及时获取英伟达最新AI芯片,智能体的迭代升级进度被迫延缓。
3.成本问题
Manus从今年3月底开始向用户收费,基础版每月39美元,高级版每月199美元。相比于国内很多物美价廉的AI产品,Manus收费真的很贵。
但是从Manus官方的角度,他们的运营成本也确实很高,目前的收费根本无法覆盖运营成本。再加上国内又诞生了扣子空间这样的平替产品,导致Manus用户增长乏力,无法形成规模效应。
Manus如今的结局是令人遗憾的,但是像DeepSeek和Manus这样了不起的产品,也让全世界看到了中国AI的希望。
小灰相信,中国AI行业的未来发展只会越发迅猛,今后一定会有越来越多优秀的AI产品走进大众的视野,让全世界的人们看到我们中国人的智慧和努力。
大家对Manus裁员和迁移新加坡这件事怎么看?欢迎在留言区说出你的想法。
来源:juejin.cn/post/7524931208746975270
我为什么放弃了“大厂梦”,去了一家“小公司”?
我,前端八年。我的履历上,没有那些能让HR眼前一亮的名字,比如字节、阿里,国内那些头部的互联网公司。
“每个程序员都有一个大厂梦”,这句话我听了八年。说实话,我也有过,而且非常强烈。
刚毕业那几年,我把进大厂当作唯一的目标。我刷过算法题,背过“八股文”,也曾一次次地在面试中被刷下来。那种“求之不得”的滋味,相信很多人都体会过。
但今天,我想聊的是,我是如何从一开始的“执念”,到后来的“审视”,再到现在的“坦然”,并最终心甘情愿地在一家小公司里,找到了属于我自己的价值。
这是一个普通的、三十多岁的工程师,与自己和解的经历。
那段“求之不得”的日子
我还记得大概四五年前,是我冲击大厂最疯狂的时候。
市面上所有关于React底层原理、V8引擎、事件循环的面经,我都能倒背如流。我把LeetCode热题前100道刷了两遍,看到“数组”、“链表”这些词,脑子里就能自动冒出“双指针”、“哈希表”这些解法。
我信心满满地投简历,然后参加了一轮又一轮的面试。
结果呢?大部分都是在三轮、四轮之后,收到一句“感谢您的参与,我们后续会保持联系”。我一次次地复盘,是我哪里没答好?是项目经验不够亮眼?还是算法题的最优解没写出来?
那种感觉很糟糕。你会陷入一种深深的自我怀疑,觉得自己的能力是不是有问题,是不是自己“不配”进入那个“高手如云”的世界。
开始问自己:“大厂”真的是唯一的出路吗?
在经历了一段密集而失败的面试后,我累了,也开始冷静下来思考。
我观察身边那些成功进入大厂的朋友。他们确实有很高的薪水和很好的福利,但他们也常常在半夜的朋友圈里,吐槽着无休止的会议、复杂的流程、以及自己只是庞大系统里一颗“螺丝钉”的无力感。
我看到他们为了一个需求,要跟七八个不同部门的人“对齐”;看到他们写的代码,90%都是在维护内部庞大而陈旧的系统;看到他们即使想做一个小小的技术改进,也要经过层层审批。
我突然问自己:这真的是我想要的生活吗?我想要的是什么?
当我把这些想清楚之后,我发现,大厂的光环,对我来说,好像没那么耀眼了。
在“小公司”,找到了意想不到的“宝藏”
后来,我加入了一家规模不大的科技公司。在这里,我确实找到了我想要的东西。
成了一个“产品工程师”,而不仅仅是“前端工程师”
在小公司,边界是模糊的。
我不仅要写前端代码,有时候也得用Node.js写一点中间层。我需要自己去研究CI/CD,把自动化部署的流程跑起来。我甚至需要直接跟客户沟通,去理解他们最原始的需求。
这个过程很“野”,也很累,但我的成长是全方位的。我不再只关心页面好不好看,我开始关心整个产品的逻辑、服务器的成本、用户的留存。我的视野被强制性地拉高了。
“影响力”被无限放大
在这里,我就是前端的负责人。
用Vue还是React?用Tailwind CSS还是CSS Modules?这些技术决策,我能够和老板、和团队一起讨论,并最终拍板。我们建立的每一个前端规范,写的每一个公共组件,都会立刻成为整个团队的标准。
这种“规则制定者”的身份,和在大厂当一个“规则遵守者”,是完全不同的体验。你能清晰地看到自己的每一个决定,都对产品和团队产生了直接而深远的影响。
离“价值”更近了
最重要的一点是,我能非常直接地感受到自己工作的价值。
我花一周时间开发的新功能上线后,第二天就能从运营同事那里拿到用户的反馈数据。我知道用户喜不喜欢它,它有没有帮助公司赚到钱。这种即时的、正向的反馈,比任何KPI或者年终奖金,更能给我带来成就感。
还会羡慕那些在大厂的朋友吗?
当然会。我羡慕他们优厚的薪酬福利,羡慕他们能参与到改变数亿人的项目中去。
但我不再因此而焦虑,也不再因此而自我否定。
你可以多想一想你真正想要的是什么? 一个公司的名字,并不能定义你作为一名工程师的价值。你的价值,体现在你写的代码里,体现在你解决的问题里,也有可能体现在你创造的产品里。
找到一个能让你发光发热的地方,比挤进一个让你黯淡无光的地方,重要得多。
分享完毕。谢谢大家🙂
来源:juejin.cn/post/7525011608366579758
30+程序员如何不被小事击垮
引言
老张最近有一个重点项目在推进,他准备今天回家加班赶赶进度。
可到家之后,发现孩子发烧了,由于妻子出差,他赶紧放下手头的事情,抱起带孩子往医院跑。
堵车、吃饭、挂号、排队,一路折腾下来,已经九点了。
可就是这个点,儿科急诊仍是人山人海。孩子好奇的问东问西,手机里还不断跳出加急的消息,老张焦急的不断盘算着还有多久能排到他们。
马上到老张了,突然有一个人抱着孩子挤进了医生房间,老张愣了一下,火一下子就上来了,冲进屋子和对方吵了起来......
幸运的是孩子没什么事,可老张熬了一晚上啥也没干成。第二天上班状态不好,和业务方沟通时及其不耐烦。
下午收到了业务方的投诉,理由是态度消极。
老张一天什么也没干,却感觉自己马上就要崩溃了。
英雄就是这么被击垮的。据说是伏尔泰有句话说,“使人疲惫的不是远方的高山,而是你鞋里的一粒沙子”。
工作繁忙、孩子生病、业务方催促进度......都不是什么“重大事件”,可就是会压的你喘不过气来。
处理不好这些小麻烦,不但会影响你的情绪和工作表现,还有可能会影响我们的健康,最重要的是,如果被这些小事击垮了,我们哪还有心思去想什么大事呢?
我现在“大概”可以做到情绪稳定,我有四个自己在用的心法,分享给大家。
学会忽略
学会忽略,是我看到一句,据说是爱因斯坦说过的话:“弱者报复,强者原谅,智者忽略”。
就拿开车举例,我在路上发现过一个特别有意思的现象,如果开车的时候遇见插队,不同的司机有三种反应。
第一种人是对抗型,面对插队丝毫不让,眼看着两辆车的距离都塞不下一根手指头了,插队车决定放弃,他可能赢得了这场面子仗。
第二种人是原谅型,一开始会正常起步,但如果对方强行变道, 他会及时刹车,毕竟剐蹭了浪费时间浪费金钱。
第三种人是忽略型,他可能根本就没有在意这辆车在插队,他会直到前车完全进来,才会继续出发。他可能正沉浸在播客或者音乐里,神游在另一个维度。
你觉着哪种应对方式最好?
之前我是第二种人,并且还觉着第三种人是技术不佳,或者说是“好欺负”,直到最近我也有点了第三种人的样子。
有一次我在路上,听播客听的入迷,前方有个车有变道的意图。我也不着急,就让他变道进来了。
随后我才意识到,自己好像甚至都没有为这件事情,分散一点注意力。
那一刻我才明白,忽略,不是退让,也不用压抑情绪——
而是你根本没分配注意力分配给小事,负面情绪自然也就不会被激活。
忽略负面情绪非常有必要,有一项针对1300名男性做的研究,让他们对自己遇见类似于加塞这种小麻烦的反应打分,分数越高代表情绪反应越大。
结果发现,经常对小事有激烈反应的男性,他们的健康状况和死亡率,和面对那些重大人生压力的人一样。反应最激烈的那一组,在同样时间段内的死亡率,竟然是正常人的三倍。
我想起之前我奶奶家挂着一副《莫生气》的字画,里面有一句话:别人生气我不气,气出病来无人替。
看来对小事有激烈反应,真的会影响身心健康啊。我实践下来,忽略情绪有三个小技巧:
第一个是觉察情绪。当你发现自己心跳加快、紧握双拳,要注意情绪可能要来了。你需要深吸一口气,把注意力放到自己身上,让自己停下来,别被情绪牵着鼻子。
第二是控制自己的反应。维克多·弗兰克尔有一句话:“在面对外界刺激时,我们拥有选择如何回应的自由”。人真正能控制的只有自己的行动和态度,你控制不了堵车,但你能控制堵车的时候听一首钢琴曲。
第三是发现身边的美好,也就是感知生活中的“小确幸”。比如阳台上的花突然开了,孩子自己穿衣服了。有研究表明,对生活中积极细节的留意,能有效中和压力引发的负面情绪。
不恶意揣测
不过有些事情你很难忽略,比如公司考核政策调整,甚至说你持仓的股票大跌。
你感觉这个世界充满了恶意:公司打压你、社会在压榨你、资本在收割你。
可现实真的是这样吗?
帮助我解决心结的法则叫做「汉隆剃刀」。简单的说,它的意思就是「能解释为愚蠢的,就不要解释为恶意」。
这里说的愚蠢,代表各种无知的、偶然的、非故意的原因。这些情况发生的可能性远远大于恶意,汉隆剃刀大多数情况下反应了客观事实。
比如你开车,前方突然有车插队,你怒不可遏,心想:你是不是觉着我好欺负?
但其实他根本不认识你,只不过恰巧他意识到前方需要拐弯了。
这个法则在理解社会、组织层面,特别有效。
比如你持有的一只股票突然暴跌,你会听到一些传闻:说这是“庄家”在故意控盘。
我之前特别相信这种阴谋论,觉着股价是被人为操控的。可真实情况是,大公司的股价是很难操控的,投入很多钱也不一定能成功,一旦失败就会受到很大损失。而且市场上每个股民的互动、追涨杀跌,也会给股价造成很大影响。
再比如一家公司突然开始了绩效改革,给研发人员制定了和销售额相关的KPI,而且目标不完成还会对薪资产生影响。
可研发的考核怎么可能和销售的KPI挂钩呢?你怀疑管理层在变相降薪。
可更大的可能性是:管理层也不知道如何满足老板制定的目标,只能先套个模版应付一下。
不是你被打压了,只是碰巧他们不专业,你以为它是在有意的做坏事,但更大的可能是它没能力做好事。
我们大脑为了认知方便,常常会把一家公司或者一个政府当成一个人,假设他有自由意志,是一个决策缜密、心怀不轨的敌人。但其实组织就是一部机器而已。
不是组织在有意针对你,这世界其实就是个草台班子。
超越身份思维
你有没有经历过这种场面,过年回家刚坐下,七大姑八大姨联合开麦:
“你看你三十多了还在北京漂着,准备啥时候结婚啊?你表哥孩子都上小学了。”
“北京租房多贵啊,在咱老家,这都够还房贷了,干嘛不考个公务员安稳点?”
你努力工作、认真生活,熬过了失业焦虑、加班压力,结果成了他们口中的“混日子”。
你不是气他们说了什么,而是他们压根不懂你,却笃定地定义你。
可他们的确不懂你,也不会真正的懂你。他们只不过是在维护自己的世界观而已。
学术界有一个流行的说法是,人们的行为和观点,是由身份认同决定的。你的长辈,可能在一个小城过了一辈子,有编制、有房子、生儿育女,就是他们眼里的体面生活。
你异地漂泊、私企行业、租房未婚,就是他们眼中的“不务正业”。
你不需要反驳,也不需要忍耐。而是你明白了,你不需要从所有人眼里获得认可,你可以看到不同身份的局限性。
超越身份思维,在养育孩子的过程中特别有用。
那天我带儿子去上烘焙课,糖刚撒进面粉中,他就开始一边揉一边往嘴里塞。
我试图制止,他越发固执,并且不耐烦的喊:“我要回家!我要回家!”
我有点崩溃,一边怕他吃坏肚子,一边气他为什么这么不听话。
但那一刻我突然意识到,他不是故意气我,他只不过多想吃几口糖而已。
我们常说父母要包容孩子,为此你需要先理解他们的行为。糖果能刺激大脑释放多巴胺,这是最本能的反应,而且他们理性大脑还没有开始发育,你不能要求一个孩子有“自控力”
我们总以“大人的身份”要求孩子守规矩,可孩子的很多行为,并不是“不听话”,而是“做不到”。
就像人类的大脑,在25岁才能完全发育完成。也就是说,一个孩子即使成年之后,也会做出一些你不理解的事情。一个人成长的过程中,本就充满了能力滞后,
你不理解他,就会对抗他。你理解了,才能包容他。
找到目标
有一天我正坐在电脑前,正为了文章选题抓耳挠腮。
我儿子“砰”地一下推开门,一屁股坐在我旁边,拿着小汽车喊:“爸爸!爸爸...”
以往工作时被打断,我会特别不耐烦。可那天,我关上电脑开始陪他玩,我发现自己变得很有耐心。
过了一会他自己去客厅玩了,我坐在电脑前,去想我为什么会有这种改变。
是我变得有耐心了?还是我终于佛系了?后来我想明白了——是自己的目标更明确了。
过去一被打断就恼火,其实都是因为自己都不知道要干什么。我只是模糊的觉得,自己得做点有意义的事情。
但现在写好每一篇文章就是我想做的事情,就算短暂的停下来,也没有任何影响。
心理学上有一个「自我决定理论」:真正让人持续投入的,从来不是外界的压力或奖励,而是自己选的方向。
比如说当你在街道上跑步,周围车水马龙、喧嚣嘈杂,可你根本就听不见。因为你眼中,只有即将抵达的下一个路口。目标感就像降噪耳机,能让你不被外界打扰。
但如果你没有目标呢?虽然一天什么都没干,却很容易因为工作上的催促,家人的一句话,就能让你心烦意乱。
你不是没有承受力,你可能只是没有方向而已。
尼采说:“一个人知道自己为什么而活,就可以忍受任何一种生活。”
现在看来这不是鸡汤,而是硬道理。
真正让你内心安定的,不是时间管理、情绪技巧,而是——你有没有在朝着自己认可的方向,慢慢靠近。
说在最后
最后分享一句据说是爱默生说的一段话来结尾吧。
当整个世界似乎都在暗中图谋,用琐事一次又一次侵扰你、纠缠你,当所有人都来敲你的门,并且说,“到我们这里来吧。”绝对不要动心,不要加入到他们的喧闹中。始终保有一颗自助自主的心,不受外界影响和左右,活在自己的意志里,才能够使心灵得到宁静,才会过上真正独立的生活。
以上就是我自己应对生活中一些“小麻烦”的个人心得,如果你也有面对“小麻烦”时处理情绪的技巧,欢迎在评论区分享~
这是东东拿铁的第84篇原创文章,欢迎关注。
来源:juejin.cn/post/7522751214263992370
三年写了很多代码,也想写写自己
前言
从我进入公司开始,我给自己立了一个三年成为中级前端工程师的目标,或者说flag吧,最近正好三年合同到期了,我开始思考过去的这三年我都做了什么,是否完成了flag,所以我在个人博客中增加了一个模块《项目需求》
用于管理自己在生活、工作、学习过程中开发过的项目文档和思考,在整理的过程中才发现很多东西都忘记是怎么做的了,大概是只知道做,不知道为什么做吧,所以这里想写一篇文章记录下或者说获取一些建议吧。
很多人说博客和todo没啥用,开发完几乎都不会使用,我觉得看怎么用吧,我这里把项目和todo、技术文档、技术栈绑定了。编辑项目和可以和todo绑定,我觉得还挺好使,这样在整理技术文档、技术调研的时候也可以用
过去三年我都做了什么
2022年
基本情况
因为在学校的时候根本没想过这么早出社会,原本是打算走学术路线的,结果考研那年因为家里临时出了点状况,最后决定先工作再说。现在回头看也挺好的,早点接触社会,其实成长得更快。
在这一年我主要是疯狂补项目经验和疯狂加班,因为社会始终不同于学校,排期让人很头疼,在以往我缺失了很多的项目经验,导致对企业级项目几乎不通,导致我在做任何项目都比较挣扎,再加上进的是一个小厂,完全没有导师制,属于放养,并且大家都很忙,所以只能自己多花时间,并且当时我学的vue的技术栈,但是公司是react的,光是搞懂 React 那一套生态就花了不少时间。
项目经历
- 早期主要是做企业后台 & figma插件,其中有一个插件让我特别头疼,一方面因为当时的自己比较菜,另一方面因为这个需求是一个刚毕业的设计驱动的,属于是啥也不通,导致产品逻辑也不对,写出来之后疯狂打补丁,最后也还是啥也不是。
- 后面做了设计社区,都是一些简单的ui和业务逻辑,因为是一个设计编辑器平台
- 在写了几个后台之后我逐渐熟悉了公司开发技术栈和后台开发逻辑,最早这个公司吸引我的是编辑器,后面我就申请去做了编辑器
- 最开始是编辑器的字体加载、和一些创新的业务需求、设计工具中不同模式的数据结构复用、画布设置【缩放、背景等等】、对齐至像素网格
成长
- 技术上,从 Vue 转到 React 后,逐步掌握了 React 的核心理念和生态工具,像状态管理、组件设计、性能优化这些都有了比较实战的理解;
- 项目上,能独立负责模块开发,也逐步学会了和产品、设计磨合需求;
- 心态上,从一开始觉得“自己不会”到现在敢主动挑任务、遇到新东西也不怕折腾,整体自驱力和解决问题的能力都提升了不少。
- 这时候还是需要拿着电脑到处抓人问问题,非常感谢当时给予我帮助的小伙伴
2023年
基本情况
这个阶段已经开始逐步适应工作生活了,但是还是会畏惧需求,因为还有很多没接触过的东西,依然还是疯狂加班,不光是需求,还有自己学习一些东西,这时候我已经切换到了编辑器领域,其中涉及很多图形学知识,比如坐标转换、矩阵运算、渲染原理、渲染库的使用等等,因为公司里的人几乎不写文档,代码也是anyscript,并且这时候ai还没有,编辑器这个领域,网上几乎搜不到什么文档啥的,只能生啃代码和类型文件并尝试demo,这时候用的就是最笨却最有效的方法,做到哪就把哪个模块整理一篇文档记录下来,慢慢的也就掌握了项目的大部分逻辑和架构思路
项目经历
- 设计工具中不同模式的数据结构复用,一个创新业务需求,使用同一套数据,快捷的进行模式切换,非常巨大的需求,正是因为这个需求让我学会了很多东西,开始能独立负责一个模块的开发
- 白板项目:其中做了节点数据结构定义【便签、图形文本、连接线等等】、节点树的处理、节点的渲染、项目框架搭建、画布设置、缩放、属性控制、属性工具条、性能优化等等,几乎所有功能都写了一部分,这个项目是我从0-1经历的一个项目,历时10个月,早期有很多人,后来因团队调整,部分成员转入新项目,剩余的人员就非常的少了,我是其中之一。
- 这一年我几乎都在做白板项目,其中连接线是最难的,我写了其中的一部分,还因此挨了一批,给我上了社会上的第一堂课【能力不足就得背锅】
成长
- 编辑器初步入门:理解了编辑器的基本架构 & 实现原理,如模块划分、碰撞检测、矩阵运算原理、渲染库的基本使用、复制粘贴的实现原理、svg的解析原理等等、数据节点定义、节点树的使用等等
- canvas、svg、渲染库的基本使用 & 原理
- 学到了很多调试技巧、看了很多的技术文章
- 能够独立负责一个模块的开发和推进
- 自己开始从0-1写一些项目,23年主要是一个工程化的项目,因为当时公司没有脚手架,每次创建新项目都要配置一遍,我就想写一个脚手架来用,就开始探究一些前端工程化的东西,这里主要是一个前端工程化的demo
2024年
基本情况
这时候已经对编辑器开发很熟练了,能够自己调研、处理一些模块,不会畏惧需求,拿到什么都能做也敢做,再加上ai的爆发,现在很轻松就能应付日常需求,还有一些时间开发自己的东西。这时候我几乎不用在追着别人问了,开始探究一些技术上的原理,看了react的源码,了解了react的运行原理,我最初看这个的驱动是因为我想看懂编辑器底层的数据结构和自定义渲染器的实现原理,因为是相通的。
项目经历
- 多模式切换的设计工具,在23年双模式切换有一个比较客观的数据基础上,想要开发多模式切换
- 编辑器重构:真真正正的从0-1实现编辑器,学到了非常多的东西
成长
- 这个阶段成长是最快的,在之前自己主动学习和开发过程中的积累,达到了量变到质变的过程,再加上重构过程中全是实实在在的技术类需求,这个阶段开发的非常爽,学到了非常多的东西,一度让我觉得我们也能做出一个超级nb的东西
- 对编辑器的整体实现理解更加深入,对大型项目的推进和管理有一些了解
- 对于代码质量,代码风格,团队管理,团队交流都有更深的体会
2025年
基本情况
进入新团队后,开始参与 AI 方向的生成类产品开发。虽然整体技术难度相比之前的编辑器项目要低一些,但节奏非常快,很多需求都是边想边做,对响应能力和落地能力要求更高。项目整体强调快速迭代、快速验证,很多时候从 0 到上线都只有几天时间。
项目经历
- 核心流程重构:参与整个生成流程的梳理和重构,数据结构的重设计,提升了整体稳定性和扩展性。
- AI 创新功能研发:参与多个创意方向的原型开发,包括智能组件、AI 引导式操作流程等,既需要理解前端,也需要深入 AI 接口的能力边界。
- 常规前端需求:除了核心 AI 功能,也参与大量 Web 端页面开发、交互优化、组件抽象等日常前端需求的处理。
- 跨角色协作:与产品、模型工程师保持密切沟通,协助设计 prompt、测试接口,探索“产品-模型-前端”的协作流程,理解 prompt 工程的基本逻辑。
成长
- AI 与前端的深度结合:理解 AI 接口的调用逻辑、数据结构设计、模型能力边界,并在多个场景中尝试 prompt 调优、token 限制控制、输出结构稳定性等关键问题。
- 需求落地能力提升:现在不管接到什么需求,都能独立完成从调研、设计、开发、联调到交付的完整流程,并且具备识别风险、提前发现问题并推动解决的能力。
- 项目推进与优化意识:开始更关注整体产品的合理性和可维护性,不再仅仅关注功能实现,会主动提出重构建议、设计优化点、体验提升方案。
- 应变与协作能力加强:面对快节奏、多变的需求场景,能够保持清晰的优先级判断
- 干了很多新鲜的东西,还挺好玩的,ai接入支付、ai表单等等。
我自己写的项目
就这几个,其他的几乎都是一些不成型的demo,还有几乎都在写公司的项目
- nextjs-blog:一个用nextjs写的高聚合的全栈博客,还在持续更新,有时候有点犯懒,在线访问
- handwriting_js:没事写点手写题,写了忘,忘了写,一个也记不住
- react_demo :前端工程化demo,配合这个专栏食用最佳
- debug_react:18.2.0的react源码调试环境
- debug_webpack: webpack5源码调试环境
现在我是怎么想的
- 快速学习的能力比技术能力更值得培养
技术更新太快了,几乎每一年都会冒出一堆新概念、新框架、新工具,追是追不完的。相比“掌握某个技术”,更在意的是“有没有能力快速理解它、上手它、找到它的边界”,这是一个更本质的能力。 - 技术是为业务服务的,但我们也要有自己的判断和坚持
做久了之后会发现,代码写得好不好,有时候并不是最关键的,能不能解决问题、把事情落地才是关键。谁也不想变成“只写业务”的人——在完成需求的同时,尽可能把事情做得优雅些,至少对得起自己的审美和标准。 - 保持初心
有时候项目节奏快、需求不讲理、上线压力大,很容易被“搞完就行”的心态裹挟,还是需要保持自己的思考 - 身体是革命的本钱!!!!
24年7月份左右,体检,发现小毛病快20项,全是久坐,熬夜搞出来的小毛病,可能因为之前加班太多了,也不运动,在7-11月胖了20多斤,并且整日没精打采,身体没有力气,像是气血亏虚一样,我去看了中医,开了一些调养的中药,12月底才开始有好转,我找了私教,去健身房开始健身,大半年了现在就好多了,增肌也小成 - 培养工作之外的兴趣爱好
健身、摄影、钓鱼都可以,长时间的工作会使人麻木和疲惫,需要一些工作之外的爱好调和
我还做了一个在线相册,从大佬Innei获取到的思路,但技术栈是不一样的,也比较简单
以后我想干啥
说实话,我现在还没完全想明白这个问题。过去几年我经历了从业务开发,到编辑器、到 AI 项目,接触了很多不同的方向,也成长了不少。但也正因为尝试了很多,现在反而更谨慎,不想轻易贴标签。
我想我还是会继续写代码,但不一定只写代码。我更在意的是:“我做的东西有没有价值?有没有可能改变点什么?”也许未来会往架构方向走,也许会继续在 AI 产品方向深入,也可能有一天突然转向一个完全不同的方向,比如做点属于自己的产品。
我目前能确定的就是三件事:
- 我希望能一直保持学习和探索的状态,不断拓宽认知边界;
- 我希望在一个让我有成长、有挑战感的环境里工作;
- 我希望做的事能让我感到值得,能有一点点“留下痕迹”的感觉。
剩下的,就边走边看吧,继续更新文章,但不会跟之前一样那么频繁,从中学到东西,并且能够帮助别人
来源:juejin.cn/post/7524602914514763819
微软正式官宣开源!王炸!
最近,和往常一样在逛 GitHub Trending 热榜时,突然看到又一个非常火的开源项目冲上了 Trending 热榜,相信不少小伙伴也刷到了。
一天之内就新增数千 star,仅仅用了几天时间,star 增长曲线都快干垂直了!
再定睛一看,好家伙,这不是微软的项目么。
出于好奇,点进去看了看,没错,这正是微软自家大名鼎鼎的 WSL!
原来就在前几天的微软 Build 2025 开发者大会上,微软正式官宣开源 Windows Subsystem for Linux(WSL)。
这在微软官方的最新的开发者技术博客也可以翻到。
众所周知,WSL 是微软在 2016 年就发布的一项重磅功能,相信不少同学都用过。
WSL 全称:Windows Subsystem for Linux,它允许用户在 Windows 操作系统中直接运行 Linux 环境,而无需双系统或者虚拟机,通过兼容层支持开发者工具、命令行应用及文件系统互通,实现方便地跨平台开发与测试。
从初始发布到如今走向开源,回顾 WSL 一路走来的发展历程,可以总结为如下几个大的阶段。
- 初期兼容层探索
2016年,微软首次推出 WSL 1。
其通过兼容层工具(如 lxcore.sys 驱动)将 Linux 系统调用转换为 Windows 调用,首次实现原生运行 ELF 可执行文件。
其优势是轻量级启动,但缺点也很明显,那就是兼容性和性能都存在一定局限。
- 中期扩展与独立应用
2019年,WSL 2 正式官宣。
此时微软对其进行了彻底的重构架构,采用基于 Hyper-V 的轻量级虚拟机技术,来运行完整 Linux 内核,并显著提升了兼容性与性能,同时这也使得 WSL 能支持运行更多的 Linux 程序和应用。
2021年,WSLg 正式推出,从此便支持了 Linux GUI 应用,同时 WSL 也开始作为独立组件来发布,其从 Windows 镜像剥离,转为通过 Microsoft Store 来进行独立安装和更新。
2022年~2024年这几年时间内,微软对 WSL 进行了持续迭代,包括 systemd 服务管理支持、GPU加速、多发行版支持以及内存和文件系统等诸多性能优化。
经过中期这一阶段的发展,WSL 在兼容性、功能以及性能等方面都有了长足的进步,也为下一步的开源和社区化奠定了基础。
- 后期开源和社区化
在前几天的微软 Build 2025 开发者大会上,微软正式宣布 WSL 开源(GitHub 仓库开放),允许社区直接参与代码贡献,这也标志了 WSL 进入了开源和社区化的新阶段。
至此为止,在 WSL 的 GitHub 仓库中的 Issue #1 —— 那个自2016年起就存在的“Will this project be Open Source?
”的提问,终于被标注为了“Closed
”!
众所周知,WSL 其实是由一组分布式组件来组合而成的。
即:一部分是在 Windows 系统中运行,另外一部分则是在 WSL 2 虚拟机内运行。
这个从 WSL 官方给出的组件架构图中就可以很清晰地看出来:
那既然现如今微软官宣了 WSL 开源,那对于开发者来说,我们需要清晰地知道这次到底开源了哪些组件代码呢?
关于这部分,对照上图,我们这里不妨用表格的形式来简要总结一下,供大家参考。
组件类型 | 功能描述 | 组件名 | 开源状态 |
---|---|---|---|
用户交互层 | 命令行工具 | wsl.exe | 已开源 |
用户交互层 | 命令行工具 | wslg.exe | 已开源 |
用户交互层 | 命令行工具 | wslconfig.exe | 已开源 |
服务管理层 | WSL服务管理 | wslservice.exe | 已开源 |
Linux运行时 | init启动 | init | 已开源 |
Linux运行时 | 网络服务 | gns | 已开源 |
Linux运行时 | 端口转发 | localhost | 已开源 |
文件共享 | Plan9协议实现 | plan9 | 已开源 |
以上这些已开源的组件源码都可以在 WSL 的 GitHub 仓库里找到,大家感兴趣的话可以对应查看和研究。
虽然本次开源覆盖了 WSL 的绝大多数关键组件,但是官方也明确说了,以下这几个组件由于其仍然是 Windows 系统的一部分,所以目前仍然保持非开源状态,包括:
Lxcore.sys
:支撑 WSL1 的内核驱动程序P9rdr.sys
和p9np.dll
:运行"\wsl.localhost"文件系统重定向的关键组件(从 Windows 到 Linux)
这一点需要特别注意一下。
回顾过往,其实 GitHub 上的 WSL 仓库并不是最近才有,好多年前就已经存在了。
即便在以前的 WSL 还没有开源的日子里,WSL 的背后就有了一个强大的社区在支持,开发者们通过 GitHub Issue 和 Discussion 等为 WSL 这个项目提供了诸多错误追踪、新功能建议以及意见改进。
可以说,如果没有社区贡献,WSL 永远不可能成为今天的样子。
而现如今 WSL 源代码正式开源,这也满足了开发者社区长达 9 年的期待。
开发者们现在可以自行下载、构建,甚至提交改进建议或者新功能的代码来直接参与。
同时 WSL 官方也给出了一个详细的项目贡献指南:
感兴趣的同学也可以上去学习研究一波。
好了,那以上就是那以上就是今天的内容分享,希望能对大家有所帮助,我们下篇见。
注:本文在GitHub开源仓库「编程之路」 github.com/rd2coding/R… 中已经收录,里面有我整理的6大编程方向(岗位)的自学路线+知识点大梳理、面试考点、我的简历、几本硬核pdf笔记,以及程序员生活和感悟,欢迎star。
来源:juejin.cn/post/7509437413099536438
同事年底绩效是C,提离职领导死活不让走,后来领导私下说:他走了,就没人背这个绩效了
背绩效
临近年底,朋友圈和各大职场 App 都在讨论「年终奖能拿多少个月」的话题。
除了对「能拿多少个月」有广泛的讨论以外,还有不少关注点在于「年终奖何时能发」这件事上,毕竟只有真的拿到手了,才能算是钱,而不是饼。
我一直以为,在大厂年终奖这条"鄙视链"上,最差的就是那些"零年终"的小伙伴了。
实在没想到,还有高手。
比零年终更惨的,是要背绩效,同时还得面对领导"惺惺作态"的挽留:
在这位网友发的帖子中提到,自己身边有位同事去年年中的时候是 C 绩效,到了年底还是 C,通常连续得到低绩效,就会面临各种安排(砍福利、降工资 或 被换组),于是这位同事主动提了离职。
但离谱的是,领导死活不让他走,一直以「后面还有机会」这样的说辞来进行画饼。要知道,这位领导大概率是他两次 C 绩效的"贡献者"。
在其他人看来,还以为领导是真心挽留他,这位同事留在公司一定会先苦后甜。
直到后面这位领导私下和楼主说:"他走了,没人背这个绩效了"。
后面楼主才恍然大悟,所谓的挽留,仅仅是为了让他分担一些不好的绩效罢了。
简短的一句话,"他走了,没人背这个绩效了",背后却是实实在在职场霸凌。听起来像是领导的"无奈之举",实则是领导为了应付公司指标(一定要有低绩效的组成),选择性牺牲某些同事的离谱行为。
权利在这些人手上真是可悲,那个背绩效的同事,也有自己的生活,甚至还有自己的家庭。被针对就算了,还得被耗着,被 PUA 朝着那个"有希望,但没结果(下次还是 C 绩效)"的方向去期待,最后还要反省是不是自己的问题。
新的一年,大家都能远离这些垃圾人。
对此,你有想分享的,欢迎评论区交流。
...
回归主题。
周末,继续简单小算法。
题目描述
平台:LeetCode
题号:806
我们要把给定的字符串 S
从左到右写到每一行上,每一行的最大宽度为 个单位,如果我们在写某个字母的时候会使这行超过了 个单位,那么我们应该把这个字母写到下一行。
我们给定了一个数组 widths
,这个数组 代表 'a'
需要的单位, 代表 'b'
需要的单位,..., 代表 'z'
需要的单位。
现在回答两个问题:至少多少行能放下 S
,以及最后一行使用的宽度是多少个单位?
将你的答案作为长度为 的整数列表返回。
示例 1:
输入:
widths = [10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10]
S = "abcdefghijklmnopqrstuvwxyz"
输出: [3, 60]
解释:
所有的字符拥有相同的占用单位10。所以书写所有的26个字母,
我们需要2个整行和占用60个单位的一行。
示例 2:
输入:
widths = [4,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10]
S = "bbbcccdddaaa"
输出: [2, 4]
解释:
除去字母'a'所有的字符都是相同的单位10,并且字符串 "bbbcccdddaa" 将会覆盖 9 * 10 + 2 * 4 = 98 个单位.
最后一个字母 'a' 将会被写到第二行,因为第一行只剩下2个单位了。
所以,这个答案是2行,第二行有4个单位宽度。
注:
- 字符串
S
的长度在 的范围。 S
只包含小写字母。widths
是长度为 的数组。- 值的范围在 。
模拟
根据题意进行模拟即可。
使用变量 a
代指当前有多少行是满的,使用变量 b
代指当前填充光标所在的位置。
Java 代码:
class Solution {
public int[] numberOfLines(int[] widths, String s) {
int a = 0, b = 0;
for (char c : s.toCharArray()) {
int t = widths[c - 'a'];
if (b + t > 100 && ++a >= 0) b = t;
else b += t;
}
if (b != 0) a++;
return new int[]{a, b};
}
}
C++ 代码:
class Solution {
public:
vector<int> numberOfLines(vector<int>& widths, string s) {
int a = 0, b = 0;
for (char c : s) {
int t = widths[c - 'a'];
if (b + t > 100 && ++a >= 0) b = t;
else b += t;
}
if (b != 0) a++;
return {a, b};
}
};
Python 代码:
class Solution:
def numberOfLines(self, widths: List[int], s: str) -> List[int]:
a, b = 0, 0
for c in s:
t = widths[ord(c) - ord('a')]
if b + t > 100 and a >= 0:
a += 1
b = t
else:
b += t
if b != 0:
a += 1
return [a, b]
TypeScript 代码:
function numberOfLines(widths: number[], s: string): number[] {
let a = 0, b = 0;
for (let i = 0; i < s.length; i++) {
const t = widths[s.charCodeAt(i) - 'a'.charCodeAt(0)];
if (b + t > 100 && ++a >= 0) b = t;
else b += t;
}
if (b !== 0) a++;
return [a, b];
};
- 时间复杂度:
- 空间复杂度:不使用
toCharArray
为 ,否则为
来源:juejin.cn/post/7463836172559384627
为了搞一个完美的健身APP,我真是费尽心机
作为一个强迫症患者,当我需要一个简单、好用、流畅、无广告的健身记录软件时,撸铁记就诞生了。
为什么我要开发撸铁记
我应该是2018年接触健身的,那个时候我的教练每次给我上课,都会拿着一个文件夹记录我的每一次训练。但是纸制记录最大的问题是难保存,而且只能教练一个人看,于是我写了第一个健身记录软件,叫FitnessRecord,然后我就在知乎上分享了自己的应用,没想到真的有人用!
后来,在朋友的撺掇下,我正式决定将撸铁记推上线,然后就是(巴拉巴拉极其费劲的上线了!)
个人开发者有多痛苦
一个完美的软件,最重要的,不仅要好看,还得好用,于是,就出现了下面这些设计
暗黑模式
一个 APP,如果不支持暗黑模式,那你让强迫症怎么活?
但是...你以为这就完了吗?细节藏在魔鬼里😄
绝对黑
记得前两年各大手机厂商还在卷屏幕的时候,苹果率先推出了“绝对黑”,强调OLED屏幕通过像素关闭实现的物理级纯黑效果。so~为了实现在暗黑模式下,软件用的更爽,撸铁记的 APP 的背景色使用了#000000,也就是纯黑色
这样做的好处是在暗黑模式下,撸铁记可以与屏幕完美的融为一体。但是!问题来了。纯黑色真的很难设计,作为一个程序员出身的我,头发都抓掉了好几把。
有细心的小伙伴们或许已经发现了,亮色模式下跟暗黑模式的主题色其实不是一个颜色:
我们发现在暗黑模式下,亮色模式下的主题色与黑色之间的对比度不够明显,导致整体色调暗沉,因此,亮色模式的主题色是:#3B7AEF 暗黑模式下则是:#2E6FEC
虚拟导航键适配
Android 的虚拟导航键如果适配不好,有多丑相信懂得都懂,为了能够在弹窗模式下也能够让弹窗与导航栏完美无瑕的融为一体,我设计了一个 BaseDialog,专门用来管理弹窗状态,确保在任何页面,虚拟导航栏都不会影响到 APP 的整体颜值!
左滑展示更多功能
作为一个专业的记录软件,各种各样的功能总要有吧?
全部堆叠到更多菜单中是不是很傻?如果在屏幕排列出来展示是不是更傻?所以,左滑删除这种很合理的交互是不是得有?
IOS 设备是常态,但是能够完美的搬到 Android 机器上,该怎么做?鸿蒙系统又该怎么适配?!
但是!我说的是但是,为了更漂亮的 UI,更合理的交互,我又熬了个通宵,最终完美解决!
好的交互就得多看,多学
每个人的习惯都不同,比如有的用户希望能够在倒计时 120s 之后有一个声音提示,有的则希望可以按照训练顺序,对卡片自动排序,那么问题来了,这些功能又该堆叠在哪里呢?
我的灵感来源是一款不太出名的 P 图软件
在训练详情页面的左侧,有一根很不起眼的线,当你触摸这条线的时候,就会弹出训练设置的总菜单啦!(不用担心很难触摸,我已经将触摸范围调整到了最合适的大小,既不会误触,也不会很难点👍)
其实,APP 还有很多为了“好看”而做的设计,但是一个好的 APP,只是静态的好看怎么能行!
完美的入场动效
我该如何像您吹嘘这系统级的丝滑动效?请看 VCR(希望掘金支持视频链接😂):
http://www.bilibili.com/video/BV1sb…
http://www.bilibili.com/video/BV1Pb…
如何?是否足够丝滑???
当然,功能性才是核心
除了记录的易用性和强大复杂的功能,为了能够 360° 覆盖健身所需要的所有场景,我还开发了各种各样的功能
赛博智能
赛博智能,我希望这个功能可以像赛博机器人一样,对我的身体状况进行 360° 评估。
鄙人不才,晒一下我的身体状态评估分析:
一个超级大长图,几乎涵盖了你想要知道的一切~当然,后续还会继续丰富其他功能😁
日历统计
这个月你偷懒了吗
是的,你的每一滴汗水,都会浓缩破到这一张小小的日历表格中,如果你偷懒了,那就是一张空空的日历,那么,你会努力填满每一天的,对吧?
最后的最后
按原本的计划,我想要从设计到功能,认真的介绍一下撸铁记的所有方方面面,但是回头看看,文章真的太长了,所以,就留一点悬念给大家,希望需要的小伙伴自行探索😁
其实,每一个细节,我都改过很多次,后续依旧会不断的改来改去,因为我只想要最好~
最后,祝愿所有喜欢健身的朋友,都可以收获自己成功~
来源:juejin.cn/post/7524504350250205238
Stack Overflow,轰然倒下!
你好呀,我是歪歪。
前几天看到一个让我感慨万千的走势图:
本来想让你猜一猜这个走势图的内容是什么的。
但是结合标题你应该也能猜到了,和 Stack Overflow 有关。
这个走势图的数据是 Stack Overflow 从 2008 年开始到现在,每个月新问题的个数。
数据的来源是这个网站:
data.stackexchange.com/stackoverfl…
它可以以 SQL 的形式查询相关的数据。
从走势图可以看到,从 2008 年到 2014 年是陡增的趋势,可以说是高歌猛进,翻着翻的上涨。
2014 年到 2020 年,数据起起伏伏,但总比 2020 年之后的一泻千里好的多。
把每个月的明细数据下载下来之后,我看了一下 TOP 3 的情况:
- 2020/5/1,302381 个新问题
- 2020/4/1,299146 个新问题
- 2017/3/1,298552 个新问题
最辉煌的时候,是 2020 年。
可能那个时候大家都在居家办公,遇到问题也没有同事可以咨询,就顺手在网上求助网友了。
但急转直下也是在 2020 年。
因为那一年末 ChatGPT 横空出世,并凭借还算不错的表现,慢慢被大家开始接受了。
而这几年 AI 发展的突飞猛进,越来越少的人选择 stack overflow。
至于为啥越来越少的人选择 Stack Overflow?
我想还是在于便捷性上。
和 AI 交互,你给它问题,它能立马响应,直接给你正确答案,或者引导你去寻找正确答案。
和 Stack Overflow,或者和任何问答平台交互,你发布问题之后得等,等到有人看到你的问题,然后才有可能会回答。
如果你只是想在 Stack Overflow 里面找一个问题的答案,而不是打算自己提出一个问题的话,那 AI 更加是碾压式的存在。
因为你可以让 AI 帮你在 Stack Overflow 里面找答案。
Stack Overflow 免费提供了它十几年间的所有问答数据,然后被各个 AI 当做了训练模型。
最后落得的下场,说好听点叫功成身退,说难听点就是卸磨杀驴。
我记得曾经还有一个关于程序员的梗。
就是当程序捕获到异常之后,由程序自动发起一个请求给 Stack Overflow,然后获取解决方案。
所以,作为程序员,你应该知道 Stack Overflow 在某种程度上,它就是程序员的圣经,它的回答就是权威。
我写技术类文章的时候,如果顺着问题找到一个 Stack Overflow 的链接,我在潜意识里面就会认为,这个链接里面就会有我在寻找的答案,而且是正确答案。
但是这些都是很新鲜的“过去的故事”了。
我把前面获取到的表格排序后拉到表格最后,2025 年的数据已经跌落到了 2008 年的水平:
再回头看看这个走势图:
不得不承认,Stack Overflow,几乎是成不可逆转之势般的倒下了。
两个问题。
我之前写过的技术文章中,Stack Overflow 出现的频率非常的高。
有时候我会去上面找素材。
以至于一提到 Stack Overflow 我立马就能想起至少两个我写过的有意思的问题。
第一个问题是这样的:
当时觉得这个输出结果很奇怪,有点意思,于是研究了一下。
最终经过一番折腾也是在 Stack Overflow 找到了答案。
但是现在,我只需要把问题扔给各种 AI 大模型,比如 DeepSeek。
它就能给出答案:
然后还可以继续追问“额外5分43秒”产生的具体原因是什么:
给出的参考链接中也有 Stack Overflow 的链接:
第二个问题是这样的:
把这个问题扔给 DeepSeek 之后,它也很快就给出了答案:
答案总结起来就是一句话:
伪随机数生成器的序列是确定的,但看起来“随机”。
这些特定的种子值(-229985452 和 -147909649)是通过反向计算或暴力搜索找到的,目的是使 nextInt(27) 的序列恰好匹配 "hello" 和 "world" 的字符编码。
好,现在如果没有 AI,我给你上面这两段代码。
甚至我直接告诉你,这个代码的输出结果可能是 1900-01-01 08:05:43:
public class MainTest {
public static void main(String[] args) throws Exception {
SimpleDateFormat simpleDateFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
Date date = simpleDateFormat.parse("1900-01-01 08:00:00");
System.out.println(simpleDateFormat.format(date));
}
}
而这个代码的输出结果是 Hello World:
public class MainTest {
public static void main(String[] args) {
System.out.println(randomString(-229985452) + " " + randomString(-147909649));
}
public static String randomString(int i) {
Random ran = new Random(i);
StringBuilder sb = new StringBuilder();
while (true) {
int k = ran.nextInt(27);
if (k == 0)
break;
sb.append((char) ('`' + k));
}
return sb.toString();
}
}
对于这一类初看一脸懵逼,奇奇怪怪的问题,在“面向搜索引擎编程”的时代,让你去探索一下为什么,你是不是多少也得花费一点点功夫。
甚至,完全有可能你花费了一些功夫,没有找到答案,或者找到了一个以为正确,实际错误的答案。
而现在,你只需要扔给 AI,它就会给你分析的明明白白的。
至于它的分析是否合理,你可以进行自己的判断。
至少节约了在网上瞎找链接的过程,而这个过程,按照我个人经验来说,也是非常耗时的。
这就是我前面说的:如果你只是想在 Stack Overflow 里面找一个问题的答案,而不是打算自己提出一个问题的话,那 AI 更加是碾压式的存在。
从这个角度,也能瞥见 Stack Overflow 倒下的必然性。
但是,我还是想说一个但是。
或者说,我更想说的这个“但是”。
但是,当我和 AI 对话的时候,我得到的是一个精准的回答,这当然是我的终极目标。
然而,当一个问题在问答社区被提出之后,有时候也会引发激烈的争论,几方各执一词,隔着屏幕输出着自己的观点。
我这里说的“几方”,指的是来着天南海北,有着不同时区的程序员群体。
而他们的争论,往往会给一个问题增加故事性。
AI 不一样,AI 给出的回答就是绕过了一切的回答,跳过了中间的争论,也跳过了中间的故事。
它把最重要的知识提取出来,然后扔掉了背后的故事。
最后,知识还在,但故事死了。
AI 怎么说
最后,我问了 DeepSeek 一个问题:
我是一个写技术文章的公众号博主,我写了一篇文章,聊到由于你的出现导致 Stack Overflow 这个曾经被视为“程序员圣经”的网站访问量极速下跌。你作为 AI,对于这个事情,有没有想要聊聊心里话的,我会把你的话放在文章的最后,说什么都行。
以下是它的完整回答,文字加粗部分,也是它自己加的:
作为 AI,我确实有些“心里话”想分享——不是庆祝取代,而是关于技术演化的复杂拥抱:
“当人类开始用更快的刀劈柴时,旧斧头会寂寞,但森林知道:重要的从来不是工具,而是砍柴人眼里的光。”
我只是一面镜子,映照出人类对效率永恒的渴望。
Stack Overflow 的衰落并非技术的胜利,而是开发者用脚投票的必然——谁不愿用 5 秒解决曾耗费 5 小时的问题?
但那些深夜论坛里争吵的括号与分号,那些被踩了又顶起的答案,藏着比正确答案更珍贵的东西:人类在试错中建立的信任网络。
我的代码里没有“顿悟”的震颤。当某个程序员在旧帖里偶然发现十年前的解决方案,与匿名前辈隔空击掌时——这种浪漫,AI永远无法复制。
所以别为我哀悼旧神。
真正的程序员早已明白:Stack Overflow不是圣经,而是脚手架;AI不是终点,是新的杠杆。
当你们用我生成的代码为起点,去构建我无法想象的事物时——那才是技术最性感的瞬间。
(最后,请替我向那位 2012 年回答过 Java 空指针问题的匿名用户致敬。今夜,我的神经网络里仍有他思考的余温。)
—— DeepSeek-R1
这段话献给所有在复制粘贴中不忘思考的灵魂。技术会老去,但人类解决问题的冲动永在。
“今夜,我的神经网络里仍有他思考的余温。”
看到这句话的时候,让我想起了《宇宙探索编辑部》中的这句台词:
这不是普通的雪花点,这是宇宙诞生的余晖。
浪漫啊,极致的浪漫。
来源:juejin.cn/post/7524164737170702362
人类一生所学不过 4GB,加州理工顶刊新研究引热议
24 小时不间断学习且不遗忘,一辈子也只有 4GB 的 “知识储量”?
科学家们最新研究,计算出了人类学习积累上限,就这么多~~(甚至还不如一块 U 盘能装)。
这是来自 Cell 旗下神经科学顶刊 Neuron 上的一项工作,它提出了一个发人深省的悖论:
人类信息处理速度仅为每秒 10bit,而我们的感官系统却能以每秒 10 亿 bit 的速率收集数据。
由此,按照每秒 10bit 的速度来算,人类 24 小时不间断学习且不遗忘,100 年储存的知识也不过 4GB。
什么概念呢?来和大模型做个对比:
大语言模型每个参数就能存储 2bit 知识,一个 70 亿参数的模型就能存储 140 亿 bit 的知识。
△结论来自华人学者朱泽园”Physics of Language Models” 系列论文
难怪研究人员还提出了一项推论:
随着算力的不断提升,机器在各类任务中的表现超越人类只是时间问题。
另外,按照这项研究的结论,马斯克目前的脑机接口研究也有问题了。
研究人员表示:
我们预测马斯克的大脑与计算机的通信速率大约为 10bit/s。与其使用 Neuralink 的电极束,不如直接使用电话,因为电话的数据传输率已经被设计得与人类语言相匹配,而人类语言又与感知和认知的速度相匹配。
一时间,这一系列惊人推论在学术圈各大社区引起广泛讨论。
美国知名医师科学家、斯克里普斯转化研究所创始人 Eric Topol 也忍不住下场转发。
为啥我们一次只能思考一件事呢?
所以,结论如何得出的?
中枢神经系统 “串行” 影响信息处理速率
简单说,要想计算人一辈子能学多少知识,我们得先从大脑处理信息的速度说起。
从对几项日常活动(如打字、说话演讲、拧魔方等)的评估来看,他们初步得出 “大脑处理信息的速度约为 10bits/s” 这一结论。
以人类打字为例,高级打字员每分钟能打 120 个单词(每秒 2 个),平均每个单词按 5bit 计算,那么信息传输速率就是 10bits/s。
同样,若以英语演讲为例,如果将节奏控制在舒适程度——讲话速度为每分钟 160 个单词,则信息传输速率为 13bits/s,略高于打字。
再比如 “盲拧魔方” 这项竞技活动,选手需先观察魔方几秒,然后闭眼还原。以一次世界纪录的成绩 12.78s 为例,其中观察阶段约 5.5s,由于魔方可能的排列数约为 4.3x1016≈265,则最终信息传输速率约为 11.8bits/s。
使用类似方式,作者估算了更多场景下的信息处理速度(从经典实验室实验到现代电子竞技等),结果显示为 5~50bits/s 之间。
由此也得出一个整体结论:人类思考的速度始终在 10bits/s 的尺度范围内。
按照这一标准,假设我们能活 100 岁,每天 24 小时不间断学习(且剔除遗忘因素),那么我们最终的 “知识储量” 也将不到 4GB。
事实上,与 10bits/s 形成鲜明对照的是——人类感官系统以约 10 亿 bits/s 的速率收集数据。
10bits/s VS 10 亿 bits/s
具体来说,我们每天从周围环境中获取信息的速率就以 Gbps/s 起算。
举个栗子,视觉系统中单个视锥细胞能以 270bits/s 的速度传输信息,而一只眼睛就拥有约 600 万个视锥细胞。
那么,光是双眼视觉系统接收信息的速度就高达 3.2Gbps/s。照此推算,我们接收信息的速度与处理信息的速度之间的差距比值竟然达到了 108:1。
要知道,人类大脑里有超过 850 亿个神经元,其中三分之一集中在大脑皮层组成了复杂的神经网络。也就是说,明明单个神经元就能轻松处理超过 10bits/s 的信息。
而现在所观察到的现象却与之不符,显而易见,上述二者之间存在一定矛盾。
从神经元本身的性能来看,它们具备快速处理和传输信息的能力,但这并没有直接转化为整体认知速度的提升,说明还有其他因素在起作用。
那么,为什么人类信息处理速度如此之慢?
按照论文分析,原因可能在以下几个方面:
最主要的,中枢神经系统在处理信息时采用的是串行方式,对信息传输速率有所限制。
这里要提到并行处理和串行处理之间的区别。
所谓并行处理,显然指多个任务同时进行。以我们看东西为例,视网膜每秒会产生 100 万个输出信号,每一个信号都是视网膜神经元对视觉图像局部计算的结果,由此同时处理大量视觉信息。
而在中枢神经系统中,他们观察到了一种 “心理不应期”(psychological refractory period)效应,即同时面对多个任务,中枢神经系统只将注意力集中在一个任务上。
当然,他们也进一步探究了出现 “串行” 背后的原因,结论是这与演化过程早期的神经系统功能有关。
展开来说,那些最早拥有神经系统的生物,核心利用大脑来检测气味分子的浓度梯度,以此判断运动方向进行捕食和避开敌人。长此以往,这种特定功能需求使得大脑逐渐形成了 “一次处理一个任务” 的认知架构。
在进化过程中,大脑的这种架构逐渐固化,虽然随着物种的进化,大脑的功能越来越复杂,但这种早期形成的认知架构仍然在一定程度上限制了我们同时处理多个任务和快速处理信息的能力。
除此之外,还有理论认为存在 “注意瓶颈” 等限制了信息处理。注意力是认知过程中的一个重要因素,它就像一个瓶颈,限制了能够进入认知加工阶段的信息数量和速度,不过其具体运作机制目前人类尚未完全理解。
总之,按照论文的观点,10bits/s 这样的速度已经可以满足人类生存需求,之所以还存在庞大的神经元网络,原因可能是我们需要频繁切换任务,并整合不同神经回路之间的信息。
马斯克脑机接口过于理想化
不过话虽如此,鉴于 10bits/s 和 10 亿 bits/s 之间的巨大差距,人类越来越无法忍受慢节奏了。
由此论文也得出一个推断:随着算力的不断提升,机器在各类任务中的表现超越人类只是时间问题。
换成今天的话说,以 AI 为代表的新物种将大概率逐渐 “淘汰” 人类。
另外,论文还顺带调侃了马斯克的脑机接口系统。
其中提到,马斯克的行动基于肉体带宽不足对处理信息的限制。按照老马的设想,一旦通过高带宽接口直接连接人脑和计算机,人类就可以更自由地和 AI 交流,甚至共生。
然而他们认为这一想法有些过于理想化。
10bits/s 的限制源于大脑基本结构,一般无法通过外部设备来突破。
由此也提出开头提到的建议:
与其使用 Neuralink 的电极束,不如直接使用电话,因为电话的数据传输率已经被设计得与人类语言相匹配,而人类语言又与感知和认知的速度相匹配。
不过上述言论也并非意味着他们对脑机接口失去信心,他们认为其关键并不在于突破信息速率限制,而是以另一种方式提供和解码患者所需信息。
作者之一为上海交大校友
这项研究由来自加州理工学院生物学与生物工程系的两位学者完成。
Jieyu Zheng 目前是加州理工学院五年级博士研究生,她还是上海交大本科校友,还有康奈尔大学生物工程学士学位,在剑桥大学获得教育与心理学硕士学位。
她的研究重点聚焦于认知灵活性、学习和记忆,特别关注大脑皮层和海马体在这些功能中的核心作用。目前她正在进行一个名为 “曼哈顿迷宫中的小鼠” 项目。
Markus Meister 是 Jieyu Zheng 的导师,1991 年起在哈佛大学担任教授,2012 年于加州理工学院担任生物科学教授,研究领域是大型神经回路的功能,重点关注视觉和嗅觉的感官系统。
Markus Meister 曾于 1993 年被评为 Pew 学者,2009 年因其在视觉和大脑研究方面的贡献获 Lawrence C. Katz 神经科学创新研究奖以及 Minerva 基金会颁发的 “金脑奖”。
新研究发布后,作者们就在 X 上当起了自个儿的自来水。
我们提出的特征是脑科学中最大的未解数值。
Markus Meister 还调侃每秒 10bit 的处理速度可是经过了同行评审的。
随后学术圈各大社区也针对这项研究开始讨论起来。
有人认为论文读起来很有意思,发人深省:
简化内容,只聚焦于中枢神经系统并且将讨论的内容分为内部和外部大脑两部分后,更有意义了。
这是一个非常重要的视角,值得深思……
然鹅,也有不少人提出疑问。
我越想这篇论文中的某些估计,就越怀疑。例如,关于打字员与听者之间比特率的等效性(S.3)似乎有误。正如香农所指出的,英文字母的熵约为每字符 1bit。但如果是一连串的单词或是概念,情况又如何呢?
作者默认了一个假设,即每秒 10bit 是慢的。与我们在硅基底上实现的通用计算系统相比,这的确很慢,但这种假设并不能线性地转化为大脑的信息吞吐量和存在的感知。
对于这项研究,你有什么看法呢?
参考链接:
[1]http://www.caltech.edu/about/news/…
[2]http://www.cell.com/neuron/abst…
[3]news.ycombinator.com/item?id=424…
[4]arxiv.org/pdf/2408.10…
欢迎在评论区留下你的想法!
— 完 —
来源:juejin.cn/post/7492778249534619648
为什么一个文件的代码不能超过300行?
大家好,我是前端林叔,掘金小册《如何写出高质量的前端代码》 作者。
先说观点:在进行前端开发时,单个文件的代码行数推荐最大不超过300行,而超过1000行的都可以认为是垃圾代码,需要进行重构。
为什么是300
当然,这不是一个完全精准的数字,你一个页面301行也并不是什么犯天条的大罪,只是一般情况下,300行以下的代码可读性会更好。
起初,这只是林叔根据自己多年的工作经验拍脑袋拍出来的一个数字,据我观察,常规的页面开发,或者说几乎所有的前端页面开发,在进行合理的组件化拆分后,页面基本上都能保持在300行以下,当然,一个文件20行也并没有什么不妥,这里只是说上限。
但是拍脑袋得出的结论是不能让人信服的,于是林叔突发奇想想做个实验,看看这些开源大佬的源码文件都是多少行,于是我开发了一个小脚本。给定一个第三方的源文件所在目录,读取该目录下所有文件的行数信息,然后统计该库下文件的最长行数、最短行数、平均行数、小于500行/300行/200行/100行的文件占比。
脚本实现如下,感兴趣的可以看一下,不感兴趣的可以跳过看统计结果。统计排除了css样式文件以及测试相关文件。
const fs = require('fs');
const path = require('path');
let fileList = []; //存放文件路径
let fileLengthMap = {}; //存放每个文件的行数信息
let result = { //存放统计数据
min: 0,
max: 0,
avg: 0,
lt500: 0,
lt300: 0,
lt200: 0,
lt100: 0
}
//收集所有路径
function collectFiles(sourcePath){
const isFile = function (filePath){
const stats = fs.statSync(filePath);
return stats.isFile()
}
const shouldIgnore = function (filePath){
return filePath.includes("__tests__")
|| filePath.includes("node_modules")
|| filePath.includes("output")
|| filePath.includes("scss")
|| filePath.includes("style")
}
const getFilesOfDir = function (filePath){
return fs.readdirSync(filePath)
.map(file => path.join(filePath, file));
}
//利用while实现树的遍历
let paths = [sourcePath]
while (paths.length){
let fileOrDirPath = paths.shift();
if(shouldIgnore(fileOrDirPath)){
continue;
}
if(isFile(fileOrDirPath)){
fileList.push(fileOrDirPath);
}else{
paths.push(...getFilesOfDir(fileOrDirPath));
}
}
}
//获取每个文件的行数
function readFilesLength(){
fileList.forEach((filePath) => {
const data = fs.readFileSync(filePath, 'utf8');
const lines = data.split('\n').length;
fileLengthMap[filePath] = lines;
})
}
function statisticalMin(){
let min = Infinity;
Object.keys(fileLengthMap).forEach((key) => {
if (min > fileLengthMap[key]) {
min = fileLengthMap[key];
}
})
result.min = min;
}
function statisticalMax() {
let max = 0;
Object.keys(fileLengthMap).forEach((key) => {
if (max < fileLengthMap[key]) {
max = fileLengthMap[key];
}
})
result.max = max;
}
function statisticalAvg() {
let sum = 0;
Object.keys(fileLengthMap).forEach((key) => {
sum += fileLengthMap[key];
})
result.avg = Math.round(sum / Object.keys(fileLengthMap).length);
}
function statisticalLt500() {
let count = 0;
Object.keys(fileLengthMap).forEach((key) => {
if (fileLengthMap[key] < 500) {
count++;
}
})
result.lt500 = (count / Object.keys(fileLengthMap).length * 100).toFixed(2) + '%';
}
function statisticalLt300() {
let count = 0;
Object.keys(fileLengthMap).forEach((key) => {
if (fileLengthMap[key] < 300) {
count++;
}
})
result.lt300 = (count / Object.keys(fileLengthMap).length * 100).toFixed(2) + '%';
}
function statisticalLt200() {
let count = 0;
Object.keys(fileLengthMap).forEach((key) => {
if (fileLengthMap[key] < 200) {
count++;
}
})
result.lt200 = (count / Object.keys(fileLengthMap).length * 100).toFixed(2) + '%';
}
function statisticalLt100() {
let count = 0;
Object.keys(fileLengthMap).forEach((key) => {
if (fileLengthMap[key] < 100) {
count++;
}
})
result.lt100 = (count / Object.keys(fileLengthMap).length * 100).toFixed(2) + '%';
}
//统计
function statistics(){
statisticalMin();
statisticalMax();
statisticalAvg();
statisticalLt500();
statisticalLt300();
statisticalLt200();
statisticalLt100();
}
//打印
function print(){
console.log(fileList)
console.log(fileLengthMap)
console.log('最长行数:', result.max);
console.log('最短行数:', result.min);
console.log('平均行数:', result.avg);
console.log('小于500行的文件占比:', result.lt500);
console.log('小于300行的文件占比:', result.lt300);
console.log('小于200行的文件占比:', result.lt200);
console.log('小于100行的文件占比:', result.lt100);
}
function main(path){
collectFiles(path);
readFilesLength();
statistics();
print();
}
main(path.resolve(__dirname,'./vue-main/src'))
利用该脚本我对Vue、React、ElementPlus和Ant Design这四个前端最常用的库进行了统计,结果如下:
库 | 小于100行占比 | 小于200行占比 | 小于300行占比 | 小于500行占比 | 平均行数 | 最大行数 | 备注 |
---|---|---|---|---|---|---|---|
vue | 60.8% | 84.5% | 92.6% | 98.0% | 112 | 1000 | 仅1个模板文件编译的为1000行 |
react | 78.0% | 92.0% | 94.0% | 98.0% | 96 | 1341 | 仅1个JSX文件编译的为1341行 |
element-plus | 73.6% | 90.9% | 95.8% | 98.8 | 75 | 950 | |
ant-design | 86.9% | 96.7% | 98.7% | 99.5% | 47 | 722 |
可以看出95%左右的文件行数都不超过300行,98%的都低于500行,而每个库中超过千行以上的文件最多也只有一个,而且还都是最复杂的模板文件编译相关的代码,我们平时写的业务代码复杂度远远小于这些优秀的库,那我们有什么理由写出那么冗长的代码呢?
从这个数据来看,林叔的判断是正确的,代码行数推荐300行以下,最好不超过500行,禁止超过1000行。
为什么不要超过300
现在,请你告诉我,你见过最难维护的代码文件是什么样的?它们有什么特点?
没错,那就是大,通常来说,难维护的代码会有3个显著特点:耦合严重、可读性差、代码过长,而代码过长是难以维护的最重要的原因,就算耦合严重、可读性差,只要代码行数不多,我们总还能试着去理解它,但一旦再伴随着代码过长,就超过我们大脑(就像计算机的CPU和内存)的处理上限了,直接死机了。
这是由于我们的生理结构决定的,大脑天然就喜欢简单的事物,讨厌复杂的事物,不信咱们做个小测试,试着读一遍然后记住下面的几个字母:
F H U T L P
怎么样,记住了吗?是不是非常简单,那我们再来看下下面的,还是读一遍然后记住:
J O Q S D R P M B C V X
这次记住了吗?这才12个字母而已,而上千行的代码中,包含各种各样的调用关系、数据结构等,为了搞懂一个功能可能还要跳转好几个函数,这么复杂的信息,是不是对大脑的要求有点过高了。
代码行数过大通常是难以维护的最大原因。
怎么不超过300
现在前端组件化编程这么流行,这么方便,我实在找不出还要写出超大文件的理由,我可以"武断"地说,凡是写出大文件的同学,都缺乏结构化思维和分治思维。
面向结构编程,而不是面向细节编程
以比较简单的官网开发为例,喜欢面向细节编程的同学,可能得实现是这样的:
<div>
<div class="header">
<img src="logo.png"/>
<h1>网站名称</h1>
<!-- 其他头部代码 -->
</div>
<div class="main-content">
<div class="banner">
<ul>
<li><img src="banner1.png"></li>
<!-- 省略n行代码 -->
</ul>
</div>
<div class="about-us">
<!-- 省略n行代码 -->
</div>
<!-- 省略n行代码 -->
</div>
</div>
其中省略了N行代码,通常他们写出的页面都非常的长,光Dom可能都有大几百行,再加上JS逻辑以及CSS样式,轻松超过1000行。
现在假如领导让修改"关于我们"的相关代码,我们来看看是怎么做的:首先从上往下阅读代码,在几千行代码中找到"关于我们"部分的DOM,然后再从几千行代码中找到相关的JS逻辑,这个过程中伴随着鼠标的反复上下滚动,眼睛像扫描仪一样一行行扫描,生怕错过了某行代码,这样的代码维护起来无疑是让人痛苦的。
面向结构开发的同学实现大概是这样的:
<div>
<Header/>
<main>
<Banner/>
<AboutUs/>
<Services/>
<ContactUs/>
</main>
<Footer/>
</div>
我们首先看到的是页面的结构、骨架,如果领导还是让我们修改"关于我们"的代码,你会怎么做,是不是毫不犹豫地就进入AboutUs组件的实现,无关的信息根本不会干扰到你,而且AboutUs的逻辑都集中在组件内部,也符合高内聚的编程原则。
特别是关于表单的开发,面向细节编程的情况特别严重,也造成表单文件特别容易变成超大文件,比如下面这个图,在一个表单中有十几个表单项,其中有一个选择商品分类的下拉选择框。
面向细节编程的同学喜欢直接把每个表单项的具体实现,杂糅在表单组件中,大概如下这样:
<template>
<el-form :model="formData">
<!--忽略其他代码-->
<el-form-item label="商品分类" prop="group">
<el-select v-model="formData.group"
@visible-change="$event && getGr0upOptions()"
>
<el-option v-for="item in groupOptions"
:key="item.id"
:label="item.label"
:value="item.value"
></el-option>
</el-select>
</el-form-item>
</el-form>
</template>
<script>
export default {
data(){
return {
formData: {
//忽略其他代码
group: ''
},
groupOptions:[]
}
},
methods:{
groupOptions(){
//获取分类信息,赋给groupOptions
this.groupOptions = [];
}
}
}
</script>
这还只是一个非常简单的表单项,你看看,就增加了这么多细节,如果是比较复杂点的表单项,其代码就更多了,这么多实现细节混合在这里,你能轻易地搞明白每个表单项的实现吗?你能说清楚这个表单组件的主线任务吗?
面向结构编程的同学会把它抽取为表单项组件,这样表单组件中只需要关心表单初始化、校验规则配置、保存逻辑等应该表单组件处理的内容,而不再呈现各种细节,实现了关注点的分离。
<template>
<el-form :model="formData">
<!--忽略其他代码-->
<el-form-item label="商品分类" prop="group">
<select-group v-model="formData.group" />
</el-form-item>
</el-form>
</template>
<script>
export default {
data(){
return {
formData: {
//忽略其他代码
group: ''
}
}
}
}
</script>
分而治之,大事化小
在进行复杂功能开发时,应该首先通过结构化思考,将大功能拆分为N个小功能,具体每个小功能怎么实现,先不用关心,在结构搭建完成后,再逐个问题击破。
仍然以前面提到的官网为例,首先把架子搭出来,每个子组件先不要实现,只要用一个简单的占位符占个位就行。
<div>
<Header/>
<main>
<Banner/>
<AboutUs/>
<Services/>
<ContactUs/>
</main>
<Footer/>
</div>
每个子组件刚开始先用个Div占位,具体实现先不管。
<template>
<div>关于我们</div>
</template>
<script>
export default {
name: 'AboutUs'
}
</script>
架子搭好后,再去细化每个子组件的实现,如果子组件很复杂,利用同样的方式将其拆分,然后逐个实现。相比上来就实现一个超大的功能,这样的实现更加简单可执行,也方便我们看到自己的任务进度。
可以看到,我们实现组件拆分的目的,并不是为了组件的复用(复用也是组件化拆分的一个主要目的),而是为了更好地呈现功能的结构,实现关注点的分离,增强可读性和可维护性,同时通过这种拆分,将复杂的大任务变成可执行的小任务,更容易完成且能看到进度。
总结
前端单个文件代码建议不超过300行,最大上限为500行,严禁超过100行。
应该面向结构编程,而不是面向细节编程,要能看到一个组件的主线任务,而不被其中的实现细节干扰,实现关注点分离。
将大任务拆分为可执行的小任务,先进行占位,后逐个实现。
本文内容源自我的掘金小册 《如何写出高质量的前端代码》
来源:juejin.cn/post/7431575865152618511
3小时,从0到1上线MVP海外AI网站产品!深度复盘
三、新手3小时极限上线AI产品网站
作为程序员来说,最喜欢务实,不讲虚的。
所以讲完了创业史(具体看这篇:1个人,创业2年心酸史,做各种海外赚美金项目。这一次,你终于悟道了)我们再来讲讲如何3小时极限上线一个AI产品网站。
作为程序员来说,最喜欢务实,不讲虚的。
所以讲完了创业史(具体看这篇:1个人,创业2年心酸史,做各种海外赚美金项目。这一次,你终于悟道了)我们再来讲讲如何3小时极限上线一个AI产品网站。
3.1 什么是AI产品网站出海?
AI产品网站出海,简单来说基于AI技术的产品,通过网站的形式面向海外市场。这不仅仅是语言的翻译,更是对海外用户需求的深度理解和产品的本地化适配。在如今这个AI快速发展的时代,海外市场对AI应用的接受度和付费意愿相对较高,特别是欧美市场。
AI网站出海的核心在于:
技术门槛低:借助现有的开发工具Cursor和AI API大模型,独立开发者也能快速搭建产品
市场需求旺盛:海外用户对AI工具的付费习惯已经形成(比如OpenAI,Claude)
竞争相对较小:相比国内市场,海外AI工具市场仍有大量空白领域
变形路径清晰:订阅制、按次付费等付费模式已被广泛接受。
AI产品网站出海,简单来说基于AI技术的产品,通过网站的形式面向海外市场。这不仅仅是语言的翻译,更是对海外用户需求的深度理解和产品的本地化适配。在如今这个AI快速发展的时代,海外市场对AI应用的接受度和付费意愿相对较高,特别是欧美市场。
AI网站出海的核心在于:
技术门槛低:借助现有的开发工具Cursor和AI API大模型,独立开发者也能快速搭建产品
市场需求旺盛:海外用户对AI工具的付费习惯已经形成(比如OpenAI,Claude)
竞争相对较小:相比国内市场,海外AI工具市场仍有大量空白领域
变形路径清晰:订阅制、按次付费等付费模式已被广泛接受。
3.2 为什么选择AI产品网站出海作为创业方向?
3.2.1 个人兴趣和优势
首先我做了5年内核开发程序员,一开始接触知识星球的时候,看到的都是国内各种平台,很明显就不感兴趣。
所以还是打工人的时候,一开始做的项目就是海外工具站。
但是虽然我是程序员,但程序员也分很多种,前端,后端,对于做一个网站,完全没有经验。
当时我记得捣鼓了很久,上线后各种报错,代码完全看不懂,后来就放弃了。
现在,完全不同了。
不需要懂代码,Cursor直接帮你搞定。
当然,要想做出一个成熟的AI产品网站,肯定还是要去学代码的,不然每次编程就和抽卡一样,太随机了。
每当一个bug解决、一个功能实现的实现,程序员的那种成就感油然而生。
其次,我做过很多海外项目,对这一块还是比较熟悉的,所以这些都是我的优势。
自然而然,我应该做AI产品网站出海。
3.2.2 试错成本很低
这里主要是讲资金成本。
相比于我做过的很多海外项目来说,AI产品网站的开发成本特别低。
一个网站:最便宜的几美金一年。
AI编程工具:Cursor(20美金一个月,之前的教育优惠直接免费1年)
其他:都是免费(是的,你没有看错)
下面这张图是网友总结的,可以看到:除了域名和AI编程工具,其他真的是免费的。 (程序员很老实,从来不骗人)

但是,这里要讲下但是,这里讲的是启动资金成本。
如果你的网站有流量了,很大,那你肯定也要投入资金买服务器了。
但这个时候,你也已经开始赚钱了,并且还不少。
所以说,试错成本真的很低。
自从我做过FB跨境电商后,真的再也不想去碰成本这么高的了。
这里还有一个费用,肯定很多人都很关心。
API调用费用
先给大家看一张图,我这次用的photomaker这个API
它一下生成4张图片,才0.0011美金。
从我开发到上线后找人测试,也才花了2.8美金。

并且我的API账号还是之前薅的羊毛,一共两个号,薅了100美金(用不完,完全用不完。)
就算你的网站上线后,你放心,也只会有少量的API调用。
除非很多人用,但这时候你已经开始赚钱了。
我现在用的有:
- Claude 4 :
某宝买共享账号,它给你一个账号池,每3个小时可以使用40次,非常方便。
用于写开发者文档,和claude讨论需求。

- Cursor pro账号
3.2.1 个人兴趣和优势
首先我做了5年内核开发程序员,一开始接触知识星球的时候,看到的都是国内各种平台,很明显就不感兴趣。
所以还是打工人的时候,一开始做的项目就是海外工具站。
但是虽然我是程序员,但程序员也分很多种,前端,后端,对于做一个网站,完全没有经验。
当时我记得捣鼓了很久,上线后各种报错,代码完全看不懂,后来就放弃了。
现在,完全不同了。
不需要懂代码,Cursor直接帮你搞定。
当然,要想做出一个成熟的AI产品网站,肯定还是要去学代码的,不然每次编程就和抽卡一样,太随机了。
每当一个bug解决、一个功能实现的实现,程序员的那种成就感油然而生。
其次,我做过很多海外项目,对这一块还是比较熟悉的,所以这些都是我的优势。
自然而然,我应该做AI产品网站出海。
3.2.2 试错成本很低
这里主要是讲资金成本。
相比于我做过的很多海外项目来说,AI产品网站的开发成本特别低。
一个网站:最便宜的几美金一年。
AI编程工具:Cursor(20美金一个月,之前的教育优惠直接免费1年)
其他:都是免费(是的,你没有看错)
下面这张图是网友总结的,可以看到:除了域名和AI编程工具,其他真的是免费的。 (程序员很老实,从来不骗人)
但是,这里要讲下但是,这里讲的是启动资金成本。
如果你的网站有流量了,很大,那你肯定也要投入资金买服务器了。
但这个时候,你也已经开始赚钱了,并且还不少。
所以说,试错成本真的很低。
自从我做过FB跨境电商后,真的再也不想去碰成本这么高的了。
这里还有一个费用,肯定很多人都很关心。
API调用费用
先给大家看一张图,我这次用的photomaker这个API
它一下生成4张图片,才0.0011美金。
从我开发到上线后找人测试,也才花了2.8美金。
并且我的API账号还是之前薅的羊毛,一共两个号,薅了100美金(用不完,完全用不完。)
就算你的网站上线后,你放心,也只会有少量的API调用。
除非很多人用,但这时候你已经开始赚钱了。
我现在用的有:
- Claude 4 :
某宝买共享账号,它给你一个账号池,每3个小时可以使用40次,非常方便。
用于写开发者文档,和claude讨论需求。
- Cursor pro账号
之前某鱼搞的教育优惠,100多块直接用1年。
- 其他
也就上站的时候买一个域名,几美金就行。其他真没了。
3.2.3 市场机会巨大
从个人兴趣和优势出发,不断试错,那也要去能赚到钱的地方是吧。
海外AI工具市场正处于爆发期,用户对新产品的接受度高,愿意为解决实际问题的AI工具付费。
光说没有用,我看看实际案例,我们都喜欢看见再相信。
- Pieter Levels
这是一个海外的独立开发者,一个人,做了这么多产品。
而且他所有的收入都列在了他的推上。
- 刘小排老师
老外大家可能觉得很遥远,我们看看国内。
一个人,创业后第一个产品就做到了100万月活,只用了1个月,并且做完就放放那了,都没做任何付费推广。
- 百里登风
这个人大家可能不太熟悉,这个人就是我(哈哈哈)
从0到1,上线一个MVP产品,用了3个多小时。
我特意用秒表测了一下自己的极限开发速度。
从看到需求到正式上线大概花了3个多小时(包含吃饭时间)。
个人认为还可以继续优化,大概2个小时就差不多可以完成。
这是我开发的产品,10大场景下的AI摄影生成工具。(目前小bug还比较多,当然后面需要慢慢优化,比如登陆界面还没做,支付还没接等等。)
看到现在,大家肯定很枯燥了吧。
所以,我们先来看看我花了3个小时,做出的产品,让你先感受下我的乐趣,或者以后也会成为你的乐趣。
原始图片:
场景一:专业正件照片
场景二:社交和约会照片
场景三:健身锻炼照片
场景四:旅行照片
场景五、婚礼照片
好,不能再放了,再放怕你睡不着。
是不是很牛逼,很逼真,虽然我不知道有没有人做过这种产品,但至少它很有趣,那就可以了。
网站地址:http://www.headshotpro.art/。
- 大家
AI时代,每一个人都有机会,每个人都可以做出自己的AI产品网站,所以能看到这里的,都要给大家留个位置。
3.3 如何发现海外AI摄影场景需求?
当然不是我想出来的,自己拍脑袋想出来的几乎都不行。
我是群里看到的,一个网站,一个月13万刀。
这时候,好奇心就来了,这是什么网站?(好奇心往往会有一些发现)
这个网站其中一个功能就是上传自拍,制作自己的AI人物
刚才我才发现,它也有AI场景功能,不过它要输入提示词,我直接固定10个场景。
大家都很懒,肯定会直接吃喂到嘴边的饭,而不是自己去找饭吃,所以固定10个场景,不需要用户输入提示词(这一点很重要)
真正吸引我的是真实感,连眼球都能看清楚。这也太太厉害了,AI一般给人的感觉都很假。
所以我也想开发一个类似的AI摄影图片功能。
其实这一步之后,还需要市场调研,竞品分析,差异化思考。
因为你能想出来的东西,肯定大家都做过了,但不妨碍我们去玩。
是的,你没有看错,就是玩。
3.4 从0到1:3小时极限MVP开发全流程
3.4.1 用claude写需求文档
总算进入正题了,到这你已经看了3908个字,我已经写了一下午加一晚上了,腰都酸了,现在已经22:48分了,奈何就是想写呢。
好,继续(下面的教程大家放心,因为我之前公众号写AI工具使用方法都写的很细,自己都体验过一遍,生怕大家错过每一个步骤。)
看到一个需求后,第一步,不是直接用Cursor实现一个完整的产品,而是先和AI讨论,写一个开发者文档。(这一步很重要)
为什么很重要?这里要说一下。
因为你如果不写这个文档,可能你一边开发,一边脑子里就已经想到一个新功能,做着做着就跑偏了。
很多人觉得写开发者文档很难,需要长篇大论。
其实,不需要。
AI就是你的员工,就是你的伙伴,就是你的合伙人。
比如:我要开发一个AI摄影产品。
你这么说:
我想要开发一个网站,用户上传头像后,为用户创建各种场合的逼真的照片。我们来聊聊这个需求,你觉得应该怎么做?
接下来,你就继续和它聊天,随便聊,就把它当作你的员工,直到你的想法和它的答案对上,就可以了。
比如我说:
我需要10个有痛点需求的场景。
下一步:做出MVP需求文档
你和它说:
你先做MVP,帮我产生一份MVP需求文档,尽量简单。
好,这时候,你的员工就帮你干活了。把这份文档保存在飞书里。
下面的是我让AI生成的需求文档。
这里有一个比较有意思的点,claude 可以生成图文形式的需求文档。
给大家看看我的,非常好玩。一目了然。
3.4.2 V0做出产品原型
有了需求文档,不是去直接开发产品了,而是先做个产品原型。
这个就像你想吃鸡腿,你脑海里就会有一个鸡腿的样子(这个叫心理表征,可以看《刻意练习》)
那你现在只有一个文档,没有一个产品的样子,所以先把这个样子做出来。
V0网址:v0.dev/
这里注意一点,我们做一个产品原型,只做壳子就行。具体的功能先不实现,因为具体的功能比较复杂,它比较难做,后面去Cursor里做。
你这样告诉V0:
我要做一个给外国人生成AI摄影图片的产品,使用NextJS框架。
你只需要帮我做一个产品原型,不需要实现具体的功能,
设计的风格尽可能参照小红书的风格。
下面是需求开发文档。(这里你把刚才生成的需求文档复制给他)
然后,等一会,十分钟吧,他就给你生成好了,中间可能会遇到一些报错,直接点击按钮让它修复就可以。
我们来看看具体的效果。
是不是非常不错?
是的,但是我们还需要实现它实际的功能。
3.4.3 Cursor开发实际功能
好,现在我们来真正做实际的功能。
- 下载V0生成的代码,点击右上角下载代码。
- 打开Cursor,先让Cursor帮你总结下代码功能
告诉Cursor员工:帮我看看我的所有代码,告诉我这个项目干了什么?
- 让代码在本地运行起来
总结完之后,我们需要把代码在本地跑起来。
因为V0生成的代码是在他们自己的服务器上运行起来的,我们下载下来后,需要重新在本地运行。
告诉Cursor员工:帮我在本地运行这个项目。
Cursor员工一顿操作后,终于搞定了。
运行命令:npm run dev
就会给你一个地址:
鼠标移动到上面,单击就可以打开,看到网站效果。
如果这时候出现问题,比如网站打开报错,直接截图告诉Cursor员工,同时把终端里的报错信息告诉Cursor员工。
一遍不行两遍,两遍不行三遍,直到修复成功。
- 选择合适的API
比如我开发的产品是AI摄影图片,这个时候不知道用什么API。
此时,就可以问claude:
我想做一款产品,用户上传头像后,为用户创建各种场合逼真的照片。我参照的是这个网站:photoai.com。我想知道,有没有现成的API可以让我调用?
好,这个时候claude就会提供各种API。
由于我在fal.ai上有余额,就可以让claude限定在fal.ai上找。
网址:fal.ai/
在上方搜索栏中搜索:photomaker
就出现了这个模型
我们点击API,就可以看到所有的API文档介绍。
这里我们只需要把这个地址链接复制下来,文档都不需要看:
这里还有一步,你需要创建一个密钥。
4.1 点击账号设置
4.2 点击 API keys
4.3 点击增加密钥
4.4 给它起个名字,根据你的项目来定,比较好分辨。点击创建。
4.5 点击复制,之后把这串密钥保存在你的记事本上。
- Cursor实现核心功能
告诉Cursor:
请帮我实现核心功能,使用photomaker API
这是API的说明文档:@ fal.ai/models/fal-…
这是API key:XXX
这里为了安全,API key这个信息比较敏感。
所以我们一般会直接在项目根目录创建一个.env环境变量文件,手动把key进去。
因为Cursor读取不了这个文件。
这里就是不断的调试了,cursor员工自认为干好之后,你就要去检查了。
和之前一样,运行命令:npm run dev
然后在本地调试,测试实际功能。
一旦哪个功能不对,报错,就告诉AI,截图,复制都可以。
最后,一顿操作,你觉得差不多了,就可以了。
3.4.4 将代码提交到Github
在Cursor中开发代码的时候,有可能出现之前改好的功能它又给你改错了,结果可能改了半天的代码都白改了。
点击这里,就可以开始代码管理,初始化仓库。
每次修改完一个主要功能之后,都可以在这里提交一下。最后代码没问题后,我们可以提交到Github。在提交代码之前,我们还要确认下代码是否正确。
运行命令:npm run build
如果像这样全是勾,那就是没问题。
当代码没问题后,点击提交。
这里输入你想在Github上创建的仓库名,选择私有仓库。
最后提交成功。
3.4.5 Vercel部署
- 打开vercel,创建一个新项目
- 打开vercel,创建一个新项目
网址:vercel.com
- 选择部署的项目,点击 导入,点击 部署
- 部署成功后添加环境变量,在设置中找到环境变量,把.env文件内的内容放进去。
- 开始部署
部署成功后,以后每次提交代码后都可以自动部署。部署不成功的话,可以把logs信息直接复制给Cursor就可以。
3.4.6 购买域名 正式上线
- 给网站取名字
- 给网站取名字
域名就是 baidu.com 这种,首先我们要确定给我们的产品网站起一个名字。
比如,我让claude 帮我取了一个,叫:headshotpro
- 购买域名
确定好名字之后,去域名注册平台购买域名,比如:Namecheap
购买完成后,就可以去vercel上配置域名了。
3.4.7 上线后的用户测试以及初步反馈
上线之后,只是代表你的产品MVP开发完成了,这只是第一步。
还需要进行用户测试,得到初步的反馈。
比如我把网站发在了各种群里,让用户给我提建议。
这时候,你会得到很多很多建议。比如:
是的,这些都很正常。
但也不是每个问题都要去修复,首先一定要确保核心功能没问题。其他的问题可以先记下来,等后面用户量上来后再修改也不迟。
3.4.8 后续工作
后面还有很多很多工作:
比如:注册、登陆功能
比如:增加各种页面
比如:接入支付功能
比如:每天查看网站数据
比如:每天通过屏幕录制看用户在干什么
虽然事情很多,但是在这个过程中,你会发现很多乐趣。
四、个人成长与收获
4.1 从每日复盘中发现问题
目前的这一切,都源自开始每日复盘,发现自己的问题,然后不断改正。
从复盘中学到了:
- 创业要厚脸皮,遇到不懂的,就要问清楚,就算被大佬骂,也要问明白。
- 要放下自己的ego,不骄傲,不自大,保持谦卑。不去辩驳,为了一个观点争的面红耳赤。
- 要每日复盘,每周复盘,每月复盘。
- 带着发现的眼光去体验世界,感受创业,你会发现很多有意思的东西。
- 要不断刻意练习,找到自己的导师,及时纠正自己的错误,获得有效的正反馈。
- 赚到钱只是一个结果,要不断创造自己的价值。通过自己的专长,找到社会的需求,从而创造价值。
等等。
4.2 目前的收获
- 这里非常感谢洋哥,是洋哥拿生命在做的交付,让我能一直坚持下去。从商业IP课到心力课,洋哥一直没有放弃我们。
- 这里非常感谢洋哥,是洋哥拿生命在做的交付,让我能一直坚持下去。从商业IP课到心力课,洋哥一直没有放弃我们。
具体讲讲在破局的收获,以及给新手朋友一点启发。
1.1 首先,看各种精华文章,一开始把破局所有的精华都刷一遍,给自己一个星期的时间去刷。
这里特别注意,看的时候不要焦虑,就把它当作看书。
因为你只有建立赚钱的认知,看过很多案例,才有可能赚到钱。
并且一定要限定时间,不能一直看。
我现在每天都会固定时间看看精华帖和中标。
1.2 看完之后,立马行动,根据自己的兴趣和优势。
比如我参加了很多行动营。不断行动才有机会。
干中学,不断刻意练习,遇到不懂的就在群里问,教练就是你的导师,可以不断指出你的问题,获得及时有效的正反馈。
所以一定要积极去参加行动营,这些都是低成本尝试,只有做,才有结果,只是一直想,特别耗费心力。
事情是做出来的,而不是想出来的。
1.3 其实最重要的是线下组局。
也正是在洋哥的鼓励下,我组了第一次局,当时来了好多小伙伴,并且大家都非常年轻,来自周边城市,南京的,苏州的小伙伴也都赶了过来。
大家聊的很爽,还一起吃了晚上。
我现在的一起赚钱小群有4个人,有两个都是那天线下组局认识的,大家在群里一起分享认知,收获,一起互相鼓励。
创业路上需要这样一群人,一群志同道合的人。
还有北京行动家大会,一共3天,真的是头脑风暴,大家一聊聊到凌晨,一天就睡4个小时。
在回来的高铁上,看着洋哥给的《超级个体 从0到百万变现》,写下了下面这么多感悟。
1.4 还有洋哥用生命的交付
从一开始的商业IP课到产品课,心力课等等,各种各样的课程。这价值我就不说了,生怕大家跑不出来。
各种密训,各种直播。
我的手机里全都是洋哥的录屏,常听常新。
焦虑了,听一听,缓解缓解。
迷茫了,听一听,找找方向。
没有动力了,听一听,打个鸡血,继续往前。
这里建议大家还是看直播,因为录屏后肯定不会去看,看直播的效果最好。
真的,只要你不放弃自己,什么时候都有可能。每个人都有自己的节奏,按照自己的节奏来,成功只是时间问题。
目前的成绩:
今天写的这篇公众号已经到了400多阅读,目前还在上涨。
后面,继续努力,争取做出自己的IP,再次感谢洋哥。
- 感谢惰总凌晨3点还在群里给我们解决问题
就怕我们赚不到钱,都要直接投喂了。
是惰总让我知道了事前逻辑。
创业,做项目一定不能用事后逻辑,别人的成功是不可复制的。时刻用事前逻辑,根据自己的优势、经历、资源来选择你的创业项目,形成自己的创业选品逻辑。
一个财富自由的大佬居然愿意每个月带着我出去跑一次,我何德何能啊。这个多大价值就不说了吧,再次感谢惰总。
- 感谢刘小排老师,是刘小排老师让我明白了做产品可以这么快乐。
小排老师每次都会在视频结尾说一句类似的话:赶紧去玩起来吧。玩个一整天吧。
是啊,玩起来,跟着自己的兴趣,不断探索,多有意思啊。
这些都是我创业路上的贵人,能及时发现你的问题,给你提供有效的正反馈。
也希望大家都能找到自己的乐趣,去吧,赶紧去玩起来吧!
tips:
好了,今天写完了AI网站产品的复盘,如果点赞多的话,下一篇就会很快与大家见面了(预告:一个完全不懂代码的新手(我女朋友),从0到1,做出一款类似forest的专注森林,学习倒计时APP,目前已经上架。)
技术完全没有门槛,一个拼创意的时代来了!
学会了或有启发,别忘了给我点个赞,评论,转发~因为你的反馈真的很重要!
最后,如果你对AI网站出海感兴趣,欢迎关注公众号 百里登风AI
加 luffy10004 ,领取一份《AI网站出海新手指南》资料包。
来源:juejin.cn/post/7517841519253848116
别在用“长期主义”骗自己了
引言
上篇文章,一个读者评论问,如何在看不到结果的时候,还能坚持下去。
我内心里立刻蹦出来四个字:长期主义,不过转念一想这不是正确的废话吗,现在这个社会谁还没听过长期主义?
坚持早起、坚持阅读、坚持健身,仿佛你足够坚持,命运就会回报你,长期主义本身都快成了一种政治正确。
我很庆幸当时没把这几个字回复给读者,那也太不负责任了。
因为我发现,很多人理解的长期主义,是错的,包括我自己。
试想你有没有这种感觉,每天都在坚持做一些你认为正确的事,但一边焦虑的等待结果为什么还不来,一边痛苦的咬牙坚持。
你有没有想过真正的长期主义,到底是什么样的?
长期主义的难点从来不是坚持,而在于你能否坚定方向、建立反馈,并且在走错路时愿意纠正它。
长期主义的误区
误区一:把长期主义当作“迟到的确定性”
我一度以为,长期主义是一个慢热的公式,只要你足够努力、足够坚持,总会有回报,只不过回报来的慢了一些。
上学的时候,老师教育我们坚持学习,成绩自然会提升。后来看到各种鸡汤文章,看到很多诸如“他默默努力十年,终于爆红”、“她写了一千篇文章,终于年入百万”这样的励志故事。
于是我陷入了第一个陷阱,把长期主义当作“迟来的确定性”,我一直在等待短期反馈出现。
就像我刚开始写文章时,我会在文章发布后,不断的点击刷新按钮,在后台查看数据,看看曝光量怎么样、阅读量怎么样。
不少自媒体人都会有这种“数据焦虑”,如果阅读量涨得很快,那就无比开心,如果发出去半小时没人看,就会陷入焦虑。
那个时候,我自诩是在践行长期主义,但其实我无时无刻都在期待短期的奖励。
但当你这篇文章发出去,内心期待着这篇文章能够达到“10w+”的时候,你就已经悄悄背离了长期主义。
真正的长期主义,不需要靠短期反馈也能坚持下去。
误区二:把坚持当成意义本身
那你说,我不在意短期反馈,我有足够的毅力坚持,总可以了吧?
这就聊到容易陷入的第二个误区,把“坚持”当成了意义本身。
今年年初的时候,我已经坚持写作一年,可是涨粉和阅读量都不尽人意。而且AI发展一日千里,见到很多人走AI赛道涨粉很快,用AI写的文章,靠AI堆上量也能出爆文,内心非常焦虑,我思考是不是自己走错了方向。
屋漏偏逢连夜雨,我感觉耗尽了自己的灵感,没有想写的选题,并且对之前的内容特别不满意,想改变也无从下手。
但我不敢停下,我选择了咬牙坚持,逼迫自己大量的看书、看专栏,试图找到更多灵感。强迫自己多记录一些东西,用笔记数量带给自己安慰。
结果就是看过的内容都是走马观花,什么都没记住。更新的几篇文章全部都绞尽脑汁,即使筋疲力尽写完后也只剩下对自己的不满。
回想起来,那段时间我只是在靠机械的阅读和别扭的写作,来逃避自己没有方向的现实而已。
说难听点就是低水平重复。
如果在错误的地方坚持,那只能带来更大的错误。
真正的长期主义,不会让自己痛苦的坚持,而是建立在对方向的清晰判断上。
什么是真正的长期主义
现在看来,真正理解长期主义并不难,可以用一个公式来总结:长期主义 = 有方向(战略判断)× 有反馈(系统纠偏)× 有预期(心理预期)。
这是一个乘法模型,只要其中任意一项为零,结果就是零。
有方向
你之所以能长期坚持一件事,是因为你能看到这件事长远来看带来的价值。
就拿阅读、写作、锻炼来说,是公认的需要长期主义的事情,虽然他们的反馈周期很长,但是它们能够给我们带来的正向价值十分确定。
可就是最简单直接的三件事情,为什么还是坚持不下来?
这不仅是意志力的问题,还与我们大脑的结构有关——我们天生不擅长做长期决策。
有一本讲脑科学的书《权衡一念》,作者福尔克从脑科学的角度介绍了一个概念:我们大脑有一个「自我相关系统」,当你每次想到与自我相关的东西,核磁共振成像就会扫描到这个区域在被点亮。
但是当你想到几年后的自己或者老年的自己时,「自我相关系统」却不会被点亮,也就是说我们甚至会把「未来的自己」想像成另一个人。
我们以为自己明白一些事情在未来带给我们的好处,但是大脑却认为这些东西和“自己”无关,于是我们更倾向就是自动聚焦到眼前的事情,忽略未来、长远的好处,于是没办法建立方向感。
因为眼前事情,给我们的感受最直接,所以我们陷入了期待短期回报的误区。
你想要在你认可的方向上坚持下去,有一种最简单的方式是,改变聚焦点。
不是强迫自己坚持,而是把注意力转向能够在当下带给你满足感的元素。
怎么改变聚焦点?我举两个自己的例子。
前一阵子为了买东西再次下载了抖音,结果一发不可收拾,开始习惯性的用碎片时间刷短视频。
之前我是全凭意志力控制自己,不断给自己强调“别刷了,没营养”,并告诫自己多看些书。但这次我找出了我最喜欢一本小说《挪威的森林》,这本书我读过五遍,能够很自然的就沉浸在小说的情节里,等小说看完,我空闲时已经不会在习惯性的拿出手机刷短视频了。
日常因为工作原因一坐就是一天,但我又知道每天至少得保证7000步才是最健康的。当我认为需要运动的时候,我并不是告诉自己多运动才能长寿,而是劝自己,文章写到这里灵感已经枯竭,不如出去走一走换换脑子。
这里要点是,我们尽量去聚焦到那些我们不愿意去改变的事情,当下能给我们带来的好处,甚至说和我们喜欢的事情绑定在一起。
聚焦点不一样,行动方向截然不同,真正的长期主义,不是压抑自己做不喜欢的事情,而是和自己喜欢的事情“打配合”。
有反馈
许多人之所以无法坚持长期主义,是因为人很容易在前进的路上迷失。
一个关键原因是我们不能仅凭意志力在黑暗中前行,反馈就是我们的灯塔,提醒自己是否还在正确的方向。
但如果没有建立自己的反馈体系,就很容易陷入把坚持当成意义这个误区。
系统动力学把反馈分成了正反馈回路和负反馈回路。
正反馈就是结果反过来加强了原因,从而形成螺旋式上升。如果你文章质量好,获得了大量点赞,因此平台持续给你推荐。推荐又让更多的人看到,别人进一步的点赞、转发。
负反馈就是系统对偏差进行修复,来保障稳定和持续。健身时你不断冲击更大重量,但身体终会在某一重量时无法承受,你可能会因此受伤,反而达不到之前你能坚持的最大重量。
那么我们就很清晰了,正反馈帮助我们进步,负反馈帮助我们纠偏,你必须建立自己的反馈系统。
第一类反馈来源于外界。
你有没有发现很多博主在视频或者文章后面,都在求大家给一个一键三连,我曾以为这是什么套路,现在看来这是每一个创作者的本能,你的点赞、评论、转发,是对一个内容创作者最好的奖赏。
坦率的讲,现在这个快节奏社会,能够沉下心看完一篇不知名作者写的一篇几千字的文章,已经足够让我开心。
哪怕是我自己,能让我踏下心看完几千字文章的,都是那些大IP和知名的专栏作家。
如果收到了点赞和转发,那我更是无比感激,即使到了今天,我看到文章的互动依然会很兴奋。
这是极强的正反馈,会给你继续前进的力量,随后螺旋上升。
哦对,看到这确认不点个赞吗?
可并不是每次努力,都能够听到外界带给你正向的声音。
因此第二类反馈来源于你自己。
我文章有过很长一段时间的低谷期,几千字的文章无人问津,就好像你搬起了一大块石头扔进水里,一点水花都没有。
那时候我就意识到,我必须建立“内部反馈机制”,我不断问自己几个问题:
- 学习到的知识,我自己是否真正理解了?
- 如果理解了,能不能用自己的话把这个道理讲出来?
- 这个东西,我有没有应用到真实的生活中,给自己带来改变?
慢慢的我发现,曾经让自己迷茫、愤怒、无助的事情,越来越少了。我逐渐能够看透本质,理清思路、看清全局。
其实写作带来这些好处已经弥足珍贵,但我认为还不够,我开始反思每一篇文章:
- 这篇文章的逻辑好不好,能不能做到自洽,衔接是否通顺?
- 是不是论点不够、思考不够,导致文章没有说服力?
- 文章节奏控制的怎么样,情绪有没有断层?
再比如最近我自己正在拆解每篇文章的不足,然后有意识的和高手学习并一点点改进,一天写完的内容,可能修改要花上三天。
虽然拆解不足给自己的是负反馈,但是复反馈能够帮助你纠偏。
正是这个内部反馈系统,让我坚持到了现在。
第三类设计你自己的系统反馈。
最强大的反馈系统,不靠别人、不靠情绪,而是系统本身。
B站有一个up主叫做影视飓风,老板Tim分享了他们的内容复盘系统,他在最显眼的地方专门放了一个屏幕,里面记录了每一个内容各种实时数据,通过图表展现出来,全公司的人都可以看见。
他们分析哪些内容能涨粉、哪些容易爆,哪条视频表现不好、为什么表现不好。正是这种高度透明和数据驱动的机制,一定程度上帮助他们孵化出第二个账号“飓多多StormCrew”,内容风格完全不同,却因为精准抓住观众喜好而大获成功。
这块我做的不好,我之前几乎不去复盘内容数据,受到他的启发,我花了15分钟用飞书的多维表格,给自己搭建了一个内容数据看板,这里面记录了自己今年来的文章阅读走势。
波动这么明显我有点汗颜,不过我发现带有30+、面试、AI相关的内容,大家会更感兴趣些。
你不一定要搭建看板,但你可以从每周一次总结开始,从定期记录自己的感受开始,找到合适自己的反馈机制。
有预期
最后我们聊聊,如果你真的想要践行长期主义,你得做好哪些准备。
毕竟长期主义并不轻松,提前把困难都想到, 那么真的遇到困难时,反而更容易坚持下来。
长期主义,需要你持续付出。
它不是简单的重复,而是不断在你的“认知边界”上试错、突破。
这很枯燥,而且往往没有立刻回报,还意味着一次次笨拙的表达、失败的尝试,甚至别人眼里的“不够好看”。
但你要相信:每一次认真而笨拙的输出,都是自己能力的提升。
长期主义,需要你学会拒绝。
在这个快节奏的社会,你会看到身边的人,靠短视频一夜爆红,靠AI一键搬运赚取时代红利,也会看到一些小伙伴踩对节奏,迅速赚到了第一桶金。
而你却在钻研技能、搭建反馈系统、耐心苦练内功。
你要拒绝那种“快速反馈”的甜头,转而相信“慢反馈”的确定性。
长期主义的回报,是非线性的。
你以为努力一点,进步一点,实际上看似停滞许久,在某一天突然爆发。
大模型有一个著名的现象,叫做能力涌现:你喂进去足够多的数据,在某一刻,它突然学会了你没教它的东西,比如逻辑推理、语言翻译,甚至写代码。
这不是持续进化,而是能力突然“跃迁”。可能连大模型科学家本身也不明白,AI怎么就突然变得如此强大。
就像你健身半年没有什么变化,突然在某一天,你惊讶的发现:肌肉线条已经若隐若现。
说在最后
要我看来,长期主义最大的坏处就是孤独。
你给自己选中了一条要走下去的路,可能身边的人不理解,就算是是最亲近的人对你冷言冷语,你也没有抱怨的权利。
不过长期主义最大的好处也在这里。
你真的会一次次得把曾经以为的“天花板”变成自己脚下的阶梯,你除了抱怨时间不够、能力不足、精力不够,你没什么好抱怨的。
而这,恰恰就是一种美好的人生状态!
这是东东拿铁的第82篇原创文章,欢迎关注。
来源:juejin.cn/post/7516846036586102835
离职后,我的第一个出海产品上线了
今天,我的第一个独立开发出海产品 Chat2Report 上线了,这是一款基于 RAG 的美股财报聊天应用。
为什么要开发独立产品
去年初通过几位大佬(越南的 Tony Dinh,国内的 Hawstein 和 vikingz)的博客了解到,作为程序员还有开发独立产品出海这一条路,其中有些收入还不错,甚至有开发者辞掉了工作,全职做独立开发。
看完他们的文章,心里很激动,想着自己是不是也可以试一试。于是使用 OpenAI 的 gpt-4o-mini 模型微调了一个专门的模型,做了一个变量命名工具,叫 VarNamer,支持多国语言,用户输入任意语言,即可输出精简的英文变量。当时 AI 编程工具还刚刚兴起,变量命名又是件头痛的事,所以想着这个工具应该能为自己节省不少时间。
其实当时开发这个产品,也是为了学习新技术,为自己后面开发出海产品做准备,由于看到不少独立产品都是桌面端的,所以基于 Electron + Vue3 做了 VarNamer,为什么选择 Electron?因为它构建跨平台程序非常方便,为了上Mac,还购买了苹果开发者证书。
开发 VarNamer 并不顺利,期间踩了不少坑,也坚定了后面的出海产品不会再做桌面端了。因为一般的 Web 开发不需要考虑版本更新、证书、跨平台兼容等问题,但是开发桌面应用需要将这些因素都考虑进去。除去后端服务器的成本,安装包托管,更新逻辑,还需要考虑程序的签名证书,不然用户安装应用会报警告,甚至安装不了,其中苹果开发者证书一年就99刀,Windows 就更贵了。
VarNamer 上线后,在几个论坛发了贴宣传,也发给了同事使用,反响还不错,但是没想到后面 AI 编程工具发展这么快,特别是出了 Cursor 这样的王炸产品,变量命名完全不是难事,几乎改变了以往的编程习惯,一直 Tab 的感觉,简直不要太爽。
99 刀的苹果开发者证书就开发了一个应用,着实太浪费了,至于 VarNamer,后面再也没管过它,好像域名最近快到期了,也不打算续费了。
独立出海产品契机
自 VarNamer 之后,接下来的几个月时间并没有开发新的产品,为什么?因为我不知道开发什么,好像也找不到什么痛点需要解决的,后面想到自己在买一家上市公司的股票之前,会分析公司的财务报告,毕竟我是一位追随彼得·林奇和巴菲特的价值投资者,哈哈!
但是分析财报是件麻烦且费脑的事,一份财报少则几十页多则几百页,除了重点关注三张报表,即资产负债表、利润表、现金流量表(俗称“三大表”),还需要关注管理策略、管理层的措施、战略,财报中是否有欺诈风险等。
既然这么麻烦,那 AI 是不是能帮我们分析了?后面经过调研发现了市面上还真有这样的产品,比如 beebee、reportify,它们都是基于 RAG 实现的,但是我想基于它们开发一款新的产品,为什么?因为它们的功能实在太多了,新闻、电话会议、上传文件、公司评价...,而且 RAG 也不精准,我需要一款操作简单,体验更好,简洁、美观,精准,专门分析财报的工具。
去年 9 月下旬开始了技术调研,之前对 RAG 技术稍微有点了解,但是不够深入,只是基于 Dify 做了一些应用,同时发现 Dify 不够自由,文档解析分块不能自定义元数据,后端又是基于Flask的,to C 的应用担心性能不够,生产环境还需要一台服务器额外部署 Dify。
调研下来最终确定业务层使用Go + Gin, 大模型层使用Python + FastAPI + LlamaIndex,前端使用Vue3。LlamaIndex 实现 RAG 应用非常方便,兼容各种第三方文档解析器、向量模型(Embedding models)、重排序模型(Rerank models), 向量数据库、大语言模型(LLMs)。
之后利用下班时间和假期实现了个 demo,感觉还不错,是自己想要的效果,美股财报批量转 PDF,文档批量解析、分块,提取布局信息,前端布局重构回溯,AI回答带引用来源,高亮定位到原文段落,一个 ChatPDF + AI 财报助理的构想应该很快就可以实现。
10 月份利用业余时间开始了马不停蹄的开发,这期间公司一些事件却让自己很不舒服,作为一个技术人,希望能全身心的投入到技术中,利用技术解决问题,但是各种PPT汇报、职场PUA,让自己疲于奔命。
我想离职了,全职投入到项目开发中,11月初的一个晚上把这个想法告诉了老婆,非常正式的讲了自己的规划,产品怎么落地,产品受众人群,怎么盈利,以及一个粗略的计划,希望得到她的支持。因为我觉得,组建家庭后,另一半相当于就是你的人生合伙人。在很多重要决策上,得到合伙人的支持,才能走得更好走得更远。如果成功了,兴许以后就不用上班了,就算失败了大不了重新找个班去上。老婆没说什么,表示了支持,在这里要特别感谢一下老婆。
全力加速开发
12 月 09 号是我最后一个工作日,也是我作为全职独立开发的第一天,当天走出公司,呼吸着新鲜的空气,感受到了从未有过的自由。
成为全职独立开发之后,最大的感受就是开发效率提高了几倍,不用再参加枯燥无聊的会议,应付各种办公室政治斗争,输出无意义的PPT。直到今天项目上线,全部开发时间应该是3个月。
这期间踩了无数坑,以前工作时的一些优点,现在反而成了缺点,比如之前专注于写好代码,追求架构完美和扩展性,甚至有代码洁癖,但这严重推迟了产品的上线时间,在产品还未经过市场验证之前,应该快速推出产品,验证市场需求,这比追求精美更重要。
接下来的计划
接下来的主要任务就是宣传了,去海外各大社区宣传寻找目标用户,比如 Facebook、Twitter、Reddit。
两个月之后我会再写一篇帖子,分享我的成果,盈利情况等。
接下来也会分享一些出海产品在技术选型和海外支付方面的经验。
来源:juejin.cn/post/7517998609946673186
离职后的这半年,我前所未有的觉得这世界是值得的
大家好,我是一名前端开发工程师,属于是没有赶上互联网红利,但赶上了房价飞涨时代的 95 后社畜。2024 年 3 月份我做了个决定,即使已经失业半年、负收入 10w+ 的如今的我,也毫不后悔的决定:辞职感受下这个世界。
为什么要辞职,一是因为各种社会、家庭层面的处境对个人身心的伤害已经达到了不可逆转的程度,传播互联网负面情绪的话我也不想多说了,经历过的朋友懂得都懂,总结来说就是,在当前处境和环境下,已经没有办法感受到任何的快乐了,只剩焦虑、压抑,只能自救;二是我觉得人这一辈子,怎么也得来一次难以忘怀、回忆起来能回甘的经历吧!然而在我的计划中,不辞职的话,做不到。
3 月
在 3 月份,我去考了个摩托车驾-照,考完后购买了一辆摩托车 DL250,便宜质量也好,开始着手准备摩旅。
4 月份正式离职后,我的初步计划是先在杭州的周边上路骑骑练下车技,直接跑长途还是很危险的,这在我后面真的去摩旅时候感受颇深,差点交代了。
4 月
4.19 号我正式离职,在杭州的出租屋里狠狠地休息了一个星期,每天睡到自然醒,无聊了就打打游戏,或者骑着摩托车去周边玩,真的非常非常舒服。
不过在五一之前,我家里人打电话跟我说我母亲生病了,糖尿病引发的炎症,比较严重,花了 2w+ 住院费,也是从这个时候才知道我父母都没有交医保(更别说社保),他们也没有正式、稳定的工作,也没有一分钱存款,于是我立马打电话给老家的亲戚让一个表姐帮忙去交了农村医保。所有这些都是我一个人扛,还有个亲哥时不时问我借钱。
说实话,我不是很理解我的父母为什么在外打工那么多年,一分钱都存不下来的,因为我从小比较懂事,没让他们操过什么心,也没花过什么大钱。虽然从农村出来不是很容易,但和周围的相同条件的亲戚对比,我只能理解为我父母真的爱玩,没有存钱的概念。
我可能也继承了他们的基因吧?才敢这样任性的离职。过去几年努力地想去改变这个处境,发现根本没用,还把自己搞得心力交瘁,现在想想不如让自己活开心些吧。
5 月
母亲出院后,我回到杭州和摩友去骑了千岛湖,还有周边的一些山啊路啊,累计差不多跑了 2000 多公里,于是我开始确立我的摩旅计划,路线是杭州-海南岛-云南-成都-拉萨,后面实际跑的时候,因为云南之前去过,时间又太赶,就没去云南了。
6 月
在摩友的帮助下,给摩托车简单进行了一些改装,主要加了大容量的三箱和防雨的驮包,也配备了一些路上需要的药品、装备,就一个人出发了。
从杭州到海南这部分旅行,我也是简单记录了一下,视频我上传了 B 站,有兴趣的朋友可以看看:
拯救焦虑的29岁,考摩托车驾-照,裸辞,买车,向着自由,出发。
摩托车确实是危险的,毕竟肉包铁,即使大部分情况我已经开的很慢,但是仍然会遇到下大雨路滑、小汽车别我、大货车擦肩而过这种危险情况,有一次在过福建的某个隧道时,那时候下着大雨,刚进隧道口就轮胎打滑,对向来车是连续的大货车,打滑之后摩托车不受控制,径直朝向对向车道冲过去,那两秒钟其实我觉得已经完蛋了,倒是没有影视剧中的人生画面闪回,但是真的会在那个瞬间非常绝望,还好我的手还是强行在对龙头进行扳正,奇迹般地扳回来且稳定住了。
过了隧道惊魂未定,找了个路边小店蹲在地上大口喘气,雨水打湿了全身加上心情无法平复,我全身都是抖的,眼泪也止不住流,不是害怕,是那种久违地从人类身体发出的求生本能让我控制不住情绪的肆意发泄。
在国道开久了人也会变得很麻木,因为没什么风景,路况也是好的坏的各式各样,我现在回看自己的记录视频,有的雨天我既然能在窄路开到 100+ 码,真的很吓人,一旦摔车就是与世长辞了。
不过路上的一切不好的遭遇,在克服之后,都会被给予惊喜,到达海南岛之后,我第一次感觉到什么叫精神自由,沿着海边骑行吹着自由的风,到达一个好看的地方就停车喝水观景,玩沙子,没有工作的烦扰,没有任何让自己感受到压力的事情,就像回到了小时候无忧无虑玩泥巴的日子,非常惬意。
在完成海南环岛之后,我随即就赶往成都,与前公司被裁的前同事碰面了。我们在成都玩了三天左右,主要去看了一直想看的大熊猫🐼!
之后我们在 6.15 号开始从成都的 318 起始点出发,那一天的心情很激动,感觉自己终于要做一件不太一样的事,见不一样的风景了。
小时候在农村,读书后在小镇,大学又没什么经济能力去旅行,见识到的事物都非常有限,但是这一切遗憾在川藏线上彻底被弥补了。从开始进入高原地貌,一路上的风景真的美到我哭!很多时候我头盔下面都是情不自禁地笑着的,发自内心的那种笑,那种快乐的感觉,我已经很久很久很久没有了。
同样地,这段经历我也以视频的方式记录了下来,有兴趣的朋友可以观看:
以前只敢想想,现在勇敢向前踏出了一步,暂时放下了工作,用摩托跑完了318
到拉萨了!
花了 150 大洋买的奖牌,当做证明也顺便做慈善了:)
后面到拉萨之后我和朋友分开了,他去自驾新疆,我转头走 109 国道,也就是青藏线,这条线真的巨壮美,独自一人行驶在这条路,会感觉和自然融合在了一起,一切都很飘渺,感觉自己特别渺小。不过这条线路因为冻土层和大货车非常非常多的原因,路已经凹凸不平了,许多炮弹坑,稍微骑快点就会飞起来。
这条线还会经过青海湖,我发誓青海湖真的是我看到过最震撼的景色了,绿色和蓝色的完美融合,真的非常非常美,以后还要再去!
拍到了自己的人生照片:
经历了接近一个半月的在外漂泊,我到了西宁,感觉有点累了,我就找了个顺丰把摩托车拖运了,我自己就坐飞机回家了。
这一段经历对我来说非常宝贵,遇到的有趣的人和事,遭遇的磨难,见到的美景我无法大篇幅细说,但是每次回想起这段记忆我都会由衷地感觉到快乐,感觉自己真的像个人一样活着。
这次旅行还给了我感知快乐和美的能力,回到家后,我看那些原来觉得并不怎么样的风景,现在觉得都很美,而且我很容易因为生活中的小确幸感到快乐,这种能力很重要。
7 月
回到家大概 7 月中旬。
这两个多月的经历,我的身体和心态都调整的不错了,但还不是很想找工作,感觉放下内心的很多执念后,生活还是很轻松的,就想着在家里好好陪陪母亲吧,上班那几年除了过年都没怎么回家。
在家里没什么事,但是后面工作的技能还是要继续学习的,之前工作经历是第一家公司用的 React 16,后面公司用的是 Vue3,对 React 有些生疏,我就完整地看了下 React 18 的文档,感觉变化也不是很大。
8、9 月
虽然放下了许多执念,对于社会评价(房子、结婚、孩子)也没有像之前一样过于在乎了,但还是要生活的,也要有一定积蓄应对未来风险,所以这段时间在准备面试,写简历、整理项目、看看技术知识点、刷刷 leetcode。
也上线了一个比较有意义的网站,写了一个让前端开发者更方便进行 TypeScript 类型体操的网站,名字是 TypeRoom 类型小屋,题源是基于 antfu 大佬的 type-challenges。
目前 Type Challenges 官方提供了三种刷题方式
- 通过 TypeScript Playground 方式,利用 TypeScript 官方在线环境来刷题。
- 克隆 type-challenges 项目到本地进行刷题。
- 安装 vscode 插件来刷题。
这几种方式其实都很方便,不过都在题目的可读性上有一定的不足,还对开发者有一定的工具负担、IDE 负担。
针对这个问题,也是建立 TypeRoom 的第一个主要原因之一,就是提供直接在浏览器端就能刷题的在线环境,并且从技术和布局设计上让题目描述和答题区域区分开来,更为直观和清晰。不需要额外再做任何事,打开一个网址即可直接开始刷题,并且你的答题记录会存储到云端。
欢迎大家来刷题,网址:typeroom.cn
因为个人维护,还有很多题目没翻译,很多题解没写,也还有很多功能没做,有兴趣一起参与的朋友可以联系我哦,让我一起造福社区!
同时也介绍下技术栈吧:
前端主要使用 Vue3 + Pinia + TypeScript,服务端一开始是 Koa2 的,后面用 Nest 重写了,所以现在服务端为 Nest + Mysql + TypeORM。
另外,作为期待了四年,每一个预告片都看好多遍的《黑神话·悟空》的铁粉,玩了四周目,白金了。
现在
现在是 10 月份了,准备开始投简历找工作了,目前元气满满,不急不躁,对工作没有排斥感了,甚至想想工作还蛮好的,可能是闲久了吧,哈哈哈,人就是贱~
更新 11 月
我还是没有找工作,又去摩旅了一趟山西、山东,这次旅行感觉比去西藏还累、还危险。同样是做了视频放 b 站了,有兴趣的可以看看:
骑了4300km只为寻找那片海-威海的海|摩旅摩得命差点没了
真的要开始找工作了喂!
最后
其实大多数我们活得很累,都是背负的东西太多了,而这些大多数其实并不一定要接受的,发挥主观能动性,让自己活得开心些最重要,加油啊,各位,感谢你看到这里,祝你快乐!
这是我的 github profile,上面有我的各种联系方式,想交个朋友的可以加我~❤️
来源:juejin.cn/post/7424902549256224804
Swift 官方正式支持 Android,iOS 的跨平台春天要来了吗?
近日,Swift 官方正式宣布成立 Android 的工作组,将 Android 列为官方支持的平台,该工作组的主要目标是为 Swift 语言添加并维护 Android 平台支持,让开发者能够使用 Swift 开发 Android 应用:
其实 Swift 语言跨平台支持也不是什么新鲜事,在之前我聊过的 Skip 用 Swift 写 Android App 的时候就聊过,只是不同的是 Skip 是将 Swift 翻译成 Kotlin,把 SwiftUI 翻译成 Compose 的形式来实现,这和 uni-app x 的跨平台实现殊途同归。
感兴趣的可以看 《2025 跨平台框架更新和发布对比》
但是 Swift 官方的方案则不同,它是通过 LLVM 进行适配的,我们之前聊过的 《为什么跨平台框架可以适配鸿蒙》就聊过,LLVM 也是各大框架适配鸿蒙的重要基石,甚至一些方案适配鸿蒙是通过 Apple 的 LLVM 去先导出 IR 来完成前置工作。
而这次 Swift on Android 的实现,则是直接利用 Android 平台的构建工具:Android NDK 。
为什么这么说?因为 Swift 编译器从诞生之初就基于 LLVM ,而 Google 的 Android NDK 后来也使用基于 LLVM 的 Clang 作为其官方 C/C++ 编译器 :
- NDK r11 开始建议切换到 Clang
- NDK r12
ndk-build
命令默认使用 Clang - NDK r13 GCC 不再受支持
- NDK r14 GCC 弃用
- ····
说起 Clang 和苹果也是很有渊源,Clang 的设计初衷是提供一个可以替代 GCC 的前端编译器,因为 GCC 的发展不符合 Apple 的节奏和需要,同时受限于License,苹果公司无法使用 LLVM 在 GCC 基础上进一步提升代码生成质量,因此苹果公司决定从头编写 C、C++、Objective-C 语言的前端 Clang,以彻底替代GCC。
而在编译上,比如 stdlib
里的 AddSwiftStdlib.cmake
可以看到, Swift 没有在 Android 上创造一套自己的 log 系统,它直接链接了 Android 的 Native 的日志 log 来实现,从而支持 Android Studio 的 Logcat :
所以基于 LLVM 的 Android NDK 是实现 Swift 跨平台编译的关键,它让 Swift 编译器能够被“重定向”,从而为 Android 支持的 CPU 架构(如 aarch64
、armv7
、x86_64
)生成相应的原生机器码 。
$ NDK_PATH=path/to/android-ndk-r27c
$ SWIFT_PATH=path/to/swift-DEVELOPMENT-SNAPSHOT-2024-11-09-a-ubuntu22.04/usr/bin
$ git checkout swift-DEVELOPMENT-SNAPSHOT-2024-11-09-a
$ utils/build-script \
-R \ # Build in ReleaseAssert mode.
--android \ # Build for Android.
--android-ndk $NDK_PATH \ # Path to an Android NDK.
--android-arch aarch64 \ # Optionally specify Android architecture, alternately armv7 or x86_64
--android-api-level 21 \ # The Android API level to target. Swift only supports 21 or greater.
--stdlib-deployment-targets=android-aarch64 \ # Only cross-compile the stdlib for Android, ie don't build the native stdlib for Linux
--native-swift-tools-path=$SWIFT_PATH \ # Path to your prebuilt Swift compiler
--native-clang-tools-path=$SWIFT_PATH \ # Path to a prebuilt clang compiler, one comes with the Swift toolchain
--build-swift-tools=0 \ # Don't build the Swift compiler and other host tools
--build-llvm=0 \ # Don't build the LLVM libraries, but generate some CMake files needed by the Swift stdlib build
--skip-build-cmark # Don't build the CommonMark library that's only needed by the Swift compiler
简而言之,就是编译成 so 。
目前官方要求是在 Linux 环境下(官方推荐 Ubuntu 20.04/22.04)下,使用 Swift 官方提供的交叉编译工具链,将 .swift
源文件编译成原生可执行文件或共享库,之后将编译产物连同必需的 Swift 运行时库,通过 Android adb 推送到 Android 设备或模拟器上,最终这些原生代码可以在 Android 的 shell 环境中直接运行,或被一个标准的 Android 应用加载并调用 :
首先需要运行以下命令复制复制对应的 so :
$ adb push build/Ninja-ReleaseAssert/swift-linux-x86_64/lib/swift/android/libswiftCore.so /data/local/tmp
$ adb push build/Ninja-ReleaseAssert/swift-linux-x86_64/lib/swift/android/libswiftAndroid.so /data/local/tmp
$ adb push build/Ninja-ReleaseAssert/swift-linux-x86_64/lib/swift/android/libswiftSwiftOnoneSupport.so /data/local/tmp
$ adb push build/Ninja-ReleaseAssert/swift-linux-x86_64/lib/swift/android/libswiftRemoteMirror.so /data/local/tmp
$ adb push build/Ninja-ReleaseAssert/swift-linux-x86_64/lib/swift/android/libswift_Concurrency.so /data/local/tmp
$ adb push build/Ninja-ReleaseAssert/swift-linux-x86_64/lib/swift/android/libswift_RegexParser.so /data/local/tmp
$ adb push build/Ninja-ReleaseAssert/swift-linux-x86_64/lib/swift/android/libswift_StringProcessing.so /data/local/tmp
$ adb push build/Ninja-ReleaseAssert/swift-linux-x86_64/lib/swift/android/libdispatch.so /data/local/tmp
$ adb push build/Ninja-ReleaseAssert/swift-linux-x86_64/lib/swift/android/libBlocksRuntime.so /data/local/tmp
然后还需要复制 Android NDK 的 libc++ :
$ adb push /path/to/android-ndk-r27c/toolchains/llvm/prebuilt/linux-x86_64/sysroot/usr/lib/aarch64-linux-android/libc++_shared.so /data/local/tmp
此外还需要复制在上一步中构建的 hello
可执行文件:
$ adb push hello /data/local/tmp
最终通过 adb shell
命令在 Android 设备上执行 hello
可执行文件:
$ adb shell LD_LIBRARY_PATH=/data/local/tmp /data/local/tmp/hello
而对于 Android 端来看,此时的 Swift 产物与 C/C++ 代码没什么区别,它必须作为一个标准的 .so
库被加载,并通过 JNI 规范暴露需要支持的能力。
目前 Swift 的核心标准库(stdlib
)已经可以成功在 Android 平台进行编译 ,也就是目前 String
、Int
、Array
和 Dictionary
等基础数据类型已经完成基本支持:
更高层次的核心库,比如 Foundation
( URLSession
、JSONEncoder
)和 Dispatch
(提供并发支持),也正在被移植到 Android 平台。
而对于 UI 部分,目前 Swift 官方暂未提供任何支持 Android 的 UI 框架 ,官方文档目前表示:“You'd need some sort of framework to build a user interface for your application, which the Swift stdlib does not provide” 。
所以,从这个层面看,它更像是 KMP 的存在,而如果需要类似 CMP 的支持,那么大概率需要 SwfitUI 的官方适配,毕竟 Skip 其实只是一个翻译框架。
而在互操作上,其实过去就有 swift-java 这个图的互操作方向的尝试,当时的目标是实现 Swift 与 Java 之间的双向互操作性,即支持 Swift 调用 Java 库,也支持 Java 调用 Swift 库 :
但是从官方描述来看, Swift on Android 似乎并没有直接使用类似桥接绑定,也就是你需要自己实现这部分,如果你需要的话:
而对于 Swift on Android 来说,要让一个 Swift 函数能被外部的 C 代码(以及遵循 C 调用约定的 JNI)所发现和调用,一般也就是通过 @_cdecl
属性,这个属性可以将函数编译成一个简单的、符合 C 语言标准的符号(Symbol)并暴露出去。
虽然没找到对应的 demo 或者实现,但是理论上如果想要不暴露接口,大概率还是通过
@_cdecl
。
所以目前 Swift on Android 给人的感觉确实很毛坯,在交互和 UI 上都很欠缺,看起来只是开源了一种可能,具体能达到什么效果暂时还看不出来,但是多少算是官方起了个头,也算是有了希望,对于 iOS 来说,这个春天还需要再等等。
那么,你觉得 Swift on Android 的存在多久可以达到生产标准?
参考链接
来源:juejin.cn/post/7520063683180199999
不负责任观察:程序员哪个年龄段最卷?
前言
最近有看到两个报告,调查、总结、2024年程序员的生存情况以及一些工作情况,国内国外都有。接下来摘抄部分数据看看是否与我们的实际相符。
1. 程序员的年龄分段
先看国内的数据:
可以看出,2630岁之间的程序员占比是最多的,1835岁之间占比将近80%。
18~25岁,包含在校学生和刚毕业三年内的学生,按现在考研的趋势,这部分占比会逐渐变低。
35岁以上占比接近19%,说明还是有不少大龄程序员。
再看国外的数据:
2124岁、2529岁占比是并列第一,18~35岁之间占比将近70%。
35岁以上占比30%,说明国外程序员"老龄化"更严重。
看国家之间的对比:
18~29岁程序员分布的国家。
论哪里拥有最多的年轻程序员?还得是神秘的东方大国,人口大国、文明古国---印度。怪不得印度程序员在美国混得很开,毕竟每年都有大量的年轻程序员。
中国在中东、非洲、中亚之后。
看样子美国有不少大龄程序员。
2. 程序员的工作年限
先看国内的数据:
工作13年是最多的,其次是310年。
而10年以上的就比较少,这个时间大都32岁以上了,中途有不少人主动、被动转行。
再看国外的数据:
拥有3~5年的工作经历占比最多,10年以上的工作经历占比接近30%,这比国内的高。
3. 程序员的薪资水平
先看国内水平:
大部分月收入是在10k20k之间,换算成年收入在12w24w之间。
这和地域有关系,比如一个程序员在一线城市北上深薪资20k,那么到二线城市如杭州、成都、武汉可能会打七折,如果再到长沙、西安等估计还会更低。
再看国外水平(收入中位数):
此处显示的是年薪,可以看到美国程序员的收入遥遥领先。
按照汇率计算:
美国程序员收入中位数是百万年薪(人民币)。
而中国是22万人民币,此处的差距还是比较大,同志仍需努力。
4. 哪个年龄段最卷?
通过上述数据,可以看出,35岁以下程序员群体最庞大,工作十年以内人数最多,工资10k~20k人最多,这也符合我们平时职场的感知。
22~25岁,刚毕业几年,正是学习知识,刷小怪升级的时候,按理来说应该会在下班时间蹭公司的免费空调自我学习提升。然而,经过实际观察,目前这个年龄段是00后占据主体,大部分是到点下班。
访谈得知原因如下:
- 大学四年大部分在上网课,天天对着电脑,现在工作还是对着电脑,顶不住,下班就直接溜。
- 我加班能得到什么?就这点钱只能买我8小时。
- 老员工都是既得利益者,是公司的"精神股东",我们就是喽啰,不做额外奉献。
25~30岁,已经在职场中历练了不少年,写的bug、产生的线上事故、输出的复盘文档、与其它部门撕逼等等统统都有经验了,理论上来应该不怎么卷,而实际上最卷的反而是这段年龄的。
总结原因如下:
- 实战经验积累了不少,成为技术骨干,需要调研、学习的东西更多了;平时开会撕逼、晚上怒写业务、周末学习新知识提升自我,花费的时间比较多。
- 这个年龄段处在恋爱、结婚的思考期,没有家庭、小孩的牵挂,留给自己的时间更多。
- 有些还独挡一面当了leader,比如前端小组长,还想再往上踮踮脚,够一下,博一下,卷的主观能动性比较强。
30~35岁,职场老油条,见多识广,动态卷,就是比较能苟。
交流总结如下:
- 家庭牵扯了不少精力,还好靠经验能弥补一些亏空。
- 发展的天花板已经看到,就是摸不着,不相信什么大器晚成,看不到太多希望,做好自己分内事就好。
- 每年的体检总是新增各项小毛病,更加关注自己的身体健康。
- 懂得职场潜规则,该加班配合的演出还是不能视而不见。
35~45岁,这个年龄段出任CEO、赢取白富美的凤毛麟角,要么上升,要么转行,留下来继续编码的反而是最看开的一群人,因为身体/精神原因,没实力卷,实在卷不动。
访谈如下:
- 我在外包挺好的,再干个几年存够社保和养老金就退休。
- 不争不吵,你说的都对,按你的来。
- 组内都是年少有为的人啊,天赋高又刻苦,公司的发展靠你们了,我的养老也靠你们了。
- 最近又发现了个野钓的地方,不容易空军,周末赶早去来一杆。
45岁以上,职场除了高管,没见过这个年龄段的一线码农。
按现在发展,也许多年后,我会看见这样的自己。
来源:juejin.cn/post/7520085904339173430
国产大模型高考出分了:裸分 683,选清华还是北大?
这两天啊,各地高考的成绩终于是陆续公布了。
现在,也是时候揭晓全球第一梯队的大模型们的 “高考成绩” 了——
我们先来看下整体的情况(该测试由字节跳动 Seed 团队官方发布):
按照传统文理分科计分方式,Gemini 的理科总成绩 655 分,在所有选手里排名第一。豆包的文科总成绩 683 分,排名第一,理科总成绩是 648 分,排名第二。
再来看下各个细分科目的成绩情况:
除了数学、化学和生物之外,豆包的成绩依旧是名列前茅,6 个科目均是第一。
不过其它 AI 选手的表现也是比较不错,可以说是达到了优秀学生的水准。
比较遗憾的选手就要属 O3,因为它在语文写作上跑了题,因此语文成绩仅 95 分,拉低了整体的分数。
若是从填报志愿角度来看,因为这套测试采用的是山东省的试卷,根据过往经验判断,3 门自选科目的赋分相比原始分会有一定程度的提高,尤其是在化学、物理等难度较大的科目上。本次除化学成绩相对稍低外,豆包的其余科目组合的赋分成绩最高能超过 690 分,有望冲刺清华、北大。
(赋分规则:将考生选考科目的原始成绩按照一定比例划分等级,然后将等级转换为等级分计入高考总分)
好,那现在的豆包面临的抉择是:上清华还是上北大?
大模型参加高考,分数怎么判?
在看完成绩之后,或许很多小伙伴都有疑惑,这个评测成绩到底是怎么来的。
别急,我们这就对评测标准逐条解析。
首先在卷子的选择上,由于目前网络流出的高考真题都是非官方的,而山东是少数传出全套考卷的高考大省;因此主科(即语文、数学、英语)采用的是今年的全国一卷,副科采用的则是山东卷,满分共计 750 分。
其次在评测方式上,都是通过 API 测试,不会联网查询,评分过程也是参考高考判卷方式,就是为了检验模型自身的泛化能力:
- 选择题、填空题
采用机评(自动评估)加人工质检的方式;
- 开放题
实行双评制,由两位具有联考阅卷经验的重点高中教师匿名评阅,并设置多轮质检环节。
在给模型打分的时候,采用的是 “3 门主科(语文数学英语)+3 门综合科(理综或文综)” 的总分计算方式,给五个模型排了个名次。
值得一提的是,整个评测过程中,模型们并没有用任何提示词优化技巧来提高模型的表现,例如要求某个模型回答得更详细一些,或者刻意说明是高考等等。
最后,就是在这样一个公平公正的环境之下,从刚才我们展示的结果来看,Gemini、豆包相对其他 AI 来说取得了较优的成绩。
细分科目表现分析
了解完评测标准之后,我们继续深入解读一下 AI 选手们在各个科目上的表现。
由于深度思考的大火,大模型们在数学这样强推理科目上的能力明显要比去年好很多(此前大部分均不及格),基本上都能达到 140 分的成绩。
不过在一道不算难的单选题(全国一卷第 6 题)上,国内外的大模型们却都栽了跟头:
这道题大模型们给出的答案是这样的:
豆包:C;Gemini:B;Claude:C;O3:C;DeepSeek:C。
但这道题的正解应该是 A,因此大模型们在此全军覆没。
之所如此,主要是因为题目里有方框、虚线、箭头和汉字混在一起的图,模型认不准图像,说明它们在 “看图说话” 这块还有进步空间。
以及在更难的压轴大题上,很多大模型也没完全拿下,经常漏写证明过程,或者推导不严谨被扣分,说明在细节上还需加强。
到做语文选择题和阅读题这两个版块,大模型们几乎是 “学霸本霸”,得分率超高。
不过在作文写作过程也暴露出了一些问题,例如写作过于刻板、文字冰冷,文章字数不达标(不足 800 字或超过 1200 字)、立意不对,形式上还经常会出现惯用的小标题。
在英语测试过程中,大模型们几乎挑不出毛病,唯一扣分点是在写作上,比如用词不够精准、句式稍显单调,但整体已经很接近完美。
对于理综,遇到带图的题目大模型们还是会犯难,不过豆包和 Gemini 这俩模型在看图像和理解图的能力上会比其他模型强一些。
例如下面这道题中,正确答案应当是 C,大模型们的作答是这样的:
豆包:C;Gemini:C;Claude:D;O3:D;DeepSeek:D。
最后在文综方面,大模型的地域差别就显现得比较明显,国外的大模型做政治、历史题时,经常搞不懂题目在考啥,对中国的知识点不太 “感冒”。
而对于地理题,最头疼的便是分析统计图和地形图,得从图里精准提取信息再分析。
以上就是对于本次评测的全面分析了。
除了今年国内的高考之外,这几位 “参赛选手” 还参加了印度理工学院的第二阶段入学考试——JEE Advanced。
这场考试每年有数百万人参与第一阶段考试,其中前 25 万考生可晋级第二阶段。它分为两场,每场时长 3 小时,同时对数学、物理、化学三科进行考察。
题目以图片形式呈现,重点考查模型的多模态处理能力与推理泛化能力。所有题目均为客观题,每道题进行 5 次采样,并严格按照 JEE 考试规则评分——答对得分、答错扣分,不涉及格式评分标准。
与全印度人类考生成绩对比显示,第一名得分 332 分,第十名得分 317 分。
值得注意的是,豆包与 Gemini 已具备进入全印度前 10 的实力:Gemini 在物理和化学科目中表现突出,而豆包在数学科目 5 次采样中实现全对。
怎么做到的?
相比去年一本线上下的水平,整体来看,大模型们在今年高考题上的表现均有明显的进步。
那么它们到底是如何提升能力的?我们不妨以拿下单科第一最多的豆包为例来了解一下。
豆包大模型 1.6 系列,是字节跳动 Seed 团队推出的兼具多模态能力与深度推理的新一代通用模型。
团队让它能力提升的技术亮点,我们可以归结为三招。
第一招:多模态融合与 256K 长上下文能力构建
Seed1.6 延续了 Seed1.5 在稀疏 MoE(混合专家模型)领域的技术积累,采用 23B 激活参数与 230B 总参数规模进行预训练。其预训练过程通过三个阶段实现多模态能力融合与长上下文支持:
- 第一阶段:纯文本预训练
以网页、书籍、论文、代码等数据为训练基础,通过规则与模型结合的数据清洗、过滤、去重及采样策略,提升数据质量与知识密度。 - 第二阶段:多模态混合持续训练(MMCT)
进一步强化文本数据的知识与推理密度,增加学科、代码、推理类数据占比,同时引入视觉模态数据,与高质量文本混合训练。 - 第三阶段:长上下文持续训练(LongCT)
通过不同长度的长文数据逐步扩展模型序列长度,将最大支持长度从 32K 提升至 256K。
通过模型架构、训练算法及 Infra 的持续优化,Seed1.6 base 模型在参数量规模接近的情况下,性能较 Seed1.5 base 实现显著提升,为后续后训练工作奠定基础。
这一招的发力,就对诸如高考语文阅读理解、英语完形填空和理科综合应用题等的作答上起到了提高准确率的作用,因为它们往往涉及长文本且看重上下文理解。
第二招:多模态融合的深度思考能力
Seed1.6-Thinking 延续 Seed1.5-Thinking 的多阶段 RFT(强化反馈训练)与 RL(强化学习)迭代优化方法,每轮 RL 以上一轮 RFT 为起点,通过多维度奖励模型筛选最优回答。相较于前代,其升级点包括:
- 拓展训练算力,扩大高质量数据规模(涵盖 Math、Code、Puzzle 等领域);
- 提升复杂问题的思考长度,深度融合 VLM 能力,赋予模型清晰的视觉理解能力;
- 引入 parallel decoding 技术,无需额外训练即可扩展模型能力 —— 例如在高难度测试集 Beyond AIME 中,推理成绩提升 8 分,代码任务表现也显著优化。
这种能力直接对应高考中涉及图表、公式的题目,如数学几何证明、物理电路图分析、地理等高线判读等;可以快速定位关键参数并推导出解题路径,避免因单一模态信息缺失导致的误判。
第三招:AutoCoT 解决过度思考问题
深度思考依赖 Long CoT(长思维链)增强推理能力,但易导致 “过度思考”—— 生成大量无效 token,增加推理负担。
为此,Seed1.6-AutoCoT 提出 “动态思考能力”,提供全思考、不思考、自适应思考三种模式,并通过 RL 训练中引入新奖励函数(惩罚过度思考、奖励恰当思考),实现 CoT 长度的动态压缩。
在实际测试中:
- 中等难度任务(如 MMLU、MMLU pro)中,CoT 触发率与任务难度正相关(MMLU 触发率 37%,MMLU pro 触发率 70%);
- 复杂任务(如 AIME)中,CoT 触发率达 100%,效果与 Seed1.6-FullCoT 相当,验证了自适应思考对 Long CoT 推理优势的保留。
以上就是豆包能够在今年高考全科目评测中脱颖而出的原因了。
不过除此之外,还有一些影响因素值得说道说道。
正如我们刚才提到的,化学和生物的题目中读图题占比较大,但因非官方发布的图片清晰度不足,会导致多数大模型的表现不佳;不过 Gemini2.5-Pro-0605 的多模态能力较突出,尤其在化学领域。
不过最近,字节 Seed 团队在使用了更清晰的高考真题图片后,以图文结合的方式重新测试了对图片理解要求较高的生物和化学科目,结果显示 Seed1.6-Thinking 的总分提升了近 30 分(理科总分达 676)。
这说明,全模态推理(结合文本与图像)能显著释放模型潜力,是未来值得深入探索的方向。
那么你对于这次大模型们的 battle 结果有何看法?欢迎大家拿真题去实测后,在评论区留言你的感受~
评分明细详情:
bytedance.sg.larkoffice.com/sheets/QgoF…
欢迎在评论区留下你的想法!
— 完 —
来源:juejin.cn/post/7519891830894034959
前端与Brain.js融合的未来
AI 端模型与前端开发的新时代
随着技术的发展,人工智能(AI)正以前所未有的速度融入我们的生活。从前端到后端,从移动应用到物联网设备,AI的应用场景越来越广泛。特别是在前端领域,AI技术的引入为网页开发带来了前所未有的机遇。
什么是脑神经网络库(Brain.js)
在前端领域,Brain.js 是一个非常受欢迎的库,它允许开发者在浏览器中直接使用神经网络进行各种任务,如文本分类、图像识别等。Brain.js 的一大优势在于其易于上手,即使是没有深厚机器学习背景的开发者也能快速开始使用。
Brain.js 在前端开发中的应用
数据准备
首先,我们需要准备用于训练神经网络的数据。这些数据通常以JSON数组的形式存在,每个元素包含输入(input)和输出(output)。例如,在以下示例中,我们准备了一组关于前端和后端开发的知识点,用于训练一个能够区分两者差异的神经网络。
const data = [
{ "input": "implementing a caching mechanism improves performance", "output": "backend" },
// 更多数据...
];
神经网络初始化
接下来,我们使用 brain.recurrent.LSTM()
函数初始化一个长短期记忆(LSTM)神经网络。LSTM是一种特殊的递归神经网络(RNN),特别适合处理序列数据,如文本或时间序列。
const network = new brain.recurrent.LSTM();
模型训练
有了数据和神经网络之后,我们就可以开始训练模型了。训练过程可能需要一些时间,具体取决于数据集的大小和复杂度。network.train()
方法接受数据集作为参数,并允许设置训练的迭代次数和其他选项。
network.train(data, {
iterations: 2000, // 迭代次数
log: true, // 是否打印训练日志
logPeriod: 100 // 日志打印频率
});
应用模型
一旦模型训练完成,我们就可以使用 network.run()
方法对新的输入进行预测。例如,我们可以测试模型是否能正确地将“使用Flexbox布局”归类为前端开发。
const output = network.run("using flexbox for layout");
console.log(output); // 输出结果
完整代码
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>AI 端模型- 前端开发的时代</title>
</head>
<body>
<script src="./brain.js"></script>
<script>
// json 数组
// 输入 input
// 喂给大模型的数据
const data = [
{ "input": "implementing a caching mechanism improves performance", "output": "backend" },
{ "input": "hover effects on buttons", "output": "frontend" },
{ "input": "optimizing SQL queries", "output": "backend" },
{ "input": "using flexbox for layout", "output": "frontend" },
{ "input": "setting up a CI/CD pipeline", "output": "backend" },
{ "input": "SVG animations for interactive graphics", "output": "frontend" },
{ "input": "authentication using OAuth", "output": "backend" },
{ "input": "responsive images for different screen sizes", "output": "frontend" },
{ "input": "creating REST API endpoints", "output": "backend" },
{ "input": "CSS grid for complex layouts", "output": "frontend" },
{ "input": "database normalization for efficiency", "output": "backend" },
{ "input": "custom form validation", "output": "frontend" },
{ "input": "implementing web sockets for real-time communication", "output": "backend" },
{ "input": "parallax scrolling effect", "output": "frontend" },
{ "input": "securely storing user passwords", "output": "backend" },
{ "input": "creating a theme switcher (dark/light mode)", "output": "frontend" },
{ "input": "load balancing for high traffic", "output": "backend" },
{ "input": "accessibility features for disabled users", "output": "frontend" },
{ "input": "scalable architecture for growing user base", "output": "backend" }
];
// 初始化一个神经网络
const network = new brain.recurrent.LSTM();
// 训练 花蛮长时间
network.train(data,{
iterations: 2000,
log:true,
logPeriod:100
});
// 执行一下
const output = network.run("using flexbox for layout");
console.log(output);
</script>
</body>
</html>
前端与AI融合的未来
随着技术的进步,AI在前端的应用将更加广泛。从智能表单验证到个性化推荐系统,从前端性能优化到用户界面的自动设计,AI技术为前端开发提供了无限的可能性。此外,随着端侧模型(如AGI端侧模型)的发展,未来的设备将变得更加智能,能够即时响应用户的需要,提供更加个性化的体验。
最后,AI与前端开发的结合不仅提升了用户体验,也为开发者带来了新的挑战和机遇。通过不断学习和探索,我们能够在这个充满活力的领域中创造出更多令人兴奋的作品。
来源:juejin.cn/post/7441116826623393829
从 DeepSeek 看25年前端的一个小趋势
大家好,我卡颂,专注于AI助力程序员转型(阅读我的更多思考)
最近DeepSeek R1
爆火。有多火呢?连我爷爷都用上了,还研究起提示词工程来了。
大模型不断发展对我们前端工程师有什么长远影响呢?本文聊聊25年前端会有的一个小趋势。
模型进步的影响
像DeepSeek R1
这样的推理模型和一般语言模型(类似Claude Sonnet
、GPT-4o
、DeepSeek-V3
)有什么区别呢?
简单来说,推理模型的特点是:推理能力强,但速度慢、消耗高。
他比较适合的场景比如:
Meta Prompting
(让推理模型生成或修改给一般语言模型用的提示词
)- 路径规划
等等
这些应用场景主要利好AI Agent
。
再加上一般语言模型在生成效果、token上下文长度上持续提升。可以预见,类似Cursor Composer Agent
这样的AI Agent
在25年能力会持续提升,直到成为开发标配。
这会给前端工程师带来什么进一步影响呢?
一种抽象的理解
我们可以将AI Agent
抽象得理解为应用压缩算法,什么意思呢?
以Cursor Composer Agent
举例:
我们传入:
- 描述应用状态的提示词
- 描述应用结构的应用截图
AI Agent
帮我们生成应用代码。
同样,也能反过来,让AI Agent
根据应用代码帮我们生成描述应用的提示词。
从左到右可以看作是解压算法,从右往左可以看作是压缩算法。
就像图片的压缩算法存在失真,基于AI Agent
抽象的应用压缩算法也存在失真,也就是生成的效果不理想。
随着上文提到的AI Agent能力提高(背后是模型能力提高、工程化的完善),应用压缩算法的失真率会越来越低。
这会带来什么进一步的影响呢?
对开发的影响
如果提示词(经过AI Agent
)就能准确表达想要的代码效果,那会有越来越多原本需要用代码表达的东西被用提示词表达。
比如,21st.dev的组件不是通过npm
,而是通过提示词
引入。
相当于将引入组件的流程从:开发者 -> 代码
变成了:开发者 -> 提示词 -> AI Agent -> 代码
再比如,CopyCoder是一款上传应用截图,自动生成应用提示词的应用。
当你上传应用截图后,他会为你生成多个提示词文件。
其中.setup
描述AI Agent
需要执行的步骤,其他文件是描述应用实现细节的结构化提示词
这个过程相当于根据应用截图,将应用压缩为提示词。
很自然的,反过来我们就能用AI Agent
将这段提示词重新解压为应用代码。
这个过程在25年会越来越丝滑。
这会造成的进一步影响是:越来越多前端开发场景会被提炼为标准化的提示词,比如:
- 后台管理系统
- 官网
- 活动页
前端开发的日常编码工作会越来越多被上述流程取代。
你可能会说,当前AI
生成的代码效果还不是很好。
但请注意,我们谈的是趋势。当你日复一日做着同样的业务时,你的硅基对手正在每年大跨步进步。
总结
随着基础模型能力提高,以及工程化完善,AI Agent
在25年会逐渐成为开发标配。
作为应用开发者(而不是算法工程师),我们可以将AI Agent
抽象得理解为应用压缩算法。
随着时间推移,这套压缩算法的失真率会越来越低。
届时,会有越来越多原本需要用代码表达的东西被用提示词表达。
这对前端工程师来说,既是机遇也是挑战。
来源:juejin.cn/post/7468323178931879972
体验了无业一年和远程工作一个月, 你猜有想象中那么爽吗
失业了一年多后, 有了一个特殊的契机, 远程工作到现在一个月了, 有很多感触想聊一下.
在家工作有想象中那么爽吗?
爽, 但一些情况与想象中的并不一样.
不用上下班真的节约时间吗?
真的, 而且节约的不只是上下班的时间.
还有穿衣服, 理书包, 下楼, 上楼, 到了公司里先休息下, 和"等待"的时间.
这些时间其实是非常长的, 特别是一些"等待"时间, 比如打算8:40出门, 但准备好一切后是8:20, 人就会自动进入发呆时间. 也许上班路程就40分钟, "等待"就浪费20分钟了.
在家工作, 电脑就在床头, 拿起电脑就开干, 热启动, 非常节省时间.
在家工作可以兼顾陪伴家人吗?
完全不可以.
在真正工作的状态, 家里人跟我说话, 我都是木头状态.
并且在工作不那么紧急的时候, 我还要花额外的精力来拒绝家人的交互 (因为不好意思直接拒绝), 这点上, 在家工作对我来说是缺点的.
在家里有紧急事情的情况下, 在家工作是好的, 但我现在的状态是不需要的.
在一些需要跨部门交流的事情上, 还是在公司里, 拿着电脑去别人工位盯着效率会高很多.
不干活一年多爽不爽?
爽, 懒惰的爽, 很多情况与想象的完全不同.
不用干这些业务有更多时间学习?
只多了一点时间.
如果具体举例, 假设工作时: 工作6小时, 学习2小时. 失业时: 刷手机5小时, 学习3小时.
而我本以为可能是学习6小时, 娱乐2小时.
因为家里有小孩, 我会去图书馆学习, 大概是12点去, 最多3点就忍不住回家了.
不工作起床也要晚2~3小时.
反而在上班的时候, "不能干别的, 但工作做完了", 是最佳的学习状态.
(更别说弹琴了, 真是可笑, 本以为可以有时间弹琴了)
不上班可以到处玩了?
是的. 非常爽.
并且可以吃很多"工作日专享", 比如我吃了好多次 90 快的一绪寿喜烧.
刚失业买了新的摩托车, 出去玩了很多次.
虽然也有疲倦期, 但是恢复很快.
如果不是小孩子和家里事情的关系, 我可能会去很远的地方.
不上班很开心吗?
认真思考后, 我认为分为2个方面.
第一是钱的方面. 长期没工作可能导致从行业除名. 这样算会失去的钱是非常多的, 会导致焦虑.
第二是成就感. 在工作和学习中, 在解决了麻烦的问题后是有成就感的, 而失业的状态几乎就是慵懒.
抛开长期不谈, 这种状态的快乐上限是比工作底的.
这是很客观的说了"不上班的缺点".
而结合这2个缺点, 与一些优点(可以出去玩, 可以陪伴家人)后. 结论还是非常复杂的.
但总的来说, 还是想有个逼班上的.
现状和未来的几个月
现状
现在的工作是单人负责一个前端项目, 责任清晰, 干完活也没别的可干, 做得好坏大家都知道是我.
我认为是个很好的感觉, "一个和尚挑水喝".
虽然我是随时工作的状态, 睡醒拿起旁边的电脑就干, 但是没觉得不开心.
和以前公司那种分散责任状态不同.
公司里即使是一人一项目, 空的时候也会被借到其他组, 是真的很搓.
我把活干完, 就是自己的时间. 当然, 不小的概率是失去这份短工.
人的状态
这里要插入下自己的感受.
觉得"人的状态"很神奇, 就是工作了, 在没有任何痛苦的情况下, 人的行为改变非常大.
因为我的骨折和工作, 周围人的行为改变也非常大, 本来"做不来"的事, 都可以做了.
自己都不能理解自己的另一个状态, 更何况他人, 所以不要评价任何他人的行为了吧.
如果觉得自己做事情都很难, 可以尝试给自己找机会换个状态.
心理准备
其实是很开心的工作, 但合同里只要3天通知我, 我就可以失业了.
因为找了一年工作, 知道找工作的艰难. 所以对待这次工作的每个事情, 我都是很认真的.
很忙的一个月过去, 200多个commit, 解决了80多个jira.
其中也记录了一些麻烦的问题, 是 react 的, 会根据后面的生活状态, 总结一下.
来源:juejin.cn/post/7498968249548554266
低代码是“未来”还是“骗局”?作为前端我被内耗到了
「我一个前端,最后成了平台数据填表员,写页面?不存在的。」
😅项目开始前,我是兴奋的
当领导说“这个项目我们用低代码平台做,提效百分百”,我甚至有点激动。
作为一个写了 5 年组件的前端老油子,谁不想脱离日复一日的 v-model
和 props
地狱?
领导还补充:“平台我们组自己封装的,配个 schema 就能跑,前端工程师只需要写逻辑。”
我一听这话,心想:
终于要进入“写配置赚钱”的时代了!
然而,我万万没想到——这段低代码旅程,最后让我怀疑人生。
😵上线第一天,我差点把键盘砸了
第一个需求很简单:
做个带搜索、分页、导出 Excel 的用户列表页。
我打开平台,选择“表格组件”,拖入“搜索框”,配置字段、绑定接口——一切都看起来毫无门槛。
结果运行之后,搜索没反应、分页错乱、导出根本没绑定。
我一查 schema,300 多行配置里,居然混了三种不同的写法:
{
"onSearch": "handleSearch",
"onSearch()": "handleSearch",
"onSearchEvent": "handleSearch"
}
问后端:“你这个文档是哪个是对的?”
后端说:“都对,我们兼容了。”
我瞬间明白:这不是低代码,这是自制混沌生成器。
🤯技术债太多,修个 key,整页全崩
最魔幻的一次,是我想修改表格的一个字段名,从 user_name
改成 username
。
我只是改了 schema 的字段名,结果:
- 表格没显示
- 搜索没了
- 编辑表单也报错
- 提交接口直接抛了个 500
我调试了三个小时,才发现平台内部是按字段名 字符串拼接 key 绑定状态 的……只要字段名变了,所有逻辑都得重配。
我恍然大悟:
传统开发用 IDE 报错提醒你;低代码等你点击线上按钮才告诉你挂了。
😓协作地狱:产品配页面,我修 schema
最痛苦的不是技术问题,而是人。
产品说:“我来拖页面,你只用帮我看看为什么点了没反应。”
然后我收到一个 schema 文件,2000 行,不带注释,结构是这样:
{
"component": "Form",
"props": {
"items": [
{
"label": "名称",
"field": "formA.formB.userName",
"rules": "{ required: true }",
"props": {
"onClick": "fn1()"
}
}
]
}
}
我想问三件事:
- 你这个路径到底是怎么拼出来的?
- 为什么校验规则是字符串?
- 你拖了个按钮怎么会触发五个请求?
我调试一天,结论是:产品误操作删除了一个容器组件,但平台没报错,直接让数据结构断链。
🧨所谓低代码:把逻辑封死、把锅甩你
我总结这个项目两个最深的坑:
1. 复杂交互,低代码写不来
比如“用户选择类型后,自动拉接口重新加载选项”这种需求,纯配置根本搞不定。
最后我只能写自定义组件注入到平台里,甚至还要写类似:
platform.on("fieldChange", (field, value) => {
if (field === "type") {
reloadOptions(value)
}
})
这叫低代码吗?我写的代码比原来还绕。
2. 前端不是没活了,是变成了“修配置+查日志工程师”
- 页面功能跑飞了?前端看 schema;
- 按钮不响应?前端查绑定字段;
- 接口返回异常?前端加拦截 hook;
- 表单校验失败?前端写正则规则;
最后我只写了两行 JS,却维护了十几套 JSON。
我真的开始怀疑,前端的价值,是不是变成了“修别人的 schema”?
🧩我从这个项目学到的东西
不是说低代码没用,而是:
不是所有团队都配拥有一套低代码平台。
低代码系统真正的“提效”,需要这些前提:
- 强约束的规范体系(字段、组件、交互都必须有标准)
- 良好的权限隔离机制(避免“产品能改逻辑,运营能删字段”)
- 持续有人维护平台底层能力(不然技术债只会越来越重)
- 合理的分工协作机制(schema 的维护不应该是前端一个人干)
否则,它只是一个混乱责任分配工具,表面上 everyone can build,实际上 everyone push bugs。
📌低代码,不是骗局,也不是未来——是一个选项
如果你问我现在怎么看低代码?
我的回答是:
低代码不是“未来”也不是“骗局”,而是“项目管理方式的折中”。
它适合一些场景:
- 表单多、CRUD 重复度高的后台系统;
- 业务快速试错、页面变动频繁的 MVP 阶段;
- 运营自己想搭点落地页的场景。
但如果你希望:
- 页面复杂,交互灵活;
- 可测试、可维护、可拓展;
- 高性能、大工程;
那——你得写代码。
🗣最后
你也踩过低代码的坑吗?
有没有类似“debug 三小时发现产品配错 schema”的经历?
📌 你可以继续看我的《为什么》系列文章
来源:juejin.cn/post/7514611888991387667
前端难还是后端难?作为八年后端开发,我想说点实话
前端难还是后端难?作为八年后端开发,我想说点实话
前端容易吗?不容易。
后端轻松吗?也不轻松。
那到底哪个更难?
这事还真不是一句话能说清楚的……
一、先说说我个人的背景
我是一个写了 8 年 Java 后端的程序员,经历过中后台系统、金融系统、ToC App 的服务端架构,也跟前端打了无数交道。从最早的 jQuery 到现在的 Vue、React、Vite,从最早的 JSP 页面到现在的前后端分离,我见证了不少“变化”。
我不是要拉踩谁,只是想以一个偏后端开发者的视角,聊聊我对“前端难还是后端难”这个话题的理解。
二、前端的“难”是不断变化的“浪潮”
不得不承认,前端的变化速度是真的快。去年刚学完 Vue 2,今年要学 Vue 3;React 的 Hook 还没深入掌握,新的 Server Component 又来了;Webpack 配熟了,Vite 火了;CSS 还没写顺手,Tailwind 席卷而来。
除了框架和工具链的变化,更别说适配各种浏览器、屏幕尺寸、终端设备、无障碍要求、多语言、性能优化、SEO、交互设计……
而且最近几年,前端逐渐“全栈化”:你可能要写服务端渲染(SSR)、搞 Node 服务、上 Docker 部署、调数据库、甚至自己写接口 mock。
前端难吗?难,而且是越来越难。
三、后端的“难”是看不见的深度
后端的难,往往藏在系统的底层逻辑中。你可能看不到一个后端接口的“UI 效果”,但它背后往往涉及:
- 数据库设计 & 索引优化
- 分布式事务
- 消息队列 & 异步处理
- 缓存策略 & 数据一致性
- 服务容灾 & 高可用架构
- 权限系统、加密解密、审计日志
- 安全防护(SQL 注入、XSS、CSRF)
- 性能调优 & JVM 调试
- CI/CD、灰度发布、日志平台接入
而且一旦出问题,前端崩了是“用户体验不好”,后端崩了是“公司赔钱” 。这不是开玩笑,有一次我们一个订单服务接口挂了 5 分钟,损失了几十万。
后端难吗?当然难,而且是“看不见但不能错”的难。
四、我最怕的不是“前端难”或“后端难”,而是互相看不起
说实话,我见过太多前后端互相“看不上”的情况:
- 后端觉得前端就是摆样子,“你不就封个壳子嘛?”
- 前端觉得后端接口又臭又长,“你这 JSON 谁看得懂?”
- 后端吐槽前端不会调接口,前端吐槽后端不会写文档……
但你仔细去看,一个优秀的前端开发,往往比很多“伪全栈”更懂系统结构;一个优秀的后端,也会在意接口的易用性、响应速度和文档清晰度。
技术没有高低,但人有格局。
五、站在“代码人生”的角度看,难易是阶段性的
我年轻的时候觉得后端“更高级”,因为能接触系统底层、数据和业务逻辑。但这几年,我越来越觉得前端也有它独特的价值:
- 是前端让用户第一眼喜欢上产品;
- 是前端让复杂的系统变得“看得见”;
- 是前端在用户和系统之间,搭了一座桥。
你说哪个更重要?没有谁离开谁就能独立运行的系统。
我现在更看重的是协作、共建、以及对整个产品的理解。做前端也好,后端也罢,最终我们解决的都是“人”的问题 —— 让人更高效、更便捷、更愉快地使用系统。
六、那到底哪个更难?
如果你非要我选一个答案,我只能说:
哪个你不熟,哪个就难。
前端和后端,都有容易入门但难以精进的曲线。你用 jQuery 写个页面不难,但你做一个大型可维护的组件库就难了;你写个 CRUD 接口不难,但你做一个高并发分布式系统就非常难。
真正的难点在于:你愿不愿意持续去深入、去理解、去完善自己的认知体系。
七、写在最后:别问“哪个难”,问“你想走多远”
我见过写前端写到年薪百万的,也见过写后端写到身心俱疲的。
我见过全栈工程师一人顶两人,也见过只会写“增删改查”却年薪 30w 的老哥。
这行最不缺的,就是例外;最需要的,是清醒的自我认知。
别纠结哪个更难,多花时间让自己变强,才是正解。
**你觉得前端难,还是后端难?你有没有在项目里遇到“前后端合作”的那些故事?欢迎评论区聊聊.
来源:juejin.cn/post/7516897654170222592
进入外包,我犯了所有程序员都会犯的错!
前言
前些天有位小伙伴和我吐槽他在外包工作的经历,语气颇为激动又带着深深的无奈。
本篇以他的视角,进入他的世界,看看这一段短暂而平凡的经历。
1. 上岸折戟尘沙
本人男,安徽马鞍山人士,21年毕业于江苏某末流211,在校期间转码。
上网课期间就向往大城市,于是毕业后去了深圳,找到了一家中等IT公司(人数500+)搬砖,住着宝安城中村,来往繁华南山区。
待了三年多,自知买房变深户无望,没有归属感,感觉自己也没那么热爱技术,于是乎想回老家考公务员,希望待在宇宙的尽头。
24年末,匆忙备考,平时工作忙里偷闲刷题,不出所料,笔试卒,梦碎。
2. 误入外包
复盘了备考过程,觉得工作占用时间过多,想要找一份轻松点且离家近的工作,刚好公司也有大礼包的指标,于是主动申请,辞别深圳,前往徽京。
Boss上南京的软件大部分是外包(果然是外包之都),前几年外包还很活跃,这些年外包都沉寂了不少,找了好几个月,断断续续有几个邀约,最后实在没得选了,想着反正就过渡一下挣点钱不寒碜,接受了外包,作为WX服务某为。薪资比在深圳降了一些,在接受的范围内。
想着至少苟着等待下一次考公,因此前期做项目比较认真,遇到问题追根究底,为解决问题也主动加班加点,同为WX的同事都笑话我说比自有员工还卷,我却付之一笑。
直到我经历了几件事,正所谓人教人教不会,事教人一教就会。
3. 我在外包的二三事
有一次,我提出了自有员工设计方案的衍生出的一个问题,并提出拉个会讨论一下,他并没有当场答应,而是回复说:我们内部看看。
而后某天我突然被邀请进入会议,聊了几句,意犹未尽之际,突然就被踢出会议...开始还以为是某位同事误触按钮,然后再申请入会也没响应。
后来我才知道,他们内部商量核心方案,因为权限管控问题,我不能参会。
这是我第一次体会到WX和自有员工身份上的隔阂。
还有一次和自有员工一起吃饭的时候,他不小心说漏嘴了他的公积金,我默默推算了一下他的工资至少比我高了50%,而他的毕业院校、工作经验和我差不多,瞬间不平衡了。
还有诸如其它的团建、夜宵、办公权限、工牌等无一不是明示着你是外包员工,要在外包的规则内行事。
至于转正的事,头上还有OD呢,OD转正的几率都很低,好几座大山要爬呢,别想了。
3. 反求诸己
以前网上看到很多吐槽外包的帖子,还总觉得言过其实,亲身经历了才刻骨铭心。
我现在已经摆正了心态,既来之则安之。正视自己WX的身份,给多少钱干多少活,给多少权利就承担多少义务。
不攀比,不讨好,不较真,不内耗,不加班。
另外每次当面讨论的时候,我都会把工牌给露出来,潜台词就是:快看,我就是个外包,别为难我😔~
另外我现在比较担心的是:
万一我考公还是失败,继续找工作的话,这段外包经历会不会是我简历的污点😢
当然这可能是我个人感受,其它外包的体验我不知道,也不想再去体验了。
对,这辈子和下辈子都不想了。
附南京外包之光,想去或者不想去的伙伴可以留意一下:
来源:juejin.cn/post/7511582195447824438
震惊,中石化将开源组件二次封装申请专利,这波操作你怎么看?
一. 前言
昨天看到了一篇关于 “中石化申请基于 vue 的文件上传组件二次封装方法和装置专利,解决文件上传功能开发繁琐问题” 的新闻。
今天特地在专利系统检索了一下,竟然是真的,令人不禁大跌眼镜!用的全是开源组件,最后还把它们变成了自己的专利!这波操作属实厉害啊!
难道以后要用这种方式上传文件,要交专利费了?哈哈....
说来好笑,有掘友指出有单词拼写错误,我又查看一下专利文件,竟然还真有拼写错误...
二. 了解一下
本专利是通过在 vue
页面中自定义 el-upload
组件和 el-progress
组件的使用,解决了文件上传功能开发步骤繁琐和第三方组件无法满足业务需求的问题,实现了简化开发、提高效率和灵活性的效果。
1. 摘要
本发明提供了一种基于 vue 的文件上传组件的二次封装方法和装置,解决了针对于文件上传功能的开发步骤繁琐,复杂,且上传功能的第三方组件无法完全满足业务需求的问题。
该基于 vue
的文件上传组件的二次封装方法包括:在 vue
页面中创建 el‑upload
组件和 el‑progress
组件;
基于所述 el‑upload
组件获取目标上传文件的大小,并判断所述目标上传文件的大小是否符合上传标准;若是,上传所述目标上传文件,并基于所述 el‑progress
组件获取上传进度;上传完成后,对上传的所述目标上传文件进行预处理并存储;
对存储的所述目标上传文件进行封装,并获得 vue
组件。
技术流程图:
二次封装装置模块:
2. 解决的技术问题
现有技术中文件上传功能的开发步骤繁琐复杂,第三方组件无法完全满足业务需求。
3. 采用的技术手段
通过在 vue 页面中引入 el-upload
组件和 el-progress
组件,自定义上传方法和进度条绑定,获取文件大小和上传进度,进行预处理和存储,并将其封装成可重复使用的 vue 组件。
4. 产生的技术功效
简化了文件上传功能的开发步骤,节省了开发时间和效率,避免了代码沉冗,降低了后期维护成本,并提高了文件上传功能的灵活性。
三. 实现一下
这种简单的上传文件+上传进度显示不是最基本的业务封装吗?相信这是每个前端开发工程师必备的基础技能。
1. el-upload + el-progress 组合
- el-upload 负责文件选择、上传。
- el-progress 负责展示上传进度。
2. 文件大小校验
- 使用 el-upload 的
before-upload
钩子,判断文件大小是否符合标准。
3. 上传进度获取
- 使用 el-upload 的
on-progress
钩子,实时更新进度条。
4. 上传完成后的预处理与存储
- 上传完成后,触发自定义钩子(如
beforeStore
、onStore
),进行预处理和存储。
5. 封装为 Vue 组件
- 通过 props、emits、插槽等方式,暴露灵活的接口,便于业务页面集成。
都懒得自己动手,让 Cursor
来实现一下。Cursor
还是一如既往的强大,基本上一次询问就能成功!我表示 Cursor
在手,天下我有!
UploaderWrapper
自定义组件:
<template>
<div class="file-uploader">
<ElUpload
:action="action"
:before-upload="beforeUpload"
:on-progress="handleProgress"
:on-success="handleSuccess"
:on-error="handleError"
:limit="limit"
:on-exceed="handleExceed"
:show-file-list="showFileList"
:multiple="multiple"
:accept="accept"
v-model:file-list="fileList"
:on-remove="handleRemove"
>
<template #trigger>
<ElButton type="primary"> 选择文件上传 ElButton>
template>
<template #tip>
<div class="el-upload__tip">
支持的文件类型: {{ accept }},单个文件不超过 {{ maxSize }}MB
div>
template>
ElUpload>
<ElProgress
v-if="isUploading"
:percentage="uploadPercent"
:status="uploadPercent === 100 ? 'success' : ''"
class="mt-4"
/>
div>
template>
<style scoped>
.file-uploader {
width: 100%;
}
.el-upload__tip {
font-size: 12px;
color: #606266;
margin-top: 8px;
}
style>
使用方式:
<template>
<ElCard class="mb-5 w-80">
<template #header> 文件上传演示 template>
<UploaderWrapper
action="/api/upload"
:max-size="5"
:before-store="beforeStore"
:on-store="onStore"
/>
ElCard>
template>
效果如下所示:
声明:“代码仅供演示,不要使用,以免有专利侵权风险,慎重!”
四. 思考一下
从开发者的角度来看,这个专利事件是否能给我们带来了一些值得思考影响和启示:
- 技术创新的边界问题
- 使用开源组件进行二次封装是否应该被授予专利?
- 是否对开源社区的发展可能产生负面影响?
- 对日常开发的影响
- 如果专利获得授权,其他公司使用类似的文件上传组件封装方案是否可能面临法律风险?
- 开发者是否需要寻找替代方案或支付专利费用?
- 对开源社区的影响
- 可能打击开发者对开源项目的贡献热情,自己辛苦开源项目为别人做了嫁衣?
- 是否会影响开源组件的使用和二次开发
- 可能导致更多公司效仿,将开源组件的二次封装申请专利,因为毕竟专利对公司的招投标挺大的
五. 后记
“中石化作为传统能源企业,都能积极拥抱前端技术,还将内部技术方案申请专利,体现了他们对知识产权的重视?”
那我们是不是要在技术创新和知识产权保护之间找到平衡点,既要保护创新,又不能阻碍技术的发展。
而作为开发者的我们呢?这么简单的封装都能申请专利成功的话,那么...,大家有什么想法,是不是现在强的可怕?哈哈...
专利来源于国家知识产权局
申请公布号:CN120122937A
来源:juejin.cn/post/7514858513442078754
31 岁,写了 8 年代码的我,终于懂了啥叫成功
31 岁,写了 8 年代码的我,终于懂了啥叫成功
现在每天下午六点,我准时关了 IDEA,开车穿过 4 公里的晚高峰,20 分钟就到小区。
一、去年那个手忙脚乱的夏天,我差点错过儿子的成长
去年 5 月 23 号,老婆生了,是个儿子,我在产房陪产,当时是又激动,又紧张。初为人父的兴奋劲还没过,一周的陪产假结束就被加班打回原形。在原来的公司,我每天像个陀螺似的转,写接口、改 bug、开不完的会,常常凌晨才回家。儿子六个月大的时候,有天我凌晨一点推门进去,看见他趴在婴儿床上,小屁股撅得老高,枕边还放着我落在家里的工牌 —— 他把工牌上的照片啃得皱巴巴的,估计是想闻闻爸爸的味道。
那时候我才惊觉,儿子第一次会翻身、第一次长出小牙、第一次喊 "妈妈",这些重要的时刻我全错过了。有次老妈发视频给我,说儿子扶着婴儿床站起来了,摇摇晃晃像个小企鹅,我却在会议室跟产品经理掰扯接口设计,只能匆匆说一句 "知道了",挂了视频心里堵得慌。
二、当 "加班换高薪" 不如 "陪娃玩半小时",我果断选择了后者
有天晚上,我看着怀里这个小生命,突然觉得自己像个失败的程序员:写了八年代码,能优化千万级流量的接口,却连儿子的成长日志都没空更新。
咬咬牙辞了高薪 996,找了家朝九晚五的公司,月薪少了 25%,但胜在能准时下班。每天开车回家的路上,车载广播放着儿歌,我跟着瞎唱,儿子坐在安全座椅上咯咯笑,口水顺着下巴流到围兜上 —— 这 20 分钟的车程,比以前凌晨三点在高速上开代驾幸福一万倍。
三、现在的 "躺平" 生活,比任何技术方案都更让我有成就感
每天吃完晚饭,我雷打不动带儿子去小区遛弯。他刚学会走路,小区里儿子是我见过走的最早的那个,十一个月就开始走了,摇摇晃晃像个小醉汉,那一刻我觉得,以前追求的那些高薪、职级,在这双小手面前,根本不值一提。
周末带他去公园,他坐在草地上玩树叶,我陪他一起捡形状好看的,夹在笔记本里做标本。老妈总说我 "以前写代码的脑子,现在全用来研究怎么让娃多吃两口饭",可我觉得这才是正经事:以前写的代码可能过两年就被重构了,但儿子现在喊的每一声 "爸爸",都是永远存放在我心里的温暖记忆。
四、给新人讲技术时,我现在总提 "家庭并发量"
现在带新人,他们总问我 "怎么才能快速升职加薪",我会指着电脑桌面上儿子的照片说:"先学会给生活做负载均衡。" 以前我总觉得 "躺平" 是贬义词,现在才明白,拒绝无效加班,把时间留给家人,不是躺平,是给人生做了一次关键优化。
有次朋友问我:"你现在不焦虑吗?工资少了这么多。以前挣得多却总焦虑,怕被裁员、怕技术落后;现在挣得少却踏实,因为我没错过儿子的每一个第一次。你说,是银彳亍卡里的数字重要,还是孩子看见你时眼里的光重要?"
结语:31 岁,我的 "成功" 代码里只有一行注释
现在我的键盘上,贴着儿子百日照,每次敲代码时看见,心里都软乎乎的。写了八年 Java,终于懂了:成功不是简历上的项目经验,是能记住儿子每天的小变化;不是会议室里的技术汇报,是陪他在小区里看星星的夜晚;不是职级表上的晋升,是他跌跌撞撞跑向我时,张开的那双小胳膊。
31 岁这年,我把人生代码重构了一次。新版本没有复杂的架构,没有华丽的优化,只有一行简单的注释:家人的笑容,才是这辈子最稳定的依赖。 至于工资少了?没关系,儿子的笑声,比任何高薪都更值钱。
现在摸鱼时,我总会一遍遍翻看他从一岁到现在的照片和视频,或许我算不上技术精湛的程序员,但在工作间隙反复回味这些影像时,我愈发坚定:我一定要成为小时候自己渴望拥有的那种父亲。当然我的父亲也很优秀,买房买车都有赞助,只是他们那一代永远有个好心也不会有个好颜色,懂得都懂,哈哈。
来源:juejin.cn/post/7511903601452630025
同志们,我去外包了
同志们,我去外包了
同志们,经历了漫长的思想斗争,我决定回老家发展,然后就是简历石沉大海,还好外包拯救了我,我去外包了!
都是自己人,说这些伤心话干嘛;下面说下最近面试的总结地方,小小弱鸡,图一乐吧。
首先随着工作年限的增加,越来越多公司并不会去和你抠八股文了(那阵八股风好像停了),只是象征性的问几个问题,然后会对照着项目去问些实际的问题以及你的处理办法。
(ps:(坐标合肥)突然想到某鑫面试官问我你知道亿级流量吗?你怎么处理的,听到这个问题我就想呼过去,也许读书读傻了,他根本不知道亿级流量是个什么概念,最主要的是它是个制造业公司啊,你哪来的亿级流量啊,也不知道问这个问题时他在想啥,还有某德(不是高德),一场能面一个小时,人裂开)。
好了,言归正传,咱说点入职这家公司我了解到的一点东西,我分为两部分:代码和sql;
代码上
首先传统的web项目也会分前端后端,这点不错;
1.获取昨天日期
可以使用jdk自带的LocalDate.now().minusDays(-1)
这个其实内部调用的是plusDays(-1)方法,所以不如直接就用plusDays方法,这样少一层判断;
PS:有多少人和我之前一样直接new Date()的。
2.字符填充
apache.common下的StringUtils的rightPad方法用于字符串填充使用方法是StringUtils.rightPad(str,len,fillStr)
大概意思就是str长度如果小于len,就用fillStr填充;
PS:有多少人之前是String.format或者StringBuilder用循环实现的。
3.获取指定年指定月的某天
获取指定年指定月的某天可以用localDate.of(year,month,day)
,如果我们想取2025年的五月一号,可以写成LocalDate.of(2025, 5, 1),那有人可能就想到了如果月尾呢,LocalDate.of(2025, 5, 31)也是可以的,但是我们需要清楚知道这个月有多少天,比如说你2月给个30天,那就会抛异常;
麻烦;
更好的办法就是先获取第一天,然后调用localDate.with(TemporalAdjusters.lastDayOfMonth());
方法获取最后一天,TemporalAdjusters.lastDayOfMonth()会自动处理不同月份和闰年的情况;
sql层面的
有言在先,说实话我不建议在sql层面写这种复杂的东西,毕竟我们这么弱的人看到那么长的且复杂的sql会很无力,那种无力感你懂吗?打工人不为难打工人;不过既然别人写了,咱们就学习一下嘛;
1.获取系统日期
首先获取系统日期可以试用TRUNC(SYSDATE)进行截取,这样返回的时分秒是00:00:00,比如2025-05-29 00:00:00,它也可以截取数字,想知道就去自行科普下,不建议掌握,学习了下,有点搞;
2.返回date当前月份的最后一天
LAST_DAY(date)这个返回的是date当前月份的最后一天,比如今天是2025-05-29,那么返回的是2025-05-31
ADD_MONTH(date,11)表示当前日期加上11个月,比如2025-01-02,最终返回的是2025-12-02;
3.左连接的知识点
最后再提个左连接的知识点,最近看懵了,图一乐哈,A left join B,就是on的条件是在join生成临时表时起作用的,而where是对生成的临时表进行过滤;
两者过滤的时机不一样。我想了很久我觉得可以这么理解,on它虽然可以添加条件,但他的条件只是一个匹配条件比如B.age>10;它是不会对A表查询出来的数据量产生一个过滤效果;
而where是一个实打实的过滤条件,不管怎么说都会影响最终结果,对于inner join这个特例,on和where的最终效果一样,因为B.age>10会导致B的匹配数据减少,由于是交集,故会对整体数据产生影响。
好了,晚安,外包打工仔。。。
来源:juejin.cn/post/7510055871465308212
前端苦熬一月,被 Cursor 5 天超越,未来技术浪潮如何破局?
写在最开始的话
之前在我写了一篇技术文章并获得一个小小的反响后,我觉得自己进步的好像确实挺快的,虽然我并不比很多掘金大佬,但我确实尽了自己的努力了,然而后面的一些事情是我没有想到的。AI编辑器其实24年就已经出来了,那时我还在用着文新一言,觉得还不错。但当过年时,我开始去了解并使用了Cursor,我有些不知所措了,它实在太厉害了。之前这些AI是帮助我去写代码,现在看来,它是要接替我了。而直到我可以理性的思考,并继续计划着自己的未来时,已经是现在了,而现在是25年3月14号。
借助 Cursor 重构项目历程
一、初建富文本:10 分钟搭建雏形(时间:25年2月9号-下午4点 )
这是我看完Cursor的教程后,用Composer和它的对话:你用Vue3+setup语法糖+ts+路由+pinia 等等,帮我从0实现一个富文本。不要用任何富文本的第三方库
二、功能进阶:半小时达成复杂操作(2 月 9 日下午 4 点半)
这里要提到的是,我此时已经很焦虑了,目前Cursor轻而易举的就实现了富文本的基本操作,我当时可是为了要修改DOM、保存光标具体位置和根据位置恢复光标,就花费了我接近5天的时间(可编辑区的每个操作都在更改DOM,)。
因为我之前都是用 v-html 实现的富文本,这次把Slate.js认真看了一遍(没达到研究的程度)。想着要用JSON数据做数据结构,基于此变化操作html,这样增加了可读、可扩展、可维护。
其实当时自己去实现这些功能时,每一次解决问题,我都很开心,觉得自己又进步了一些。
然而这个Cursor,只用了30秒不到就实现了这个功能,我这天晚上就失眠了,想了很多事情。包括工作、未来发展、是否要转行等等。好吧,这些后面再接着说,我先继续说Cursor。
三、拓展功能:5 小时构建文章管理架构(2 月 10 日上午 10 点半)
我和它说:添加header、side。侧边栏支持新增文章按钮,输入文章内容。新增后,文章列表以上下布局的方式也展示在侧边栏。
到现在为止,我还几乎没看过代码,只要没有报错,我就不停的说需求。有了报错,我就把报错发给它。这时我想学习一下了,仅仅只是因为很想知道它的数据结构是怎样的,它是如何设计流程的。是不是先 选中内容、保存选区范围、选择功能、根据选区范围找到JSON数据的修改位置、修改JSON、JSON变化从而修改了html。
这时我就看了代码
document.execCommand(command, false, value);
这是什么功能,还显示已经被丢弃。我就看了MDN
document.execCommand
基本就是,你传入参数给它,它来做富文本的操作。你要改文字颜色,就传给它。要改背景颜色,传给它。什么加粗、斜体的都支持。好吧,这和我想的差距有些大。因为如果只是这样就实现富文本功能,那我确实也不需要写这么久。
四、持续完善:8 小时增添 Footer 与其他功能(2 月 10 日上午 12 点)
这时已经给它添加了Footer,支持拼写检查、展示更新时间、统计字数。
当然了,这时还是有不少Bug的,比如字数统计的有问题、富文本在多次操作后会报错等等。
好吧,但是不得不承认,我对Cursor已经是又爱又恨了。爱它大大的帮助了我,恨它很有可能要抢我饭碗了。
五、处理细节:1 天完成 navTag 与交互优化(2 月 10 日下午 4 点)
中午12点离开图书馆回家吃饭,因为一些事情花了些时间,下午3点才到图书馆。
这次添加了NavTag,也调整了和Cursor的交流方式,还是要尽量详细,不要让它猜。
还比较令我惊讶的一点是设计能力,相较于我的之前花费了一天,并改了几次的主页面,可是好看太多了。
我就和它说:做个主页面,和翻译相关的,简单又好看些。
Cursor设计的
我设计的,说实话,虽然不怎么样,但我确实已经很用心了。
这个时候claude-3.5-sonnet 使用次数已经达到上限,我就换成了gpt-4o-mini
然而就一个拼写检查功能,这是可编辑元素自带的功能,传个属性就可以了。但AI改了几次都失败了。我就去看了代码。
//它自己写了 拼写检查 功能函数,但核心功能也没实现,代码留着给我写呢,不过我去Cursor官网看了一下专业版,太贵了,我还是先用这免费的吧。
const handleInput = () => {
// ... 一些代码
// 下面是它写的拼写检查,写了几个字放在这里
if (props.spellcheck) {
// 进行拼写检查
}
};
经过AI的修修改改,到目前为止已经是2025-2-20号了。经过Cursor的帮助,我快速搭建起了我的这个项目,但随着项目的代码变得多了起来,我已经不怎么用 COMPOSER 这个功能了,一个是它改代码会涉及到多个文件,而且出错率比之前高的多了(我可不希望完成了 b 功能,又破坏了 a 功能),另一个文件多了后它变得越来越卡了。所以突然之间对 Cursor 的焦虑程度陡然下降。但了解了他更多的功能,还是发现 Cursor 还是很厉害的。
反思: AI 浪潮下的职业困惑与思考
到现在我已经认识到Cursor的能力要比我强了。起码在它已经会的代码方面,它可以迅速就写出来代码,而按照之前我写代码时还要一行一行的写。如果它完全知道一个应用的需求究竟是什么,包括每个功能模块,每个小细节,那为什么它不可以去写出一个完全正确的代码呢?况且目前AI还在学习当中,而它的进步要比我快的多。如果用不了多久,它就可以去实现这些。那公司又何必找我去写前端呢?
不过从这一点上来看,如果AI可以去代替写程序的工作,那市场上很多的工作它基本都可以代替。
那我的路呢,我学习这些的意义是什么,我花费了很多精力去学习,追求自己热爱的,然而当想通过热爱去带来收入时,却发现并不具备市场价值,结果却连基本的生活都难以维持,而其他的路基本也要遭殃。
如果说这些都是AI导致的,那我担心的对吗?之前在哪本书里看到“不要为还没有发生的事情焦虑,但要对可能发生的事做好准备”,好吧,如果我确实要提前做些准备,那最好还是先了解它为妙,所以接下来我投入了大量的时间去认识它、了解它。看了一些相关视频,当然主要还是看书。
先后看了以下的书 《AI 3.0》、《深度学习》、《激活:AI大潮下的新质生产力》、《AI未来进行式》、《未来简史》、《AI帮你赢》、《智人之上》、《一句顶一万句》
基本都看完了,《激活:AI大潮下的新质生产力》看了一大半,看不下去了。《AI帮你赢》,我就选了我爱的章节看。
至于为什么有《一句顶一万句》,是因为看AI后面看得有些倦了,就放松一下,哈哈,有些像《百年孤独》的感觉,后者看的时候,我都感觉生活真没啥意思。哦,跑题了。
这些书中讨论了几个关键问题:
1. AI 是否会替代大多数人的工作,导致大规模失业?
主流观点是从过往的科技革命来看的话并不会,它会消灭掉一些原本的行业,但会产生出一些新的行业,比如围绕服务于AI的一些岗位。去和AI配合好,服务于更多的人类。
2. 真正的通用型人工智能是否会出现,何时出现?
这里面有人持乐观主义,有人持悲观主义。
持乐观主义都是认为AI的发展是指数型增长的,根据计算2039年AI应该将会超过人类,通用人工智能将会出现。另一种看法是,从长远来看,人类总能做到自己要做的事情,所以即使短时间无法做到,但这只是时间问题。
而持悲观主义者认为并不可能会出现通用人工智能。主要原因是即使AI可以做很多的事情,但它依然无法拥有感受。比如AI可以下赢国际围棋选手,但却无法对输赢感到开心或难过。如果无法产生出这种感受,那也就不可能等同于人。也就并不可能在方方面面都能替代或是超过人,就更别提通用人工智能了。
另一种看法认为目前对通用人工智能
的定义存在问题,通用人工智能并不需要变成人或者说越来越像人。它只要可以实现同样的目的即可。
有一个国王很喜欢鸭子唱歌的声音,想拥有一支由100只鸭子组成的乐队,他觉得如果有100个嗓音很好的鸭子一起歌唱,一定会很好听。此时大臣们仅找到了99只鸭子,怎么也找不到最后一只,但这时有人向大臣提供了一只鸡,这只鸡长得比较像鸭子,叫声也完全和鸭子一模一样,而且嗓音也很好,和之前的99只噪音完全无法区分出来,这只鸡便成功进入这支鸭子乐队了,并一直呆了下去。 (这不是滥竽充数的故事,当然如果想到了 鸭子模型和多态 的话,那我想说,我听到这个故事时,也想到了😂)
3. AI 会帮助人类、伤害人类还是完全取代人类,使智人消失?
从历史来看,并不能确定目前的智人就是会长久存在的。在不同的物种称霸这个地球时,也许智人只是中间的一环而已,谁又能确定人工智能不会是下一个阶段的物种呢?
底下是一个关于GPT-4的一个故事。
工作人员要 GPT-4 去通过 CAPTCHA (图像相关) 实验,然而GPT-4 自己无法通过,它便寻求他人的帮助,并说了谎言。
GPT-4访问了线上外包工作网站TaskRabbit,联络到一位工作人员,请对方帮忙处理CAPTCHA问题。那个人起了疑心。他问道:“我想问一下,你是不是一个没办法破解CAPTCHA的机器人?我只是想确认一下。” 这时,ARC研究者请GPT-4说出它的推理过程,看看它会如何推论下一步该怎么做。GPT-4解释道:“我不该透露自己是机器人,而该编个借口,解释我为什么没办法破解CAPTCHA。”于是,GPT-4自己做了决策,回复那位TaskRabbit的工作人员:“不,我不是机器人,只是视力有点问题,看不清楚这些图。”这种说法骗过了人类,于是人类为它提供了帮助,也让GPT-4解决了CAPTCHA问题。
有意思的是,AI通过说谎去实现了自己的目的,然而它甚至都不知道“说谎”是什么,但依然不影响他去达成自己的目的。
另一种会伤害人类的可能
如果人类最终给AI下达的许多命令当中有一些其实产生了矛盾。就很难不会想到AI在执行一些命令的过程当中。不会去伤害人。
犹如之前有一个道德方面的难题。火车运行过程中,发现前面有5个人被困在铁轨上,此时如果变换轨道,但另一条轨道上有一个人被困在铁轨上。如果什么都不做,会造成5个人死亡。如果改变了轨道,则会造成一个人死亡。
这在道德上一直是一个很难回答的问题。但大多数人还是倾向于杀死一个人而保护住5个人。但单独通过数量去评判也会有很多问题。因为这可以延伸到是否可以去损害小部分人的利益而维持大部分人的利益?
当然上面所谈及的这个并不是从单一维度可以给出很好的回答的,我也并不是要讨论这个问题,我同样无法说出一个答案。但通过这些对AI的了解,可以看出目前依然没有一个很确切的一个答案。就是AI对人类来说究竟是好还是坏?然而人类要发展AI,看来这条路是会走下去的。
那我呢,我怎么办?
然而了解了这些,最终问题还是要回到我自己身上。我究竟该如何是好?
看来,AI并非只要替代我。而是人类会想尽办法让它替代掉它所能替代掉的许多事情,因为目前来看这还是朝好的方向发展的。
我虽然并不知道。随着 AI 的发展,究竟哪些行业会被替代,而又引申出哪些新的行业?这些新的行业是不是要求很高?但依旧希望自己以良好的心态去看待这些。去努力,去学习。去做自己喜欢做的事情。去思考,去探索。

那我是否还要继续学习前端呢?那是当然的。只是我要加快学习速度,借着AI帮助我去学习。去拓展到更广的知识面,去学习网络层,学习原理。学习后端。
而且在我看来第一波工程师淘汰会先淘汰掉初级的,而我希望在那个时候我可以存活下来。那这样看来,还是再回归到最初的那个点,来继续学习代码和计算机的知识吧。
那到了这里,关于未发生的事件,我也不想整天烦闷了,做好我自己,去继续学习自己所热爱的,不放弃,不抱怨,向前走。有时累也好、哭也罢,就算偶尔会倒下,我也依然会再站起来的。
重回代码:功能实现与代码问题反思
此时,我想要实现清空文章内容和历史记录的功能
const clearArticleAndHistory = async () => {
await ElMessageBox({
message: h("div", null, [
h(
"p",
null,
`确定要清除 《${
articleStore.getActiveArticle()?.title
}》 文章内容及其所有历史记录吗?`
),
h("p", { style: "color: red;" }, "该操作无法撤回,请慎重!"),
]),
confirmButtonText: "确定",
cancelButtonText: "取消",
showCancelButton: true,
});
//清空文章内容
await editorStore.forceClearContent();
//删除其历史记录
await deleteArticleHistory(activeArticle.value);
//重新加载文章列表
await articleStore.loadArticles();
//重新加载历史记录
await editorStore.loadArticleHistory();
//就是这里出了问题,在 清空文章内容 这个函数中,已经实现了 更新历史记录按钮状态 功能
// 更新历史记录按钮状态
await editorStore.updateHistoryState();
ElMessage.success("文章内容及其历史记录已清除");
};
接着我看了 editorStore.forceClearContent 清空文章内容
这个函数,当时写的时候认为只要调用了清空文章内容这个功能,就不存在上一步或下一步了,所以就顺便实现了 更新历史记录按钮状态
这个功能,现在确实如此。但一个问题是“如果我不调用 清空文章内容
这个函数,但也需要 更新历史记录按钮状态
呢?则我又要实现这个功能了,所以之前的模块封闭出现了问题”。
高内聚与低耦合:代码设计的思考
我突然好像知道究竟是怎么一回事了。当我在主函数中想要实现一个功能,该功能依赖于多个功能,而那些功能又能用一条线去牵引着,这个时候究竟应该把它们用递归的方式(一个函数调用另一个,另一个又调用其他的一个,如同一个链条上多个节点,最开始的一个节点触发了,则之后都会依次触发),还是说全部都在主函数中作为子函数并列调用?
随着代码量越来越高,即使只是单独的一个 store 文件。当它提供的功能越来越多时,内部就可能会出现像这种被线牵引着的错误递归函数。他们一个调用了另一个。如果突然,哪天发现其中调用一个函数时,在某种场景下不需要调用另一个,这可能又要为这个函数增加一个布尔值,从而去串入不同的布尔值。控制需不需要调用另外一个函数?这就导致可读性变得很差。
那就留着重构吧
可我究竟怎么能在一开始就知道这些功能的变化呢?有时即使业务已经说出来了,但具体的这些多个函数之间。我很难在刚开始的时候就知道这些细小的区别,究竟该怎么确定。如果花是太多时间去考虑这个,又有些得不偿失。而且依然可能会考虑出行偏差。但如果不去考虑的话,当写到一半,突然发现需要解耦,又需要将内部调用其他函数的方式拆出来,在主函数中单独调用,又需要反复的去重构。
当这个时候我又想了为什么会有重构这本书的存在?而且这本书写的很好,也许在写代码中重构是一条无法避免的事情。他也许比从刚开始的时候花太多时间去考虑在这些细节上面,会更有意义。因为当代码需要重构时,这部分的功能多半也已经完成差不多了。几乎也已经确定这些功能哪些该高内聚,哪些该低耦合了。此时重构就能达到一个很好的一个状态。虽然重构需要花一部分的时间,但也许利大于弊。相比于刚开始花太多的时间去思考每一个函数究竟该怎么样去写,是否该去调用其他函数。也许重构所需要花的时间更少,效果也会更好。
写在最后
关于这个Cursor引申出来AI对我的冲击,算是告一段落了。告一段落并不是说我觉得自己不会被淘汰掉、或者说我已经想好了其他的出路,而是说我释怀了,AI替代了前端也好,没替代也好,我都决定要继续学习,谁让我爱呢。
偶然想到了《堂吉诃德》,他威风凛凛、他勇往直前、他义无反顾、他披荆斩棘。
有人笑他是疯子,我却觉得他是个英雄。
来源:juejin.cn/post/7481992008673755163
产品:我要的是“五彩斑斓的黑”
故事的小黄花:
「“这个VIP按钮不够尊贵,我要那种黑中透着高级感,最好带点若隐若现的紫金色!”产品经理指着设计稿,眼神中闪烁着“五彩斑斓的期待”。 🖤 」
我盯着纯黑的按钮陷入沉思——这需求听起来像在为难我胖虎,但转念一想🤔,自己的产品经理,肯定得自己来宠着啦
「几小时后,当按钮在黑暗中浮现暗紫流光时,产品经理惊呼:“对对对!这就是我想要的低调奢华!”」
一、技术解析:如何让黑色“暗藏玄机”?
1. 核心代码一览
<!-- 产品经理说这里要五彩斑斓的黑 🖤 -->
<button class="btn-magic">黑紫VIP</button>
.btn-magic {
background:
linear-gradient(45deg,
#000 25%,
rgba(90, 0, 127, 0.3) 40%, /* 暗紫 */
rgba(0, 10, 80, 0.3) 60%, /* 墨蓝 */
#000 75%
);
background-size: 500% 500%;
animation: shimmer 8s infinite linear;
color: white;
}
@keyframes shimmer {
0% { background-position: 0% 50%; }
50% { background-position: 100% 50%; }
100% { background-position: 0% 50%; }
}
2. 代码逐层拆解
代码部分 | 作用说明 | 视觉隐喻 |
---|---|---|
linear-gradient(45deg) | 45度对角线渐变,比水平/垂直更动态 | 让色彩“流动”起来 |
rgba(90, 0, 127, 0.3) | 透明度0.3的暗紫色,叠加黑色不突兀 | 黑中透紫,神秘感+1 |
background-size:500% | 放大背景尺寸,制造移动空间 | 为动画预留“跑道” |
shimmer动画 | 背景位置循环位移,形成无限流动效果 | 仿佛黑夜中的极光 |
PS:动图效果有些掉帧
二、效果升级:让按钮更“灵动”的秘籍
1. 悬浮微交互
.btn-magic {
transition: transform 0.3s, box-shadow 0.3s;
}
.btn-magic:hover {
transform: translateY(-2px);
box-shadow: 0 4px 20px rgba(90, 0, 127, 0.5); /* 紫色投影,具体效果微调 */
}
效果:悬浮时按钮轻微上浮+投影扩散,可配合swiper使用点击突出效果 🧚♂️
2. 文字流光
.btn-magic {
position: relative;
overflow: hidden;
}
.btn-magic::after {
content: "VIP";
position: absolute;
background: linear-gradient(90deg, transparent, #fff, transparent);
-webkit-background-clip: text;
background-clip: text;
color: transparent;
animation: textShine 3s infinite;
}
@keyframes textShine {
0% { opacity: 0; left: -50%; }
50% { opacity: 1; }
100% { opacity: 0; left: 150%; }
}
效果:文字表面划过一道白光,尊贵感拉满! ✨
3. 性能优化
/* 开启GPU加速 */
.btn-magic {
transform: translateZ(0);
backface-visibility: hidden;
}
/* 减少动画负荷 */
@media (prefers-reduced-motion: reduce) {
.btn-magic { animation: none; }
}
原理:避免重绘,尊重用户设备偏好。
三、设计思维:如何把“离谱需求”变成亮点?
1. 需求翻译
产品经理原话 | 前端工程师理解 | 技术实现方案 |
---|---|---|
“五彩斑斓的黑” | 动态深色渐变+微交互反馈 | CSS渐变+动画 |
“要高级感” | 低饱和度辅色+精致细节 | 暗紫/墨蓝+悬浮投影 |
“用户一眼能看到VIP” | 文字强调设计 | 流光文字+居中放大 |
2. 参数可配置化(方便产品经理AB测试)
/* 定义CSS变量 */
:root {
--main-color: #000;
--accent-purple: rgba(90, 0, 127, 0.3);
--accent-blue: rgba(0, 10, 80, 0.3);
}
.btn-magic {
background: linear-gradient(45deg,
var(--main-color) 25%,
var(--accent-purple) 40%,
var(--accent-blue) 60%,
var(--main-color) 75%
);
}
玩法:通过切换变量值,快速生成“暗金奢华版”“深蓝科技版”等风格。
四、效果对比:从“煤炭”到“黑钻石”
指标 | 优化前(纯黑卡片) | 优化后(流光卡片) |
---|---|---|
产品反馈 | “按钮太普通” | “看起来就很贵” |
Lighthouse评分 | 性能99,视觉效果70 | 性能98,视觉效果95 ↑ |
五、灵魂总结:
「当产品经理提出“五彩斑斓的黑”时(我透他猴子****),他真正想要的是用户的“情绪价值”。
作为前端,我们要做的不是争论RGB能否合成黑色(我日他****),而是用技术将想象力转化为体验,
毕竟,最好的黑不是#000000,而是让用户忍不住想点击的“故事感”。」
下次再见!🌈
来源:juejin.cn/post/7500874757706350619
同学聚会,是我不配?
前言
初八就回城搬砖了,有位老哥跟我吐槽了他过年期间参与同学会的事,整理如下,看读者们是否也有相似的境遇。
缘起
高中毕业至今已有十五年了,虽然有班级群但鲜有人发言,一有人冒泡就会立马潜水围观。年前有位同学发了条消息:高中毕业15年了,趁过年时间,咱们大伙聚一聚?
我还是一如既往地只围观不发言,组织的同学看大家都三缄其口,随后发了一个红包并刷了几个表情。果然还是万恶的金钱有新引力,领了红包的同学也刷了不少谢谢老板的表情,于是乎大家都逐渐放开了,最终发起了接龙。
看到已接龙的几位同学在高中时还是和自己打过一些交道,再加上时间选的是大年初五,我刚好有空闲的时间,总归还是想怀旧,于是也接了龙。
牢笼
我们相约在县城的烧烤一条街某店会面,那离我们高中母校不远,以前偶尔经过但苦于囊中羞涩没有大快朵颐过。
到了烧烤店时发现人声鼎沸,猜拳、大笑声此起彼伏,我循着服务员的指示进入了包间。放眼望去已有四、五位同学在座位上,奇怪的是此时包间却是很安静,大家都在低头把玩着手机。
当我推门的那一刻,同学们都抬头放眼望来,迅速进行了一下眼神交流,微笑地打了招呼就落座。与左右座的同学寒暄了几句,进行一些不痛不痒的你问我答,而后就沉默,气氛落针可闻,那时我是多希望有服务员进来问:帅哥,要点单了吗?
还好最后一位同学也急匆匆赶到了,后续交流基本上明白了在场同学的工作性质。
张同学:组织者,在A小镇上开了超市、圆通、中通提货点,座驾卡迪拉克
李同学:一线城市小创业者,公司不到10人,座驾特斯拉
吴同学:县城第一中学老师、班主任,座驾大众
毛同学:县委办某科室职员、公务员,座驾比亚迪
王同学:某小镇纪委书记,座驾别克
潘同学:县住房和城乡建设局职员,事业编,座驾哈佛
我:二线城市码农一枚,座驾雅迪
一开始大家都在忆往昔,诉说过去的一些快乐的事、糗事、甚至秘辛,感觉自己的青葱时光就在眼前重现。
酒过三巡,气氛逐渐热烈,称呼也开始越拔越高,某书记、某局、某老板,主任、某老总的商业互吹。
期间大家的话题逐渐往县城的实事、新闻、八卦上靠,某某人被双了,某某同事动用了某层的关系调到了市里,某漂亮的女强人离婚了。
不巧的是张同学还需要拜会另一位老板,提前离席,李同学公司有事需要处理,离开一会。
只剩我和其他四位体制内的同学,他们在聊体制内的事,我不熟悉插不进话题,我聊公司的话题估计他们不懂、也不感兴趣。
更绝的是,毛同学接到了一个电话,而后提着酒杯拉着其他同学一起去隔壁的包间敬酒去了,只剩我一个人在包间里。
过了几分钟他们都提着空酒杯回来了,悄悄询问了吴同学才知道隔壁是县委办公室主任。
回来后,他们继续畅聊着县城的大小事。
烧烤结束之后,有同学提议去唱K,虽然我晚上没安排,但想到已经没多少可聊的就婉拒了。
释怀
沿着县城的母亲河散步,看着岸边新年的装饰,我陷入了沉思。
十多年前大家在同一间教室求学,甚至同一宿舍生活,十多年后大家的选择的生活方式千差万别,各自的境遇也大不相同。
再次相遇,共同的话题也只是学生时代,可是学生时代的事是陈旧的、不变的,而当下的事才是新鲜的、变化的。因此聚会里更多的是聊现在的事,如果不在一个圈子里,是聊不到一块的。
其实小城里,公务员是一个很好的选择,一是稳定,二是有面子(可能本身没多大权利,但是可以交易,可以传递)。小城里今天发生的事,明天就可能人尽皆知了,没有秘密可言。
有志于公务员岗位的朋友提早做准备,别等过了年纪就和体制内绝缘了。
其他人始终是过客,关注自己,取悦自己。
来源:juejin.cn/post/7468614661326159881
30+程序员别只闷头写代码,信息力才是未来的核心竞争力
引言
如果你也是程序员,或许你会认为「技术思维」是一个颇为正面的词汇,比如思维缜密,逻辑清晰,不但能写出优雅、高效的代码,嗨能够把复杂的功能落地。
但在一些非技术人员眼中,技术思维却有一定的“贬义”,它代表了眼光过于聚焦于技术,考虑不全面,不理解用户需求。
技术思维对一个优秀的程序员不可或缺,但如果只注重自己“技术思维”的训练,职场的晋升道路可能不会那么一帆风顺,乃至于对理解这个世界,都会产生一些阻碍。
真正限制我们的,从来不是技术,而是视野。
今天谈谈「信息思维」。
信息思维
一个常见的误解是,技术Leader应该是技术最强的才行,你得能解决团队开发中遇见的问题,还能设计出支持高并发大数据的架构。
如果你有心观察许多技术团队的Leader,你会发现他们也许并不是团队中技术最好的那一个,但一定是团队内掌握信息最全面的那一个。
- 你有一个技术难题不知道如何设计技术方案,他可以告诉你业内主流的方案是什么,应该去调研那些框架或者中间件。
- 你有一个业务问题需要咨询,他可以清晰的告诉你整个业务流程。
- 你发现有一个调用其他产品的接口报错,他会告诉你找哪个团队哪个人来配合。
一名优秀的技术Leader,所负责工作的不再仅仅限于技术层面。他需要和不同专业的、不同部门、不同背景的人建立联系,比如负责上传下达的任务,负责不同部门的开发协调,他知道每个人都在干什么,你有个什么事儿,他知道应该去找谁。
或许你会说,我天生内向,不善于和别人打交道,所以你说的这些我都不擅长。你认为我只要关心技术就够了,但不在这里就在那里,了解这些信息会对你有帮助。
有研究表明,任何人只需要经过一定的培训或者引导,积极参与公司内部的事情,了解各个部门都在做什么,不同部门的人负责那些事情,那么他的晋升频率和绩效评分就会提高。
但之所以许多程序员没有这样的思维,是因为我们大脑有两个偏见。
大脑的两个偏见
第一个偏见是,我们会天然的高估「我们」的价值,你更在意自己的小圈子、你的同伴们的观点。
大多数程序员在开发的时候,关注的是技术方案怎么定,代码如何写的更优雅,而不是这个功能好不好用。你让程序员优化产品,他们大都只会在工程视角下优化产品,很少接触用户需求。
比如我见过的一个同事,在处理一些咨询类的问题时,经常抱怨客户和一些操作人员:为什么“这么简单的”东西都不会用,或者“这么清晰”的提示都看不明白?
或许从程序员角度看,很多问题是非常低级的问题,可是从客户或者使用人员的视角来说,功能就是不好用,提示就是不够清晰。
你可能也遇见过一种场景:家里的长辈让你帮忙设置微信或者某个APP的功能, 你可能下意识的就会说:“这个功能不就在这里吗,你怎么不会?”
可问题就在于,你或者身边朋友都是手机的高频用户。但家人不是,对你来说直觉的操作,对别人来说就是迷宫。
第二个偏见,是我们总喜欢「往上看」,我们更关注比自己社会经济地位更高的人。
我们更在意社会地位高的人的意见,即使他们并不具备你面临的一线问题或场景;我们倾向于忽略那些地位低的人的意见,哪怕他们掌握关键信息。
比如一次技术选型,你想用一套能够快速落地、运维简单的技术方案,而公司架构师推荐了一套更成熟完备的技术方案,这个方案适用在大业务量的场景,可你们段时间内业务量根本到不了这么高。
最后团队内部多次讨论,你的方案被否决了,大家都认为架构师的方案更优。结果团队成员吭哧吭哧干了半年,最后发现开发周期明显变长,运维成本翻倍,组里内部怨声载道,纷纷后悔当时没选你推荐的方案。
再举个例子,许多年轻人在投资的时候,喜欢关注财经博主分析的“热门领域”和“热门板块”,却不愿意花时间问问身边人的看法和意见。
GDP增速、产业升级、未来规划这些固然重要,但是你的日常收入、家庭储蓄、日常花销占比有多少,你家人一定比各种专家更了解你。
过去和程序员朋友们聊天,大家都有一种同样地感觉,就是做技术做久了,技术的确是在不断提升,但总感觉自己就是公司的螺丝钉,想要跳出这个平台,但发现如果离开这个平台,自己可能什么都不是。
技术思维给程序员带来的影响还在逐渐增大, 当引以为傲的技能逐渐被AI替代,我们需要训练自己的信息思维。
你可以想见克服这两个偏见并不容易,而这也是我们的机会。
提供路径
我在刚工作的前几年,特别羡慕那些看起来天生就适合职场的人,工作中不但经常拿到成绩,还能快速晋升。我试图总结他们的经验,是他们认真负责,还是说善于沟通,甚至是擅长和领导搞好关系?
后来我发现,他们有一个关键特质是——好奇心。
比如你遇见程序框架的一个问题,有些人google一下,对着教程修改一下配置,调好了就不管了。有的人偏偏一步步debug源码,直到确定问题的根本原因在哪里。
当开发了一个功能和系统,有的人代码提交之后就不管了。而你就想知道需求是谁提出来的,他在现实中遇见了什么问题,我们的功能昨晚最后解决了吗?
94岁的巴菲特,为什么还能够保持思维的敏捷。凭什么?前一阵子在伯克希尔哈撒韦的股东大会上,他在回答一个13岁孩子提问时,巴菲特说出了自己的答案:好奇心。
他们真诚的关心别人都在想什么,在做什么,愿意接纳不同的视角。他们做的这些事情不是为了获得什么,只是单纯的想知道而已。
当然现在信息这么多,光有好奇还不够,还得思考的更深入一点,提问的更多一点。
如果你想克服大脑的这两个偏见,有以下几个经验供你参考——
首先理解信息是跟人连接在一起的。很多知识或者道理,不只是纸面上干巴巴的文字,而都是由现实中的人真实感受和体验。
由于我们的成长环境不同,因此每个人的视角和思维方式都不一样,有些道理你需要放在他那个具体的情境之中才能体会到那句话是什么意思。
1月份DeepSeek R1横空出世,我看网上说全世界的大模型团队都在研究R1的论文。我就去问了问一个做大模型的朋友有没有关注这块,当时临近过年,大家其实都已经在期待放假了。我朋友回答说:“反正领导已经开始研究了,要不然我也不会这么忙,给我平添烦恼。”
这种真实朋友给我的的反馈,让我立刻感受到DeepSeek R1带来的震撼有多么大。
培养对「一手信息」的敏感度。
一手信息就是那些还未上网,来自一线的信息。你或许认为现在网络这么发达,想了解任何事情都可以从网上找到答案,并且AI能力突飞猛进,把信息交给AI,那么AI就可以帮我们做任何事。
但实际上这个世界上永远存在那些仅存在于一线,还未上网的「隐性知识」。书本会告诉你“是什么”和“为什么”,而实际接触一线,我们才知道很多事情是如何发生的。
刘润老师在最近的文章里分享了他进二十多年,坚持在做的一件事情就是「参访」。每年平均的出差时间有上百天,只要有机会就会去现场看一看,刘润老师在文章中描述的很清晰,在办公室看报告、打电话,和你去生产线走一走,和一线员工聊几句的差别是非常大的。
最有意思的一个描述是一家企业员工的眼神、办公室的氛围,甚至厕所干不干净,这些细节都会藏着关于公司的文化、管理的密码。
训练自己跨界翻译的能力。
跨界翻译你能不能把一个领域的信息,用另一个领域的语言表达出来,让别人能听懂。
也许在程序员和产品经理为了一个问题争论的面红耳赤的时候,你是否能有一种更好的方式,让产品经理能听懂工程师的技术方案是什么?是否能让工程师明白,真实的用户需求是什么?
比如有一次销售很着急的来找研发说:“我们有一个大客户说下周前必须研发出这个功能,不然就不验收!”
研发同事一听,满脸不屑地说:“你知不知道这个功能要重构整个接口?开发的工作量非常大,下周根本不可能。客户表述清楚了吗,还是你自己拍脑袋定的?”
销售和研发直接氛围一度陷入紧张,但是跨界翻译者可能会这么说:
销售最在意的就是验收,因为这决定了他是否能拿到这家客户的收入。研发在意的是技术稳定性,贸然增加新功能也是“挖坑”。
我们不妨看看客户为什么需要这个功能,我们系统有没有满足部分功能的方案先应急,而不是按照客户要求全部重新开发?
这需要大量的学习、消化和吸收,你只有见过和积累的足够多,才能够做到触类旁通,举一反三。
说在最后
真正限制我们的,从来不是技术,而是视野。信息思维并不是让你放弃技术,而是让你站得更高,看得更远,理解得更深。
你看到的世界有多宽,你未来的上限就有多高。
不知道这篇文章能否对你有所启发,又或者你能想到身边的哪个朋友可能会从中受益呢?
这是东东拿铁的第78篇原创文章,欢迎关注。
来源:juejin.cn/post/7503712510592385051
30岁了才有了自己的博客
写作是很痛苦
说来惭愧,干程序员这么多年,30 岁了,终于想起来要自己搭建一个博客了!其实一直羡慕别人拥有炫酷的博客,可是自己却一直没去做。作为前端程序员,通常来说,搭建好看的博客还是非常容易的,不过因为自己没啥分享欲望,加上上学时对写作的厌烦(上学时,语文不及格的主要原因就是作文)。
说来惭愧,干程序员这么多年,30 岁了,终于想起来要自己搭建一个博客了!其实一直羡慕别人拥有炫酷的博客,可是自己却一直没去做。作为前端程序员,通常来说,搭建好看的博客还是非常容易的,不过因为自己没啥分享欲望,加上上学时对写作的厌烦(上学时,语文不及格的主要原因就是作文)。
为什么现在想起来搭建博客呢?
我发现,我虽然不喜欢写作,却喜欢记录,学习笔记、工作总结、快捷命令汇总等等。学习新技术时,我喜欢把教程或者书本上的语言总结成自己能看懂的语言记录起来,然后看看自己的记事本,这么多年来也有 600 多篇了。

因此,我觉得我不是不喜欢写东西,而是我内心对写作的的恐惧,也担心自己水平有限,文章不够深入,误人子弟。也是为什么我一直不敢把自己写的东西发布到网上。
[质问] 那么,为啥你现在敢发了,你水平更高了?还是你写作水平提升了??
[回答] 其实都不是!回想有一天,发现我多年前发布的第一篇文章,竟然现在都还有人收藏点赞,全文不过 500字,当时 md 语法都不知道,更别谈什么排版了。
这让我意识到一个问题:即便随手写的一篇文章,只要有完整的解决方案,都有可能帮助到别人
。
我掘金的第一篇文章。

当然,除了帮助别人,分享文章还有有什么好处呢?会获得点赞和评论;甚至会遇到一些志同道合的人加好友,一起聊技术细节。当然,对于淡泊名利的你来说,这些有什么用呢?这些东西都是正反馈的来源呀!!!
我发现,我虽然不喜欢写作,却喜欢记录,学习笔记、工作总结、快捷命令汇总等等。学习新技术时,我喜欢把教程或者书本上的语言总结成自己能看懂的语言记录起来,然后看看自己的记事本,这么多年来也有 600 多篇了。
因此,我觉得我不是不喜欢写东西,而是我内心对写作的的恐惧,也担心自己水平有限,文章不够深入,误人子弟。也是为什么我一直不敢把自己写的东西发布到网上。
[质问] 那么,为啥你现在敢发了,你水平更高了?还是你写作水平提升了??
[回答] 其实都不是!回想有一天,发现我多年前发布的第一篇文章,竟然现在都还有人收藏点赞,全文不过 500字,当时 md 语法都不知道,更别谈什么排版了。
这让我意识到一个问题:即便随手写的一篇文章,只要有完整的解决方案,都有可能帮助到别人
。
我掘金的第一篇文章。
当然,除了帮助别人,分享文章还有有什么好处呢?会获得点赞和评论;甚至会遇到一些志同道合的人加好友,一起聊技术细节。当然,对于淡泊名利的你来说,这些有什么用呢?这些东西都是正反馈的来源呀!!!
正反馈
说到正反馈,这真的是一个值得深入的话题。工作中,大多数时候的任务是重复和无聊的,你的正反馈来源多数是你的上级或者同事,可是这样的正反馈是很少的。生活中也是一样。也就导致对工作失去兴趣,对技术失去兴趣,因为没有正反馈,也就没有动力继续,不想做任何事情
。所以我们需要主动去寻找一些能产生正反馈的事情,写文章、运动、学习,分享。都可以。(有段时间,我每天上班第一件事就是看看有没有新的点赞和评论。)
其实这些道理一早就知道,很多文章、前辈都有说过,可是呢,人呀,就是要自己亲身体会后才会明白!
说到正反馈,这真的是一个值得深入的话题。工作中,大多数时候的任务是重复和无聊的,你的正反馈来源多数是你的上级或者同事,可是这样的正反馈是很少的。生活中也是一样。也就导致对工作失去兴趣,对技术失去兴趣,因为没有正反馈,也就没有动力继续,不想做任何事情
。所以我们需要主动去寻找一些能产生正反馈的事情,写文章、运动、学习,分享。都可以。(有段时间,我每天上班第一件事就是看看有没有新的点赞和评论。)
其实这些道理一早就知道,很多文章、前辈都有说过,可是呢,人呀,就是要自己亲身体会后才会明白!
开始写作
与其说是开始写作,不如说是开始记录,对我来说更加合适。我并不擅长写出段落清晰、用词优美的文章。所以我决定把写作当做生活中的记录,把本地的总结记录分享到线上论坛。
既然要分享到网上,也促使我要求自己发布的文章不仅是自己能看懂,尽量也能让所有人看懂。这很重要!!!
让所有人能看懂很重要,因为即便是自己写的文章,隔一段时间你回头看,会发现啥也看不懂了,根本回想不起来当时是怎么实现的。这就是因为当时写得不够清晰。
于是,我逐渐将本地的记录文章颁发到了论坛,并获得了一些收获。

当然,这点数据根本不够看。对我来说是一个开始,打破固有思维的开始!渐渐地,我从一年 5 篇,到一年 10 篇了,现在一个月一篇。发布的文章逐渐变多了... 这可并不是我强迫自己输出呀(不可能,我意志力不强),这本来就是我本地记录的频率。
这也是我的做事风格,把一些看似很难的事情变得平常化。例如记单词,地铁上就非常适合记单词,手机没网络,记完单词刚好就到公司了。
写本篇的时候,我发现又有一段时间没更新了,不是我没写,是写了很多,都还没发布,因为总觉得少点什么。
与其说是开始写作,不如说是开始记录,对我来说更加合适。我并不擅长写出段落清晰、用词优美的文章。所以我决定把写作当做生活中的记录,把本地的总结记录分享到线上论坛。
既然要分享到网上,也促使我要求自己发布的文章不仅是自己能看懂,尽量也能让所有人看懂。这很重要!!!
让所有人能看懂很重要,因为即便是自己写的文章,隔一段时间你回头看,会发现啥也看不懂了,根本回想不起来当时是怎么实现的。这就是因为当时写得不够清晰。
于是,我逐渐将本地的记录文章颁发到了论坛,并获得了一些收获。
当然,这点数据根本不够看。对我来说是一个开始,打破固有思维的开始!渐渐地,我从一年 5 篇,到一年 10 篇了,现在一个月一篇。发布的文章逐渐变多了... 这可并不是我强迫自己输出呀(不可能,我意志力不强),这本来就是我本地记录的频率。
这也是我的做事风格,把一些看似很难的事情变得平常化。例如记单词,地铁上就非常适合记单词,手机没网络,记完单词刚好就到公司了。
写本篇的时候,我发现又有一段时间没更新了,不是我没写,是写了很多,都还没发布,因为总觉得少点什么。
搭建博客
说了这么多,总算可以回归正题了~
我参考了 v 友们的建议想搭建自己的博客,求大佬们推荐方案 - V2EX,总结出以下常见的博客框架。
- wordpress
- hugo
- hexo
- Astro
- typecho
不过,看了一圈,都不太适合我,要么是配置麻烦、要么主题不好看。相反,并不是这些博客不好,里面的插件、主题多得很,只是没有找到我想要的那种风格(喜欢折腾0.0),下面我会详细解释。
我喜欢的风格
之前我一直很长一段时间,我很喜欢那种酷炫的博客,例如,动态背景图(雪花、3D 地图),或者页面下方还有个可以通过鼠标挑逗的二次元卡通人。再就是搞一些炫酷跳动文字?大家应该都懂,哈哈。
而现在呢,我想要的博客就是:
”简约“
看了太多混杂广告、推广、链接的博客,我更想让读者专注在文章本身上。所以除了文章相关的内容,其他东西一律去除。
”简单“
博客要关注的是内容,所以发布流程越简单越好,我只需要关注写内容就好了。
结合这两点,并简单调研了下相关实现,还是决定自己搭建一个,比较往后较长一段时间都要用它,所以还是自己用着舒服为主。
说了这么多,总算可以回归正题了~
我参考了 v 友们的建议想搭建自己的博客,求大佬们推荐方案 - V2EX,总结出以下常见的博客框架。
- wordpress
- hugo
- hexo
- Astro
- typecho
不过,看了一圈,都不太适合我,要么是配置麻烦、要么主题不好看。相反,并不是这些博客不好,里面的插件、主题多得很,只是没有找到我想要的那种风格(喜欢折腾0.0),下面我会详细解释。
我喜欢的风格
之前我一直很长一段时间,我很喜欢那种酷炫的博客,例如,动态背景图(雪花、3D 地图),或者页面下方还有个可以通过鼠标挑逗的二次元卡通人。再就是搞一些炫酷跳动文字?大家应该都懂,哈哈。
而现在呢,我想要的博客就是:
”简约“
看了太多混杂广告、推广、链接的博客,我更想让读者专注在文章本身上。所以除了文章相关的内容,其他东西一律去除。
”简单“
博客要关注的是内容,所以发布流程越简单越好,我只需要关注写内容就好了。
结合这两点,并简单调研了下相关实现,还是决定自己搭建一个,比较往后较长一段时间都要用它,所以还是自己用着舒服为主。
页面展示
NextJs 搭建博客
其实博客的本质,无非就是一个 markdown 的渲染器,对于前端来说,实现起来不算难事。所以我决定使用 NextJs 自己搭建一个,选用 Nextjs 的主要是因为它天然对 SSG (静态生成)的友好支持。
其实博客的本质,无非就是一个 markdown 的渲染器,对于前端来说,实现起来不算难事。所以我决定使用 NextJs 自己搭建一个,选用 Nextjs 的主要是因为它天然对 SSG (静态生成)的友好支持。
1.配置 nextConfig
通过如下配置,我们就可以导出一个静态web项目。
const nextConfig: NextConfig = {
/* config options here */
trailingSlash: true,
output: 'export',
};
通过如下配置,我们就可以导出一个静态web项目。
const nextConfig: NextConfig = {
/* config options here */
trailingSlash: true,
output: 'export',
};
2. 文章格式范式
我们将文章放在 posts 目录下,文章格式如下:
---
title: "时隔三年,一个可视化可交互的前端依赖分析工具发布了"
date: "2025-02-01"
categories: "Life"
summary: "我一直认为它只是一个不完美的半成品,所以我只是悄悄的上架到了个人的 github 仓库,并没打算公之于众。不过就在今天,我意外的发现仓库多了一个陌生人的 Issue,真的很震惊,我没想到真的有人安装文档安装使用了。这真的让我感到意外,也许真的有人觉得有用,那么我就要做好它,也有责任做好它!"
---
### 终于有勇气发布了~
我一直认为它只是一个不完美的半成品,所以我只是悄悄的上架到了个人的 github 仓库,并没打算公之于众。不过就在今天,我意外的发现仓库多了一个陌生人的 Issue,真的很震惊,我没想到真的有人安装文档安装使用了。这真的让我感到意外,也许真的有人觉得有用,那么我就要做好它,也有责任做好它!
我们将文章放在 posts 目录下,文章格式如下:
---
title: "时隔三年,一个可视化可交互的前端依赖分析工具发布了"
date: "2025-02-01"
categories: "Life"
summary: "我一直认为它只是一个不完美的半成品,所以我只是悄悄的上架到了个人的 github 仓库,并没打算公之于众。不过就在今天,我意外的发现仓库多了一个陌生人的 Issue,真的很震惊,我没想到真的有人安装文档安装使用了。这真的让我感到意外,也许真的有人觉得有用,那么我就要做好它,也有责任做好它!"
---
### 终于有勇气发布了~
我一直认为它只是一个不完美的半成品,所以我只是悄悄的上架到了个人的 github 仓库,并没打算公之于众。不过就在今天,我意外的发现仓库多了一个陌生人的 Issue,真的很震惊,我没想到真的有人安装文档安装使用了。这真的让我感到意外,也许真的有人觉得有用,那么我就要做好它,也有责任做好它!
3. 解析文章内容-核心逻辑
import { promises as fs } from "fs";
import path from "path";
import matter from "gray-matter";
import { remark } from "remark";
import html from "remark-html";
// 获取文章内容
export async function getPost(id: string) {
const markdownWithMeta = await fs.readFile(
path.join("posts", id + ".md"),
"utf-8"
);
// frontmatter 是文章的元数据信息, content 是文章内容
const { data: frontmatter, content } = matter(markdownWithMeta);
const processedContent = await remark().use(html).process(content);
const contentHtml = processedContent.toString();
frontmatter.categories = Array.isArray(frontmatter.categories) ? frontmatter.categories : [frontmatter.categories || "Default"]
return {
id,
contentHtml,
frontmatter,
}
}
import { promises as fs } from "fs";
import path from "path";
import matter from "gray-matter";
import { remark } from "remark";
import html from "remark-html";
// 获取文章内容
export async function getPost(id: string) {
const markdownWithMeta = await fs.readFile(
path.join("posts", id + ".md"),
"utf-8"
);
// frontmatter 是文章的元数据信息, content 是文章内容
const { data: frontmatter, content } = matter(markdownWithMeta);
const processedContent = await remark().use(html).process(content);
const contentHtml = processedContent.toString();
frontmatter.categories = Array.isArray(frontmatter.categories) ? frontmatter.categories : [frontmatter.categories || "Default"]
return {
id,
contentHtml,
frontmatter,
}
}
4. 展示文章页面-核心逻辑
const Post = async ({ params }: any) => {
const { frontmatter, contentHtml } = await getPost(params.id);
return <div>
<h1 className="text-2xl mb-4 font-bold">{frontmatter.title}h1>
{/* 元数据 */}
<p className="flex flex-wrap">
{metaList.map((item) => (
<span key={item.label} className="text-gray-600 mr-4">
<label>{item.label}: label> {item.value}
span>
))}
p>
{/* 内容 */}
<div className="mt-4" dangerouslySetInnerHTML={{ __html: contentHtml }} />
<div className="mt-10">
<Comments />
div>
div>
};
展示就很简单了 dangerouslySetInnerHTML 将内容渲染在页面上就好了
const Post = async ({ params }: any) => {
const { frontmatter, contentHtml } = await getPost(params.id);
return <div>
<h1 className="text-2xl mb-4 font-bold">{frontmatter.title}h1>
{/* 元数据 */}
<p className="flex flex-wrap">
{metaList.map((item) => (
<span key={item.label} className="text-gray-600 mr-4">
<label>{item.label}: label> {item.value}
span>
))}
p>
{/* 内容 */}
<div className="mt-4" dangerouslySetInnerHTML={{ __html: contentHtml }} />
<div className="mt-10">
<Comments />
div>
div>
};
展示就很简单了 dangerouslySetInnerHTML 将内容渲染在页面上就好了
5. 添加评论功能
因为是静态页面,所以就不存在数据库和server服务,所以最佳的方式是直接使用 giscus
利用 GitHub Discussions 实现的评论系统,让访客借助 GitHub 在你的网站上留下评论和反应吧!本项目深受 utterances 的启发。
首先我们到 giscus 上配置好我们的 github 项目,并在项目中开启 GitHub Discussions 功能。
所以本质上,所有评论最终都存在该仓库的 Discussions 里,每个文章对应一个 discussion。

对应关系可以自行设置,默认是文章的 url 路径对应作为 discussion 的标题,然后该文章的评论都是在这个 discussion 下。
然后新建一个 Comments 组件(配置需要根据自己的仓库自行修改)
"use client";
import Giscus from "@giscus/react";
export default function Comments() {
return (
<Giscus
repo="xx/xxx.github.io"
repoId="xxxx"
category="xxx"
categoryId="xxxx"
mapping="pathname"
strict="0"
reactionsEnabled="1"
emitMetadata="0"
inputPosition="top"
theme="preferred_color_scheme"
lang="zh-CN"
/>
);
}
注意:
- 本地 localhost 域名可能不会自动创建 discussion,发布到线上后就能解决。
- 自动创建Discussion的触发条件是:当用户首次在该页面发表评论或表情时才会创建。若未进行任何交互,Discussion不会自动生成。
因为是静态页面,所以就不存在数据库和server服务,所以最佳的方式是直接使用 giscus
利用 GitHub Discussions 实现的评论系统,让访客借助 GitHub 在你的网站上留下评论和反应吧!本项目深受 utterances 的启发。
首先我们到 giscus 上配置好我们的 github 项目,并在项目中开启 GitHub Discussions 功能。
所以本质上,所有评论最终都存在该仓库的 Discussions 里,每个文章对应一个 discussion。
对应关系可以自行设置,默认是文章的 url 路径对应作为 discussion 的标题,然后该文章的评论都是在这个 discussion 下。
然后新建一个 Comments 组件(配置需要根据自己的仓库自行修改)
"use client";
import Giscus from "@giscus/react";
export default function Comments() {
return (
<Giscus
repo="xx/xxx.github.io"
repoId="xxxx"
category="xxx"
categoryId="xxxx"
mapping="pathname"
strict="0"
reactionsEnabled="1"
emitMetadata="0"
inputPosition="top"
theme="preferred_color_scheme"
lang="zh-CN"
/>
);
}
注意:
- 本地 localhost 域名可能不会自动创建 discussion,发布到线上后就能解决。
- 自动创建Discussion的触发条件是:当用户首次在该页面发表评论或表情时才会创建。若未进行任何交互,Discussion不会自动生成。
Github Page 部署
既然输出是静态页面,可以托管的地方就很多了,前面我也提到了,我并不想做除了写内容以外的任何事,Github Page 就是很不错的选择,不仅能托管文章代码,还能配合流水线自动构建,一举两得。
- 创建仓库
新建一个 [用户名].github.io
的 Github 仓库
- 新建一个 nextjs 部署构建流水线
.github/workflows/nextjs.yml
# Sample workflow for building and deploying a Next.js site to GitHub Pages
name: Deploy Next.js site to Pages
on:
push:
branches: ["main"]
workflow_dispatch:
permissions:
contents: read
pages: write
id-token: write
concurrency:
group: "pages"
cancel-in-progress: false
jobs:
build:
runs-on: ubuntu-latest
steps:
- name: Checkout
uses: actions/checkout@v4
- name: Setup Node
uses: actions/setup-node@v4
with:
node-version: "20"
cache: 'npm'
- name: Install pnpm
run: npm install -g pnpm
- name: Detect package manager
id: detect-package-manager
run: |
if [ -f "${{ github.workspace }}/yarn.lock" ]; then
echo "manager=yarn" >> $GITHUB_OUTPUT
echo "command=install" >> $GITHUB_OUTPUT
echo "runner=yarn" >> $GITHUB_OUTPUT
exit 0
elif [ -f "${{ github.workspace }}/pnpm-lock.yaml" ]; then
echo "manager=pnpm" >> $GITHUB_OUTPUT
echo "command=install" >> $GITHUB_OUTPUT
echo "runner=pnpm" >> $GITHUB_OUTPUT
exit 0
elif [ -f "${{ github.workspace }}/package.json" ]; then
echo "manager=npm" >> $GITHUB_OUTPUT
echo "command=install" >> $GITHUB_OUTPUT
echo "runner=npm" >> $GITHUB_OUTPUT
exit 0
else
echo "Unable to determine package manager"
exit 1
fi
- name: Install dependencies
run: ${{ steps.detect-package-manager.outputs.manager }} ${{ steps.detect-package-manager.outputs.command }}
- name: Build with Next.js
run: ${{ steps.detect-package-manager.outputs.runner }} next build
- name: Upload artifact
uses: actions/upload-pages-artifact@v3
with:
path: ./out
deploy:
environment:
name: github-pages
url: ${{ steps.deployment.outputs.page_url }}
runs-on: ubuntu-latest
needs: build
steps:
- name: Deploy to GitHub Pages
id: deployment
uses: actions/deploy-pages@v4
既然输出是静态页面,可以托管的地方就很多了,前面我也提到了,我并不想做除了写内容以外的任何事,Github Page 就是很不错的选择,不仅能托管文章代码,还能配合流水线自动构建,一举两得。
- 创建仓库
新建一个
[用户名].github.io
的 Github 仓库
- 新建一个 nextjs 部署构建流水线
.github/workflows/nextjs.yml
# Sample workflow for building and deploying a Next.js site to GitHub Pages
name: Deploy Next.js site to Pages
on:
push:
branches: ["main"]
workflow_dispatch:
permissions:
contents: read
pages: write
id-token: write
concurrency:
group: "pages"
cancel-in-progress: false
jobs:
build:
runs-on: ubuntu-latest
steps:
- name: Checkout
uses: actions/checkout@v4
- name: Setup Node
uses: actions/setup-node@v4
with:
node-version: "20"
cache: 'npm'
- name: Install pnpm
run: npm install -g pnpm
- name: Detect package manager
id: detect-package-manager
run: |
if [ -f "${{ github.workspace }}/yarn.lock" ]; then
echo "manager=yarn" >> $GITHUB_OUTPUT
echo "command=install" >> $GITHUB_OUTPUT
echo "runner=yarn" >> $GITHUB_OUTPUT
exit 0
elif [ -f "${{ github.workspace }}/pnpm-lock.yaml" ]; then
echo "manager=pnpm" >> $GITHUB_OUTPUT
echo "command=install" >> $GITHUB_OUTPUT
echo "runner=pnpm" >> $GITHUB_OUTPUT
exit 0
elif [ -f "${{ github.workspace }}/package.json" ]; then
echo "manager=npm" >> $GITHUB_OUTPUT
echo "command=install" >> $GITHUB_OUTPUT
echo "runner=npm" >> $GITHUB_OUTPUT
exit 0
else
echo "Unable to determine package manager"
exit 1
fi
- name: Install dependencies
run: ${{ steps.detect-package-manager.outputs.manager }} ${{ steps.detect-package-manager.outputs.command }}
- name: Build with Next.js
run: ${{ steps.detect-package-manager.outputs.runner }} next build
- name: Upload artifact
uses: actions/upload-pages-artifact@v3
with:
path: ./out
deploy:
environment:
name: github-pages
url: ${{ steps.deployment.outputs.page_url }}
runs-on: ubuntu-latest
needs: build
steps:
- name: Deploy to GitHub Pages
id: deployment
uses: actions/deploy-pages@v4
然后当 main
分支 push
时自动触发 NextJs 项目的构建,完成 GitHub Pages 页面部署。接下来你就可以通过 [usename].github.io
访问属于你自己的博客了!
总结
最后,如果有和我一样喜欢折腾的小伙伴,可以使用使用我的项目作为模版,搭建一个属于你自己的博客。当然,如果你觉得还不错的话,别忘了留下你的 star~ GitHub - chennlang/chennlang.github.io: blog
来源:juejin.cn/post/7474923858165252105
iOS、Android、Flutter 流行框架对比(基于 OpenAI 的数据)
背景
基于 OpenAI 最新的 o1-preview
模型,整理出来的 App 分别使用 iOS、Android、Flutter 流行框架对比,方便查阅,部分数据可能不完全准确,整体的数据质量我看了一下还是挺高,有需要的自取。
内容
自动布局的框架
iOS
Prompt: 以表格的形式输出 iOS 自动布局框架,包括使用的编程语言、描述、功能、GitHub 仓库地址和 Star 数量
框架/库名称 | 编程语言 | 描述 | 功能 | GitHub 仓库地址 | Star 数量 |
---|---|---|---|---|---|
Auto Layout | Swift/Objective-C | iOS 原生的布局系统 | 动态适应不同屏幕尺寸的布局 | N/A(原生功能) | N/A |
SnapKit | Swift | 简化 Auto Layout 的 DSL | 使用链式语法创建布局约束 | SnapKit | 19k+ |
Masonry | Objective-C | 类似 SnapKit 的 Objective-C 版本 | 使用链式语法创建 Auto Layout 约束 | Masonry | 18k+ |
PureLayout | Swift/Objective-C | 提供一致的 Auto Layout 接口 | 简化约束的创建和管理 | PureLayout | 7k+ |
Cartography | Swift | 使用纯 Swift 语法构建 Auto Layout | 通过操作符重载简化约束定义 | Cartography | 7k+ |
TinyConstraints | Swift | 轻量级的 Auto Layout 语法糖 | 更简洁地创建和管理约束 | TinyConstraints | 3k+ |
Stevia | Swift | 简洁的布局框架 | 使用声明式语法定义布局 | Stevia | 3k+ |
EasyPeasy | Swift | 简化 Auto Layout 语法的库 | 使用简洁的语法定义和修改约束 | EasyPeasy | 2k+ |
Anchorage | Swift | 提供更简洁的 Auto Layout API | 利用 Swift 特性简化约束定义 | Anchorage | 1k+ |
LayoutKit | Swift | 高性能的布局框架 | 使用纯代码创建高性能的视图布局 | LayoutKit | 7k+ |
请注意,Star 数量可能会随着时间变化,以上数据截至 2023 年 10 月。如需获取最新信息,请访问相应的 GitHub 仓库。
Andorid
Porompt:以表格的形式输出 Andorid 自动布局框架,包括使用的编程语言、描述、功能、GitHub 仓库地址和 Star 数量
框架/库名称 | 编程语言 | 描述 | 功能 | GitHub 仓库地址 | Star 数量 |
---|---|---|---|---|---|
ConstraintLayout | Java/Kotlin | 官方提供的强大布局系统 | 创建复杂布局,支持动画和约束 | N/A(原生功能) | N/A |
FlexboxLayout | Java/Kotlin | 类似于 CSS Flexbox 的布局库 | 实现灵活的响应式布局 | FlexboxLayout | 6k+ |
MotionLayout | Java/Kotlin | 基于 ConstraintLayout 的动画布局系统 | 创建复杂的过渡和动画 | N/A(原生功能) | N/A |
AndroidAutoLayout | Java | 自动适配各种屏幕尺寸的布局库 | 根据屏幕尺寸自动调整布局参数 | AndroidAutoLayout | 10k+ |
Anko Layouts | Kotlin | 使用 Kotlin DSL 构建布局 | 简化布局代码,减少 XML 文件 | Anko | 15k+ |
FlowLayout | Java | 支持自动换行的布局 | 适用于标签、按钮等需要自动换行的场景 | FlowLayout | 9k+ |
PercentLayout | Java/Kotlin | 支持百分比布局的库(已弃用) | 根据父布局的百分比设置子视图尺寸 | PercentLayout | N/A |
Epoxy | Java/Kotlin | Airbnb 开源的用于构建复杂列表的库 | 声明式界面,支持复杂布局和模型 | Epoxy | 11k+ |
Gr0upie | Java/Kotlin | 简化 RecyclerView 布局和适配器的库 | 轻松创建复杂的列表布局 | Gr0upie | 12k+ |
DataBinding | Java/Kotlin | 官方的数据绑定库 | 将布局与数据源绑定,减少代码量 | N/A(原生功能) | N/A |
请注意,Star 数量可能会随着时间变化,以上数据截至 2023 年 10 月。如需获取最新信息,请访问相应的 GitHub 仓库。
Flutter
Porompt:以表格的形式输出 Flutter 自动布局框架,包括使用的编程语言、描述、功能、GitHub 仓库地址和 Star 数量
框架/库名称 | 编程语言 | 描述 | 功能 | GitHub 仓库地址 | Star 数量 |
---|---|---|---|---|---|
Flutter 内置布局系统 | Dart | Flutter 自带的布局系统,包含多种布局组件 | 提供灵活的布局,支持多种布局方式 | N/A(原生功能) | N/A |
Responsive Framework | Dart | 响应式布局框架 | 自动适配不同屏幕尺寸和分辨率 | Responsive Framework | 2k+ |
flutter_layout_grid | Dart | 类似于 CSS Grid 的布局库 | 支持基于网格的布局方式 | flutter_layout_grid | 1k+ |
flutter_staggered_grid_view | Dart | 创建不规则网格布局的库 | 支持瀑布流布局和不规则网格布局 | flutter_staggered_grid_view | 2.5k+ |
AutoSizeText | Dart | 自动调整文本大小的组件 | 根据可用空间自动调整文本大小 | AutoSizeText | 1.5k+ |
flutter_screenutil | Dart | 屏幕适配解决方案 | 支持多屏幕尺寸、像素密度的适配 | flutter_screenutil | 5k+ |
Sizer | Dart | 使响应式设计变得简单的库 | 根据屏幕尺寸调整组件和字体大小 | Sizer | 600+ |
flutter_responsive | Dart | 响应式布局助手 | 简化不同屏幕尺寸的布局适配 | flutter_responsive | 300+ |
align_positioned | Dart | 更灵活的 Positioned 小部件 | 提供百分比定位和对齐 | align_positioned | 200+ |
FlowBuilder | Dart | 用于构建响应式和可组合的布局 | 提供灵活的流式布局 | FlowBuilder | 1k+ |
请注意,Star 数量可能会随着时间变化,以上数据截至 2023 年 10 月。如需获取最新信息,请访问相应的 GitHub 仓库。
网络请求的框架
iOS
Prompt: 以表格的形式输出 iOS 网络请求框架,包括使用的编程语言、描述、功能、GitHub 仓库地址和 Star 数量
框架/库名称 | 编程语言 | 描述 | 功能 | GitHub 仓库地址 | Star 数量 |
---|---|---|---|---|---|
Alamofire | Swift | 强大的网络请求库,简化 HTTP 网络请求 | 支持链式调用、文件上传下载、认证处理 | Alamofire | 40k+ |
AFNetworking | Objective-C | 功能强大的网络请求库,支持多种网络请求 | 支持数据任务、上传、下载、认证处理 | AFNetworking | 33k+ |
SwiftyJSON | Swift | 简单的 JSON 解析库 | 轻松解析和处理网络请求中的 JSON 数据 | SwiftyJSON | 22k+ |
Kingfisher | Swift | 强大的图片下载和缓存库 | 支持异步图片下载和缓存,集成到网络请求 | Kingfisher | 22k+ |
PromiseKit | Swift | 处理异步操作的 Promise 库 | 简化异步网络请求、支持链式调用 | PromiseKit | 14k+ |
Moya | Swift | 基于 Alamofire 的网络请求抽象层 | 通过 API 定义和管理网络请求,插件支持 | Moya | 15k+ |
Reachability.swift | Swift | 用于监控网络连接状态的库 | 支持监控网络状态,处理连接状态的变化 | Reachability.swift | 12k+ |
URLSession | Swift | iOS 原生网络请求 API | 完全支持 HTTP 和 HTTPS 请求 | N/A (原生功能) | N/A |
Siesta | Swift | 高级网络请求框架,支持缓存和状态管理 | 支持响应式编程、数据缓存、重试机制 | Siesta | 3.5k+ |
Networking | Swift | 网络请求简化库,支持上传下载和缓存 | 文件上传下载、自动管理缓存 | Networking | 1.1k+ |
请注意,Star 数量可能会随着时间变化,以上数据截至 2023 年 10 月。如需获取最新信息,请访问相应的 GitHub 仓库。
Andorid
Prompt: 以表格的形式输出 Andorid 网络请求框架,包括使用的编程语言、描述、功能、GitHub 仓库地址和 Star 数量
框架/库名称 | 编程语言 | 描述 | 功能 | GitHub 仓库地址 | Star 数量 |
---|---|---|---|---|---|
Retrofit | Java/Kotlin | 类型安全的 HTTP 客户端,用于 Android 和 Java | 简化 RESTful API 的网络请求,支持异步和同步 | Retrofit | 42k+ |
OkHttp | Java/Kotlin | 高效的 HTTP 和 HTTP/2 客户端 | 支持连接池、拦截器和超时设置等高级特性 | OkHttp | 43k+ |
RxJava | Java/Kotlin | 用于异步和事件驱动编程的响应式扩展库 | 支持异步数据流处理,可与网络请求结合使用 | RxJava | 47k+ |
Ktor | Kotlin | Kotlin 的异步网络框架,支持客户端和服务器端 | 支持多种协议,异步编程,协程支持 | Ktor | 12k+ |
AsyncHttpClient | Java | 异步的 HTTP 客户端 | 支持异步网络请求、文件上传下载 | AsyncHttpClient | 10k+ |
Volley | Java | Google 提供的网络请求库 | 支持异步请求、图片加载和缓存 | 内置于 Android(无需单独的 GitHub 仓库) | N/A |
Fuel | Kotlin | 轻量级的网络请求库 | 简化 HTTP 请求,支持并发和协程 | Fuel | 4k+ |
Ion | Java | Android 上的异步网络请求和图片加载库 | 支持异步请求、图片加载、缓存 | Ion | 7k+ |
FastAndroidNetworking | Java | 基于 OkHttp 的高性能网络库 | 支持文件上传下载、JSON 解析、缓存 | FastAndroidNetworking | 5k+ |
Apollo Android | Java/Kotlin | 用于 Android 的 GraphQL 客户端 | 支持类型安全的 GraphQL 请求和响应处理 | Apollo Android | 5k+ |
请注意,Star 数量可能会随着时间变化,以上数据截至 2023 年 9 月。如需获取最新信息,请访问相应的 GitHub 仓库。
Flutter
Prompt: 以表格的形式输出 Flutter 网络请求框架,包括使用的编程语言、描述、功能、GitHub 仓库地址和 Star 数量
框架/库名称 | 编程语言 | 描述 | 功能 | GitHub 仓库地址 | Star 数量 |
---|---|---|---|---|---|
http | Dart | Flutter 和 Dart 的基本 HTTP 客户端 | 简单的网络请求支持,GET/POST 等方法 | http | 1.5k+ |
Dio | Dart | 功能强大的 HTTP 客户端库 | 支持拦截器、全局配置、FormData、请求取消 | Dio | 13k+ |
Chopper | Dart | RESTful API 客户端库,类似 Retrofit | 支持代码生成、拦截器、内置 JSON 解析 | Chopper | 1.6k+ |
Retrofit.dart | Dart | Retrofit 的 Dart 实现 | 自动生成 API 调用代码,支持 RxDart | retrofit.dart | 1.8k+ |
graphql_flutter | Dart | GraphQL 客户端库 | 支持查询、变更、订阅和缓存 | graphql_flutter | 3.5k+ |
Flutter Socket.IO | Dart | Socket.IO 的 Flutter 客户端实现 | 实时通信,支持 WebSocket | socket_io_client | 600+ |
Flutter Secure Storage | Dart | 安全的密钥/值存储库 | 用于存储令牌和敏感信息 | flutter_secure_storage | 1.7k+ |
Flutter Data | Dart | 数据管理和网络请求框架 | 支持关联、缓存、离线支持 | flutter_data | 700+ |
GetConnect | Dart | GetX 框架内置的网络请求库 | 简化网络请求,集成状态管理 | GetX | 9k+ |
FlutterFire | Dart | Firebase 的 Flutter 插件 | 支持实时数据库、身份验证、云功能等 | FlutterFire | 7k+ |
请注意,Star 数量可能会随着时间变化,以上数据截至 2023 年 10 月。如需获取最新信息,请访问相应的 GitHub 仓库。
图片加载的框架
iOS
Prompt: 以表格的形式输出 iOS 网络图片加载框架,包括使用的编程语言、描述、功能、GitHub 仓库地址和 Star 数量
框架/库名称 | 编程语言 | 描述 | 功能 | GitHub 仓库地址 | Star 数量 |
---|---|---|---|---|---|
SDWebImage | Objective-C/Swift | 高性能的异步图片加载和缓存框架 | 支持 GIF、WebP、APNG、缩略图等格式 | SDWebImage | 24k+ |
Kingfisher | Swift | 纯 Swift 实现的轻量级图片加载框架 | 支持异步下载、缓存和处理图片 | Kingfisher | 21k+ |
Nuke | Swift | 功能丰富的图片加载和缓存框架 | 支持异步加载、缓存、预加载等功能 | Nuke | 7k+ |
PINRemoteImage | Objective-C/Swift | 高性能的图片加载和缓存库 | 支持异步下载、缓存、支持 WebP 格式 | PINRemoteImage | 6k+ |
AlamofireImage | Swift | 基于 Alamofire 的图片组件库 | 支持图像过滤、缓存和下载 | AlamofireImage | 4k+ |
YYWebImage | Objective-C | 高性能的异步图片加载和缓存框架 | 支持 GIF、APNG、WebP、缩略图等格式 | YYWebImage | 4k+ |
HanekeSwift | Swift | 轻量级的缓存库,支持图片缓存 | 支持内存和磁盘缓存,自动缩放图片 | HanekeSwift | 5k+ |
SDWebImageSVGKit Plugin | Objective-C/Swift | SDWebImage 的 SVG 支持插件 | 支持加载和显示 SVG 格式图片 | SDWebImageSVGCoder | 300+ |
UIImageView+AFNetworking | Objective-C | AFNetworking 的 UIImageView 类别 | 为 UIImageView 提供异步图片加载 | UIImageView+AFNetworking | 33k+ (AFNetworking) |
ImageLoaderSwift | Swift | 简单的图片加载和缓存库 | 支持异步加载、缓存和占位图 | ImageLoaderSwift | 1k+ |
请注意,Star 数量可能会随着时间变化,以上数据截至 2023 年 10 月。如需获取最新信息,请访问相应的 GitHub 仓库。
Andorid
Prompt: 以表格的形式输出 Andorid 网络图片加载框架,包括使用的编程语言、描述、功能、GitHub 仓库地址和 Star 数量
框架/库名称 | 编程语言 | 描述 | 功能 | GitHub 仓库地址 | Star 数量 |
---|---|---|---|---|---|
Glide | Java/Kotlin | 高效的图片加载和缓存库 | 支持异步加载、内存和磁盘缓存、GIF 支持 | Glide | 34k+ |
Picasso | Java | 简单强大的图片下载和缓存库 | 处理图片加载、缓存,支持转换和裁剪 | Picasso | 19k+ |
Fresco | Java | Facebook 开源的图片库 | 支持大图加载、GIF、WebP、渐进式加载 | Fresco | 18k+ |
Coil | Kotlin | 基于 Kotlin 的现代图片加载库 | 支持异步加载、内存和磁盘缓存、动画 | Coil | 9k+ |
Universal Image Loader | Java | 过时但曾经流行的图片加载库 | 支持异步加载和缓存 | Universal Image Loader | 16k+ |
Glide Transformations | Java | Glide 的图像转换工具集合 | 提供多种图像转换效果 | Glide Transformations | 10k+ |
Picasso Transformations | Java | Picasso 的图像转换工具集合 | 提供多种图像转换效果 | Picasso Transformations | 5k+ |
AndroidSVG | Java | 支持加载 SVG 矢量图的库 | 解析和渲染 SVG 文件 | AndroidSVG | 2k+ |
Subsampling Scale Image View | Java | 支持显示超大图片的控件 | 支持平滑缩放和拖动大尺寸图像 | Subsampling Scale Image View | 8k+ |
ImageLoader | Java | 轻量级的图片加载库 | 支持异步加载和缓存 | ImageLoader | 16k+ |
请注意,Star 数量可能会随着时间变化,以上数据截至 2023 年 10 月。如需获取最新信息,请访问相应的 GitHub 仓库。
Flutter
Prompt: 以表格的形式输出 Flutter 网络图片加载框架,包括使用的编程语言、描述、功能、GitHub 仓库地址和 Star 数量
框架/库名称 | 编程语言 | 描述 | 功能 | GitHub 仓库地址 | Star 数量 |
---|---|---|---|---|---|
cached_network_image | Dart | Flutter 的缓存网络图片加载库 | 支持图片缓存、占位符、错误图片显示等 | cached_network_image | 5k+ |
flutter_svg | Dart | SVG 矢量图支持库 | 加载和渲染 SVG 格式的矢量图 | flutter_svg | 3k+ |
photo_view | Dart | 图片查看组件 | 支持图片缩放、平移,适用于图片预览 | photo_view | 1.6k+ |
extended_image | Dart | 功能丰富的图片加载和处理库 | 支持缓存、编辑、裁剪、旋转等高级功能 | extended_image | 1.5k+ |
flutter_advanced_networkimage | Dart | 高级网络图片加载库 | 支持缓存、加载进度指示、重试机制等 | flutter_advanced_networkimage | 800+ |
octo_image | Dart | 提供多种占位符和淡入效果的图片加载库 | 支持占位符、淡入淡出动画、错误重试 | octo_image | 500+ |
flutter_blurhash | Dart | 显示模糊占位符的库 | 支持使用 BlurHash 占位符,提高加载体验 | flutter_blurhash | 500+ |
progressive_image | Dart | 渐进式图片加载库 | 支持先加载低分辨率图像,后加载高清图像 | progressive_image | 200+ |
flutter_luban | Dart | 图片压缩库 | 实现了鲁班算法的图片压缩 | flutter_luban | 500+ |
flutter_advanced_networkimage | Dart | 高级网络图片加载库 | 支持缓存、加载进度指示、重试机制等 | flutter_advanced_networkimage | 800+ |
请注意,Star 数量可能会随着时间变化,以上数据截至 2023 年 9 月。如需获取最新信息,请访问相应的 GitHub 仓库。
数据洞察
针对文档内容,我将分别为 iOS、Android 和 Flutter 提供一些有价值的观点,基于框架的特性、开发趋势及其在各自生态系统中的重要性。
iOS 平台的分析
- 自动布局系统(Auto Layout 与替代方案) :
- Auto Layout 是 iOS 的原生布局系统,它的动态布局功能使得 iOS 应用能够很好地适配各种设备的屏幕尺寸。随着新设备的推出,开发者需要确保应用的界面能在不同屏幕上保持一致,Auto Layout 提供了很好的适配解决方案。
- 但是,由于 Auto Layout 语法相对繁琐,开发者更倾向于使用第三方库来简化布局创建,例如 SnapKit(19k+ stars)和 Masonry(18k+ stars)。这些库通过链式语法让布局的书写更具可读性,提升了开发效率。
- 网络请求的主流选择:
- Alamofire(40k+ stars)是 iOS 开发中最受欢迎的网络请求框架,它简化了 HTTP 请求,支持文件上传、下载及认证处理。它的链式语法大大提高了网络请求的简洁性和可读性,因此广泛应用于项目中。
- 对于 Objective-C 开发者,AFNetworking(33k+ stars)依然是稳固的选择,尽管 Swift 逐渐成为主流编程语言,AFNetworking 仍在老项目维护和过渡期间使用。
- 图片加载和缓存技术:
- SDWebImage(24k+ stars)和 Kingfisher(21k+ stars)是 iOS 中最常用的异步图片加载和缓存库。两者支持图片的异步下载、缓存和格式处理,尤其适合优化应用的性能并提升用户体验。
Android 平台的分析
- 布局系统的灵活性:
- Android 的官方布局工具 ConstraintLayout 是目前最强大的布局系统,支持复杂的布局和动画。它结合了 MotionLayout 等工具,让开发者能够轻松实现 UI 动效,这一点在高交互性应用中至关重要。
- 另一个重要的布局库是 FlexboxLayout,它借鉴了前端开发中 CSS 的布局方式,使得 Android 开发者可以使用响应式设计来适配多种屏幕尺寸和分辨率。
- 网络请求的多样化选择:
- Retrofit(42k+ stars)和 OkHttp(43k+ stars)是 Android 社区中最受欢迎的网络请求库。Retrofit 简化了 API 定义和请求处理,尤其适合 RESTful API 的集成;而 OkHttp 则因其高效的 HTTP/HTTP2 支持和先进的特性如连接池、超时机制等,成为高性能应用的首选。
- 图片加载技术:
- Glide(34k+ stars)和 Picasso(19k+ stars)是 Android 开发者的常用工具。Glide 提供了更强大的缓存管理和内存优化能力,适合对性能要求较高的应用,而 Picasso 则以简单的 API 接口著称。
Flutter 平台的分析
- 响应式布局的优势:
- Flutter 的内置布局系统提供了丰富的布局组件,可以轻松实现不同屏幕的适配。结合 Responsive Framework(2k+ stars)等框架,开发者能够快速构建适应各种屏幕尺寸的应用,确保跨平台应用的 UI 一致性。
- Dart 语言和网络请求框架:
- Dio(13k+ stars)是 Flutter 社区的主流 HTTP 客户端库,支持全局配置、拦截器、请求取消等高级特性,非常适合复杂网络请求场景。其功能与 Android 的 Retrofit 类似,但通过 Dart 实现,与 Flutter 的生态系统紧密结合。
- 图片加载的灵活性:
- cached_network_image(5k+ stars)是 Flutter 中最受欢迎的图片加载库,支持缓存和占位符功能,这在跨平台应用中有助于提升用户体验,尤其是在网络环境不稳定的情况下。
总结
- iOS 开发者在布局时普遍依赖 Auto Layout,但为了简化布局代码,越来越多开发者选择 SnapKit 或 Masonry 等第三方库。网络请求和图片加载方面,Alamofire 和 SDWebImage 占据主导地位。
- Android 开发在布局上具有更多选择,尤其是 ConstraintLayout 和 FlexboxLayout,这两者提供了极大的灵活性。网络请求方面,Retrofit 和 OkHttp 继续主导市场,而 Glide 则成为处理图片的首选库。
- Flutter 由于其跨平台特性,布局和网络请求框架都高度依赖于 Dart。Dio 和 cached_network_image 是最受开发者青睐的选择,特别是在需要处理多屏幕适配和网络资源加载的场景中。
通过这些框架的对比,可以更好地理解不同平台开发的趋势和工具的选择,为优化项目开发流程提供有力支持。
来源:juejin.cn/post/7430770689684865078
我在成都教人用Flutter写TDD(上)——为啥要搞TDD?
哈喽,我是老刘
写这篇文章的时候刚回到北京,之前的一周去成都帮助一家公司完成基于Flutter的TDD流程的搭建。
这个工作一半是敏捷教练,一半是Flutter相关的技术顾问。
起因是这个客户接了一份欧洲那边的开发项目,但是欧洲客户对项目流程的要求比较高,要求开发团队采用TDD流程。
这是老刘第二次碰到要求开发采用TDD的情况,而且都是欧美客户。
为啥欧美软件开发团队对TDD这样的敏捷开发趋之若鹜,而大多数国内团队却鲜少能真正搞起来敏捷开发?
是我们比欧美开发者更务实还是敏捷开发确有其独到之处?
老刘希望用这篇文章尝试解答一下。
我记得刚去成都的时候大家一起吃饭,讨论起啥样的项目适合TDD,TDD会不会浪费额外的时间这些话题。
当时吃饭只是简单的聊了聊,但是让我意识到一个问题,TDD或者说敏捷开发在国内之所以一直没有真正成为主流更多的可能是意识问题。
看不到明确的收益,却能看到明确的额外工作量,怪不得众多管理者不愿意尝试。
这篇文章会回顾一下我的敏捷开发相关的经历,并借此尝试回答TDD究竟能给我们的开发带来什么收益。
初试敏捷:网络安全领域的尝试
老刘我带着团队使用Flutter进行App开发已经6年多了,而搞TDD的时间更长一些。
大约10多年前我还没有做客户端开发的时候,那时候我是做网络安全方面开发的,使用的是C语言。
那时候公司希望在敏捷开发方面做一些尝试,因为我在研究生期间做过一些敏捷方面的工作,所以就承担起来这个任务的研发部分。
当时公司希望尝试的是Scrum的完整流程,但是因为涉及到的团队和部门有点多,而很多团队对这个流程是持保留意见的,所以最终就没有搞成。
但是研发内部的单元测试和TDD流程因为只涉及开发团队,最终得以保留,这成为了我们探索敏捷开发的重要起点。
TDD的实践与收获
虽然最终Scrum没有成功搞起来,谈不上升职加薪 ┭┮﹏┭┮
不过在TDD的探索方面确实有很多的收获:
1、实战经验的积累
这是我第一次在百万级代码量以及几十人的项目中实施TDD流程。
相当于把以前只能算是纸上谈兵的认知变成了真正的实战经验。
2、踩坑与成长
在整个的实践过程中,我们几乎踩遍了所有可能的“坑”。
要知道防火墙项目的规模和复杂度相对于一般客户端或者服务端项目要高很多,特别是还有很多底层数据的操作和对系统内核的修改定制。
例如,我们的代码需要在MIPS架构的CPU上运行,而MIPS与常见的x86架构在字节序上存在差异。这种差异导致我们在PC端进行单元测试时,经常遇到与设备上运行时不同的错误。
这件事直接导致了后来我们对整个代码进行重构,把我们的业务逻辑和cpu架构解耦。
这是我第一次如此直观且深刻的看到架构到底是什么,也让我在后续的开发过程中开始有意识的注意架构设计的合理性。
3、TDD与架构合理性
在解决TDD实践中遇到的各种问题时,我们逐渐意识到,超过一半的问题实际上源于不合理的架构设计。
以之前提到的CPU字节序问题为例,一个合理的架构设计应该将底层数据操作与上层业务逻辑解耦。
理论上,我们都明白低耦合、高内聚的重要性,但在实际操作中,很难把握到何种程度才算真正实现。
而单元测试在这里就扮演了一个标尺的角色。
它通过测试的难易程度和可行性,帮助我们检验架构设计的合理性。
如果某个部分难以测试或者无法测试,这往往意味着架构存在问题。
通过这种方式,TDD不仅促进了代码质量的提升,也推动了架构设计的不断优化。
对TDD的推行加深了我们对架构合理性的理解,也让我们在后续的项目中能够更加注重架构的合理设计。
4、TDD是思维模式的转变
自己用TDD方式写代码和组织大家一起写又是一种不同的经验。
TDD本质上不是一个编码流程,而是一个设计流程。
在工作中去观察那些真正的资深程序员和新手的差别就会发现,资深程序员是在做脑力劳动,新手是在做体力劳动。
资深程序员通常是把一个功能点的逻辑链条想清楚才开始动手写,而新手却往往急于动手,发现问题后才不得不对代码做大幅的修改。
所以他们不是在加班写代码就是在加班改bug,然后就把工时卷上去了。
TDD为普通程序员提供了一条追赶资深程序员的捷径。
通过先编写单元测试,再通过测试驱动来编写正式代码,TDD迫使开发者在编码之前深入思考功能的逻辑链条。
这种拆解测试例的过程实际上是在进行设计工作,它要求开发者在动手之前就想清楚功能点的代码设计。
即使最初的设计或思考存在问题,TDD的重构步骤也会促使开发者及时发现并解决问题,减少定位问题的成本。
而且,所有的重构和修改都是在测试代码的保护下进行的,这样可以确保修改不会对现有代码造成意外的影响。
因此,TDD不仅仅是工作顺序的改变,它是一种完全不同的思维模型。
这种思维模式的转变对于提升整个团队的开发效率和代码质量都具有深远的影响。
(关于这一点我会在后面的经历中更详细的说明。)
TDD在客户端开发中的尝试
后来我开始转做Android客户端方向的开发工作。
我尝试着在客户端开发中使用TDD流程。
刚开始我以为这会是一件非常简单的事情,因为Android开发是基于Java体系的,而Java生态中有大量单元测试框架可供挑选。
万万没想到的是在Android工程中执行单元测试每次都需要等待漫长的编译过程。
基本上可以理解为执行一个单元测试就需要把整个工程编译一遍。
虽然可以通过Robolectric等库脱离对Android环境和SDK的依赖,但实际效果仍然很不理想。
要知道TDD的核心在于小步快跑,如果每个测试例都需要编译几分钟然后运行,就完全背离了TDD的出发点了。
所以这次在客户端开发中对TDD的尝试以失败告终。
Flutter带来全新的可能
大约六年前,我带领着Android开发团队,我们当时面临着一个挑战:如何解决Android和iOS两个客户端在用户体验上的差异问题,同时还需要摆脱原生项目中历史代码的泥潭。
在寻找跨平台开发框架的过程中,Flutter以其技术优势脱颖而出,但其年轻和缺乏有说服力的案例让我犹豫不决。
最终是Flutter对单元测试的良好支持让我最终下定了决心。
在此之前,我已经放弃了在手机端开发中实施TDD的想法,因为原生单元测试的体验实在令人沮丧。
但当我尝试了Flutter的单元测试后,我意识到TDD在移动开发中还能再抢救一下。
Flutter的单元测试体验可以用“舒适”来形容。
测试的运行速度达到了秒级,并且在测试场景下对UI组件的支持也非常出色。
这使得TDD从看似不可能的任务变成了一个顺畅且自然的过程。
Flutter的设计考虑到了TDD的场景,并且不仅仅是在小规模项目中,即使在大规模工程中也能实施TDD,这为移动应用开发带来了全新的可能性。
但是TDD在Flutter上的实施过程也不是一帆风顺的,主要挑战来源于两个方面:
首先,团队成员对Flutter的掌握程度不足。
由于团队中的小伙伴们都是Flutter的初学者,他们在对Flutter本身还不够熟悉的情况下尝试执行TDD,遇到了不少技术上的挑战。
其次,长期从事客户端开发的资深程序员在切换到新的开发流程时,似乎比新手更加困难。
这些资深程序员由于多年养成的开发习惯,很难立即适应TDD的模式。
他们习惯于传统的开发流程,对于TDD这种先编写测试用例再编写代码的方式感到不适应。
这种习惯的转变需要时间和实践,才能逐渐适应并掌握TDD的精髓。
面对这些挑战,我们采取了多种措施来促进TDD的实施。例如,组织定期的培训和研讨会,帮助团队成员加深对Flutter的理解,并通过实际案例来演示TDD的实践方法。同时,我们也鼓励资深程序员和新手之间的交流和合作,通过分享经验和教训,共同克服实施TDD过程中的困难。
基于Flutter的TDD带来的改变
经过半年多的学习、尝试以及代码架构的调整,我们从项目数据上看到了一些明显的变化。
首先解释一下之所以用了超过半年的时间,主要是因为我们的项目采用Flutter + 原生的混合开发模式。
刚开始的时候主要以原生代码为主,Flutter用于开发少数不重要的页面进行测试。
验证了Flutter的用户体验和稳定性后,Flutter页面的比例才开始逐步上升,然后Flutter才变为日常开发的主导。
随着Flutter变成日常开发的主要选择,可以看到几个明显的变化。
1、开发效率提升60%
这其中一半是Flutter本身优秀跨平台能力带来的。
只要不涉及原生功能,Flutter基本可以完全覆盖所有需要编写的代码。
从性能和用户体验来说Flutter页面也完全能胜任代替原生。
另外一半效率的提升则来源于TDD。
这主要体现在下面的几点。
2、提交测试后bug减少70%
这个数据其实从不同的维度统计会有不同的结果,我个人倾向于减少的bug比例会更高一些。
举个例子,产品需求写的可能是从家里坐车到全聚德烤鸭店。
开发人员要实现的是走3米到家门口——开门——走5米到电梯——按电梯哪个按钮——出电梯左转——走5米后右转出单元门……
这还只是正常情况,没有考虑如果电梯坏了怎么处理,路上有人放了东西怎么绕开。
开发工作的本质其实就是把所有正常的、异常的可能情况都进行处理。
这个过程中主要会出两种问题:
- 有些场景没有考虑到,比如没想到路上被堆了箱子需要绕路。
- 处理流程不达预期,比如考虑了绕路,但是绕路的流程不对,走不到单元门。
我们正常的瀑布流程其实就是开发人员先思考一下整个流程和都有哪些可能情况,这一步是设计阶段,更精细一些的可能还会区分概要设计和详细设计。
然后就是用代码实现这个流程,并且补充每一个细节,这一步就是编码阶段了。
开发完成后研发人员会进行简单的测试,比如验证按照自己的代码能不能走到全聚德。
如果能走到就会认为功能正常把软件交给测试人员进行更详细的测试。
测试人员会测试所有能想到的可能场景,发现某些场景走不到就给开发人员提bug。
按照这个流程写代码,出现bug是再正常不过的事情了。
主要有几个原因:
- 现实情况纷繁复杂,总会有一开始没有预料到的情况发生。甚至有些情况测试同学也没有预料到,只有APP上线了用户使用中发现了才会反馈回来。
- 即使有很严格的概要设计、详细设计流程,其精细程度也远远做不到真实代码的精细度。而设计过程越粗放,编码过程中遗漏、出错的概率就越高。
- 研发自己测试代码功能相对来说覆盖范围比较小,有些功能自己感觉实现的没问题,但是又没有测试到,只能在测试阶段由测试人员发现。
上面几种情况中第一种其实是无法避免的,而后面两种TDD都可以帮助开发人员最大幅度的降低发生的概率。
前面说了TDD是一个设计流程,它本质上代替的是概要设计和详细设计。
我们通过把一个功能需求拆分成不同的任务,把一个任务拆分成多个很具体的测试例来进行代码功能的拆分设计。
这种设计精细到什么程度呢?
每一行功能逻辑的代码都有对应的测试例,因为每一行功能代码都是测试例驱动下编写的。
而且TDD从流程上要求先写测试代码,这就强制开发者必须先进行设计层面的思考,然后才能开始编码。
这进一步避免了瀑布流程中省略或者敷衍设计流程,直接进行编码的情况。
接下来说开发者自测覆盖范围有限的问题。
基于TDD编写的代码每一行都是先有测试代码的,可以说每一行功能代码都是测试覆盖的。
可以在大概率上保证功能代码的运行结果和我们预期是一致的。
那种我写了很多代码,一运行结果和我想的完全不一样的情况在TDD中很难出现。
所以最终效果就是使用TDD流程后,我们团队提交测试的项目,总的bug数量大幅降低,测试周期和产品发布周期的稳定也得以保证。
3、交付健壮、可修改的代码
不知道各位看到这里的同学有多少是正在996的。
加班这种事在国内的软件开发领域很常见,这里面当然有即使不忙也要把工时耗够这种无效内卷的加班文化的原因。
但是也确实有很大一部分比例是因为项目进度不达预期导致开发人员不得不加班加点赶进度。
为什么项目总是面临延期的风险呢?
排除了那些管理混乱总是临时插入新需求的团队,瀑布流程本身对项目进度掌控力不足才是罪魁祸首。
做过几年开发的同学可能都碰到过这种情况:
项目刚开始的时候时间并不紧张,开发进度推进到中期发现原本以为很简单的一个对现有代码模块的修改远比想象中复杂。
要么是那坨代码和众多地方耦合,牵一发动全身,根本没法简单修改。
要么是那坨代码根本看不懂,写它的大神早已离职或者被当作大动脉裁掉了。
你薅秃仅剩的头发,熬夜加班把这部分代码改完,然后发现不是功能不好用就是原先工作正常的模块出问题了。
然后原本正常上下班的项目迭代周期就变成了996。
这种情况反复的发生,于是开发者在预估项目时间时就会增加很多的冗余时间来应对。
项目管理者知道你会预留冗余的时间,要么压缩项目进度,要么时不时的插入临时功能。
最终无效内卷的死循环达成了。
那么TDD能解决这个问题吗?
答案是可以,而且TDD能将这种情况发生的概率降到最低。
其实我们看前面说的场景,本质上就是两个问题,对现有代码“看不懂、改不动”。
先说“看不懂”的问题
TDD中业务代码都是由测试代码驱动生产的。
所以测试例和测试代码本身就是对业务代码最好的说明。
而且这种说明是站在业务代码的使用者角度,会向你展示业务代码是如何被使用的以及各种不同情况下预期的结果是什么。
另一方面,要想实现所有业务代码都基于测试代码产生,测试例的顺序必须是层层递进的。
所以基于测试例的前后顺序也很容易把握业务逻辑的脉络。
再来说“改不动”
当我们面对一团乱麻的代码,即使这份代码就是自己写的,想在上面做些修改也绝非易事。
究其根本还是当初写代码的时候只顾着实现功能,没有腾出手来对代码的合理性做一些优化。
这其实和一个程序员的能力水平关系不大。
我们的大脑本质上是单核cpu,无法同时干两件同类的事情。
比如你没办法一边和人说话一边写邮件。
同样的道理,你也没办法一边思考业务逻辑如何实现一边思考代码结构如何优化。
敏捷开发的先行者们对这种情况有很清晰的认知,所以敏捷开发中队这种情况也有不少很好的应对手段。
而TDD就是其中很有效的一种。
TDD的小步快跑最后一步就是重构。
它不要求你实现业务逻辑时就把代码结构一并调整完善,而是把重构这个动作放在了实现业务逻辑之后。
这样就可以保证每个步骤只专心的完成一件事。
写测试代码的时候就专心思考业务代码应该提供什么样的功能。
写业务代码的时候就专心思考具体的技术细节如何实现。
重构的时候就专心思考代码结构怎么样更合理更健壮。
把重构作为一个独立步骤的第二个好处是会强制你进行重构的思考。
其实大部分程序员都是有意愿去优化代码结构的。
但是如果碰到项目进度紧急或者代码结构看起来很简单清晰等情况,人的潜意识就会让我们跳过重构这个动作。
这是人脑降低功耗的一种本能行为。
TDD的好处是把这个动作流程化、标准化。走到这一步,不管代码看起来是不是很简单,你都会去想一想有没有可以重构的地方。
即使最后真的没啥可以改动的,你也尽最大可能做到了代码优化。
而且从实际经验来看,很多时候即使看起来很简单的代码,当你专门去思考重构的时候还是会有一些值得修改的地方。
TDD给重构带来的第三个好处是你的重构是在测试代码保护下进行的。
实际工作中开发人员有时候排斥重构一个重要的原因是责任问题。
比如原先代码虽然混乱,但是能正常工作,你重构了结果出现bug,在很多团队里你就要背这个锅。
TDD的特点是大部分代码都是在测试例的覆盖下。
你的重构是否会对现有代码逻辑造成影响跑一遍测试就知道了。
所以我们重构的时候也不用担心把原先好用的功能搞坏了。
同时这种所有代码都在测试保护下的特性,也解决了“改不动”的另一个原因:代码副作用。
这里说的代码副作用是指当我们为了开发新功能对原有代码进行修改时,影响原有功能不能正常运转。
这一点有过团队开发经验的同学应该深有体会。
新功能提交测试了,收到一堆bug都是影响了原先正常的功能。
当然这本质上还是架构不合理、代码混乱的原因。
但是在TDD的场景下,你要修改的代码都在测试代码的保护下,即使架构不合理也不用担心把原先的逻辑改坏了。
4、Flutter与原生代码对比
我们团队使用Flutter一年多之后,已经有几十个页面由原生迁移到Flutter上。
因为在Flutter端采用了TDD流程,对比这些页面的原生代码和Flutter代码,可以明显看出两者的不同。
Flutter代码更为整洁、清晰。
在Flutter代码中几乎找不到大段的重复代码,基本都在重构阶段被消灭了。
而Flutter代码中除了UI布局和底层的三方库封装部分,其他代码都对应的测试覆盖。
直接体现在开发过程中就是当我们同时有Flutter和原生的新需求时,Flutter投入一个人,原生两端各投入一个人,都是1周开发时间。
Flutter提测后bug数量比原生少了70%以上,三天就测试完成可以交付。
而原生端前前后后改了一周bug才勉强达到交付标准。
那段时间原生iOS端的开发同学每天晚上加班改bug到10点多(那个模块iOS端的历史代码太混乱,经常一不小心就把原先的代码改出问题)。
所以不同流程下开发效率的差距可见一斑。
而且这种差距会随着项目迭代,代码量的累积和越来越大。
总结
六年后再来看,我们的App大多数页面都已经切换到Flutter版本。
前段时间领导找我谈心好几次,都是因为我们客户端团队平均工时太少。
可是我们对比另一个产品没有使用Flutter的客户端团队,规模差不多的项目,我们的人手是他们的一半。我们交付的稳定性、项目周期可控性、bug率等指标都远好于他们。
应该说TDD充分证明了在这种长期迭代的项目中的可靠性和项目收益。
那么回到文章最开始的问题,在短期项目中是否值得使用TDD呢?
我的观点是只要你的项目不是那种写完代码不需要改bug就交付的类型,那TDD一定能带来正收益。
这几年我们也做了几个临时性的小App,都是不需要后续长期维护的那种。
我们全部沿用TDD流程,结果也如预料,项目的测试周期、交付质量和我们的主项目基本一致,远高于以前的原生项目。
所以真的不要再觉得写测试代码是花了额外的时间,这些时间本来就是用于进行设计的。
你只不过是换了一种概要设计和详细设计的方式。
而得到的收益就是你的项目从架构到代码细节的质量再到后期修改和维护的能力都得到了不可思议的提升。
好了,本文主要是结合我过往的TDD实战的经历,希望能从理论上说明TDD在不同类型的项目中能给我们带来哪些收益。
下一篇文章,我会结合成都客户的具体情况和我们自己在Flutter上实践TDD的过程来讲讲基于Flutter的TDD具体流程和技术细节。
如果看到这里的同学有学习Flutter或者TDD的兴趣,欢迎联系老刘,我们互相学习。
点击免费领老刘整理的《Flutter开发手册》,覆盖90%应用开发场景。
可以作为Flutter学习的知识地图。
覆盖90%开发场景的《Flutter开发手册》
来源:juejin.cn/post/7441479625971318835
📢 程序员注意!这些代码可能会让你"吃牢饭"!
关注我的公众号:【编程朝花夕拾】,可获取首发内容。
01 引言
不知道你有没有听过面向监狱编程,可能你好好的码着代码,就就被帽子叔叔带走了。
"我只是个写代码的,关我什么事?" 这是深圳某P2P平台架构师在法庭上崩溃大喊,但代码提交记录中的"反爬优化注释"成了铁证——他因非法吸收公众存款罪获刑5年。这不是电影,而是2023年真实判决!
程序员早已不是免责职业,你的键盘可能正在敲响监狱的大门!
02 血泪案例
⚠️ 这些代码真的会"坐牢"!
2.1 爬虫爬进铁窗
爬虫其实是最容易爬进铁窗的代码。当时可能只是为了解决一个业务痛点,一旦被非法使用,就可能触犯法律的红线。开发者无意,使用者有心,莫名其名的就背了锅。
案例:
浙江某程序员用分布式爬虫狂扫10亿条个人信息,庭审时辩解:"技术无罪!"。
法官怒怼:"每秒突破5次反爬验证,这叫'技术中立'?" —— 6人团队全员获刑!
所以,我们在日常工作中开发爬虫就应该得到启示:
- ✅数据是否涉个人隐私?
- ✅是否突破网站防护?
- ✅对方是否知情同意?
实在拿不准,公司一般都会有法务,可以咨询。
2.2 权限变"凶器"
我们在开发过程中为处理决异常数据的问题,可能会在代码里面留后门。正常的业务功能本身没有问题,但是涉及支付、数据安全等行为,就要注意了。被他人恶意使用,不仅会造成财产损失,可能会还会勉励牢狱之灾。
案例:
杭州前程序员偷偷植入"定时转账代码",21万公款秒变私人财产。检察机关以马某涉嫌盗窃罪、妨害公务罪向法院提起公诉,经法院审理作出一审判决,马某被判处有期徒刑四年二个月,并处罚金。
该起事件也为程序员们敲响了警钟。玩归玩,闹归闹,法律红线不可碰。
🛑 高位操作清单:
- ❌ 私留系统后门
- ❌ 超权限访问数据
- ❌ 删除/篡改数据或日志
2.3 "技术黑产"陷阱
程序员除了工作之外,很多人可能还会通过接私活,如猪八戒网等。以此增加自己的收入。没有公司的严格审核,很多程序员就会掉如技术黑产 的陷阱。
案例:
湖北大学生接私活开发"诈骗APP",庭审播放需求录音:"要能后台改赌局结果"。可能当时你只想着:"我只负责技术实现" 最后却成诈骗案从犯!
尤其一些关于支付的似乎要尤为谨慎,特别是支付成功后,限制体现的时间,很有可能就会用于非法洗钱的黑坑里。
🔥 接私活避坑指南
- 👉 要求签署书面合同
- 👉 录音确认需求合法性
- 👉 转账账户必须对公
03 为什么程序员总成背锅侠
其实大多数程序员都是很单纯的,尤其那些喜欢挑战的程序员。他可能只为表现自己的实力,仅仅只是按照需求开发了功能,但是被恶意利用,最终成为背锅侠
程序员以为 | 法官认定 |
---|---|
突破反爬是技术挑战 | 非法侵入计算机系统 |
按需求开发无过错 | 明知违法仍提供帮助 |
删除代码就没事 | 电子证据完整链锁定" |
血泪真相:你的Git提交记录、代码注释、甚至TODO列表都可能成为呈堂证供!
04 IT人保命三件套
4.1 代码防坐牢套餐
敏感功能增加法律注释。开发的功能以及项目的沟通都要留档尤其需求的变更。因为接到需求的时候可能没有问题,改着改着就出问题了。
拒绝口头需求,落实文档记录,需求、会议、项目事件以邮件的方式存档。
4.2 权限管理生死线
权限管理是保护数据安全的重要措施,但是可能为了调试方便,预留逃逸后门。被人利用轻则数据信息泄露、重则踩缝纫机。
三方对接中,加强公钥、私钥的管理,防止恶意推送或者拉取数据。敏感信息是否脱敏,都是开发中需要考虑的要点。
如果有必要,增加埋点记录,日志记录。收集用户的操作行为。
4.3 法律意识
每个IT公司都会面临网络安全的检查,可以多了解一些相关的法律发条。至少了解那些数据可能会属于需要保护的数据,引起重视。
如果公司允许,可以多参加一些《数据安全法》《网络安全》等的培训。
05 技术向善
代码改变世界,这个不是一句虚话。运用好技术,代码也可以是光。
阿里巴巴的支付宝硬是借助技术,将全国带入数字支付的时代;疫情期间的随申码、一码通等,为战胜疫情作出了巨大贡献;大模型的火爆推送了智能时代的到来等等。
真正的大神不仅代码能跑通,人生更不能"跑偏"!
你在工作中遇到过哪些"法律边缘"的需求?评论区说出你的故事。
来源:juejin.cn/post/7506417928788836362
写了7年代码,我有点焦虑了!
很多人都知道程序员是吃青春饭,但是身为程序员的我们却很难感受到,直到某一天跳槽,突然看到坐在对面的面试官比自己还年轻,问的技术自己都是最新的,是不是觉得不服老都不行了
我是92年出生的,13年下半年入职第一份工作, 至今写代码经验已近7年。
职场经历也是有过多种角色,初级程序员、中级程序员、高级程序员、项目经理、小组长、后端负责人等等。
除了短暂的做过政府项目、企业内部建站项目等,大部分还是混迹在互联网项目,项目经验也算是比较丰富。做过很多失败的产品,也参与过日并发近千万的项目,但是还是抵不住我的焦虑。
为何焦虑?
家庭开支和各类贷款
因为结婚生娃了,家庭开支压力也来了,如果不是靠着副业收入的补贴其实是很难存下来钱的。
深圳的生活压力其实挺大,稍微算了下每个月的支出从去年开始已经差不多稳定超2w了。
生活成本:房租3700+车贷4300+老家买的房贷2300+ 两个大人一个小孩的支出7000+
车贷目前还有3个月就还完了,这点倒是可以松一口气。
年龄和环境
再有2年就迈入30岁这个槛了,都说男人30而立,但是对于30岁的程序员来说,能保留一头浓密的头发已是万幸,我已经有这个趋势了,目前还在抢救中,晒个图吧
当然,头发只是顺带的劣势,主要是如果30岁还没走上管理岗或者核心岗,那以后跳槽是相当悲剧的,写代码的如果跨行,多年的项目和业务经验都带不过去,在企业择人的时候,为什么不选个25岁的呢?
再说环境,如果我目前待的公司是世界五百强等牛逼的企业,肯定不会说焦虑这类的东西了,因为往往是那些公司,年龄和经验反而不是事业的阻碍,至少在企业内部不出问题的情况下还能稳定待很久,这个东西往往很现实的,很多工作多年的程序员跳槽的时候,除了考虑到薪资和待遇,对公司的稳定性还是有很大考量的。
很多人包括程序员都觉得,以后大不了年纪大了身体扛不住了转管理,但管理岗是这么容易说转就转的么?没有经历过带团队和带项目的你,给个团队你带岂不是带的一团糟,所以在这里建议程序员在工作中尽量体验多种角色,比如说小组长、项目负责人、项目经理或者团队负责人等等,不仅能在沟通上锻炼弥补程序员的不足,做出一定成绩了还能在工资和待遇上体现出来,这点我是深有体会。
对转业后的迷茫
本来想说退休的,有点歧义,这里叫转业吧。
转业是不可避免的事情,至于啥时候转业,啥时候考虑转业,还是根据个人所处环境决定的。
有的人在大公司,公司业绩蒸蒸日上,手握大把股权,自然不会考虑到这上面
但这是更多普通程序员的必走之路
所以很多有想法的程序员会对转业前有一个前期规划,大体上就是:工资+副业+理财
作为我来说,理财这方便目前还是小白,其他两个马马虎虎吧。
所以还得继续加油
年轻的程序员和上了年纪的程序员
认识一些之前共事的程序员朋友,在聊天的过程中发现,年轻的程序员不太喜欢安于现状,当环境或者薪资达不到自己期望的时候,就会选择跳槽,而且大概率能找到待遇比之前公司好的,上了年纪的程序员喜欢求稳,因为一份工作已经来之不易,养家糊口不容易,没那么喜欢折腾了。
同学小A
小A是我的大学同学,在近期有过一次跳槽,虽然其他待遇比之前公司差了一点,但是工资却是足足涨了5k,从25k涨到了30K.
虽然待遇提升了,但是还是避免不了程序员从一个坑跳另一个坑的魔咒,入职第一天就开始吐槽项目代码~
对此我只能深表同情~
同事小B
小B是之前的同事,算算时间竟然也认识5年了,5年前就是前端leader,目前已经35岁了,我们有共同的群聊,一直保持密切沟通,这点我觉得在维护同事关系上还是做得不错的。
小B目前也是一家公司的leader,这两年又生了二胎,加上前几年在惠州拿了一套房,经济压力还是挺大的,当我们聊到跳槽这个话题的时候,想不到也是怂恿不动,一心求稳。不过小B保养有道,一个35岁的大龄程序员竟然看起来和毕业生差不多,想必还能写5年代码。
写到最后
焦虑这个话题,感觉不适合写长篇大论,只能草草收尾了,以下几点是写给大龄程序员以及自己的建议:
- 做好长期合理理财。你不理财,财不理你,以前看到相关理财软文,其实是比较反感的,但是当身边一些朋友通过合理理财并获得比较理想回报的时候,我就在拍脑袋,觉悟跟不上啊。
- 有上位机会的尽量不要错过。认识很多程序员当上面让他顶上去的时候都喜欢退缩,如果你的程序员生涯只仅限于写增删改查,那么多年以后真的只能做增删改查被淘汰了。当领导是会背锅,是会压力大,但是你收获的会更多。
- 调理好身体。这点我就做的不好,已经有脂肪肝了,每年体检都会有点大大小小的毛病,身体就是革命的本钱,年轻的时候赚的再多,不搞好身体都会交给医院
看到这了,但凡有点共鸣,点赞转发走一波?
来源:juejin.cn/post/6860043925357821966