2024年终总结

前些天还有很大冲动要赶紧忙完手头事给这个年更节目预留时间,但真腾出空来打算下笔时,迟疑了很久,不知从何说起。打开相册从 1 月翻到 12 月,各种平淡无奇的片段一闪而过,要说这一年都干了些什么,貌似除了继续“熬”着并没有什么让我印象深刻,但真当想放弃时,又觉得该为他记录些什么。此刻的我扁桃体发炎加高烧不退,最终能写下啥文字,有几分可读性也不再清楚,但年更节目不能断更。 在投资中感受人性的贪婪与恐惧 要说这些年的“熬”收获了什么,我首先想到的是对贪婪与恐惧的人性有了更深的认知。在每一轮行情中,除了感受市场冷暖,自己的贪婪与恐惧也随之不断辗转。 今年初,A 股在急跌后迎来了一波转瞬即逝的疯狂反弹,就当大家还没回过神来,随着经济数据陆续出炉,市场情绪迅速冷却,一路阴跌到 9 月缩量到每天 6000 亿左右。熬到熊市第三年,加仓的间隔与金额在每次计算时都显得更加谨慎,虽然心知肚明,市场不可能一直跌下去,但在经济下行的背景下,不论是宏观行业还是微观个体的经济状况,都在不断恶化,我也早已没了从前的自信。 就在市场绝望之际,9 月底重磅会议突然加场,给政策转向定调,市场情绪直接被点燃。你说这半个月不到的时间里,有实体经济变化了吗?丝毫没有。但上证指数就直接旱地拔葱式的从 2700 直接跳到将近 3700,“信心比黄金重要“。甚至,一位从不投资的同事,也在国庆期间信誓旦旦跟我预测:指数月底必上 6000,年底 10000 不是梦。当然,没人能猜到市场怎么走,一路狂欢的暴涨行情在国庆后也戛然而止。直至今日,A 股的震荡行情已持续三个月了。 不仅要有目标,还要有清晰的执行计划 你可能会好奇,在今年市场最疯狂的那半个月,我做了什么?市场突然转向,几乎没给我太多时间思考行动方案,但却给我带来了巨大的焦虑。这种急涨行情明显不可持续,我频繁问自己是否需要撤出一些已盈利仓位;与此同时,更让我不安的是随着行情从火热变得火爆,因为手头还有闲钱在活期,我也开始担心错过。 即便不知道击鼓传花最终停在谁手中,但我仍会觉得自己不是那最后一个,于是我开始谨慎增加了短期仓位,并开始沉迷于每天不停地刷新软件。从结果上看,没动长期仓位以及通过短期网格使我不仅享受了完整行情也额外赚到几波零花钱,多少算个小股神,但只有我知道,当时的我可不是这个状态。 直到现在,我仍会设想另一条不曾发生过的场景:如果行情快速跌回到 2 月?如果因为担心过早撤出了大量仓位,而后又上头追涨了进去?人终归是动物,贪婪与恐惧的情绪在投资上会被极大放大,如果没有清晰的执行计划,那么就只能依靠不可靠、充满情绪的大脑。 市场上赚钱翻倍的机会数不胜数,但只需要亏一次就可以净值归零。提前做好计划,不预测,只应对。新的一年,要把完善的执行计划补齐。 不用等到一切都就绪才开始 很多时候,我都会倾向一件事情在大体上就绪才开始,因为,太多的不确定性会给我一种”失控感“。我曾经从中受益良多,从竞赛获奖到推免保送,从校招斩获众多 offer 到依据自身规划跳槽晋升加薪,这些大多都是在有了足够准备和充分练习后,奋力发起一击的结果。但凡事没有银弹,并不是所有事情都适用这种方式,也不是所有事情都有足够的时间等得起你的准备。 还记得两年前就和朋友约定好,我们要互相监督努力发展副业,但两年过去了从没行动起来。反省起自身,也不算是个拖延症的性格,但就是一直没开始,源头还是因为我真的没准备好。我还需要想清楚,但如果一直不能想清楚呢? 我们今年做出了改变,先从稳定的输出开始。不论是生活、技术还是商业、社会,不用过多的关注行文段落和措辞,但要输出鲜明的观点。我还记得逼迫自己将第一篇文章选题香港时,逼迫自己在半小时内完成搜索、阅读、学习以及将文章发表出来当时争分夺秒的紧迫感。随后的大半年时间里,我利用下班、周末、健身的间隙记录些思路关键词,并通过其他空余时间将其扩写成文章。期间不仅越写越顺畅,还结识了不少朋友。 你要问我现在准备好了吗?我会说并没有,也许永远都准备不好,因为永远都会有值得琢磨与优化的空间,但他已经不影响我行动起来。在行动的过程中,不断地审视与回顾,使自己对要做的事情也有了更加清晰的认知。可能最初我定的目标是向东走,而后发现应该转向东南,但这都不重要,重要的是行动起来。行动的过程,也是在梳理思路、发现自己的过程。 留出时间,与自己对话 这些年经济下行压力很大。各行各业都受此影响。本以为熬一熬就能看到光明,但实际等来的却是起落落落。每个你我都承受了很多,这在日常工作上体现为”不停的内卷“。当增量市场没了空间,就只能从存量市场中抢蛋糕。当自己行业的蛋糕不够吃,便开始觊觎跨行业的蛋糕。一个直观的数据来源,从统计局统计的人均每周工作时长在不断提升。 我们都知道卷不好,但更不好的是他的副作用。我经常听到一些朋友的声音,他们说,再熬一熬,忍一忍就好了。但就像今年 9 月的闪电行情一般,如果我们只是一味的熬,而不思变,那等行情真正来临时,我们如何反击?一味的内卷,既是对当下生活的麻木应对,也占用我们用于思考的时间。 我今年坚持下来的几个习惯,都源自留出的时间。即便工作再忙,我都留出时间写作、健身与复盘。游泳吐气之余,思考自己昨天做的事还有哪些改进措施可以做得更好;坚持输出观点之余,与自己对话,为不断学习、不断收获的自己喝彩;坚持投资复盘之余,找到自己的弱点、补齐短期计划并实施。每个人都是一个独立个体,世上能真正与我们感同身受的只会有我们自己。懂的自己的希望与迷茫,快乐与悲伤,才能知道自己想要向哪走,以及如何走。 享受结果的同时也享受过程 今年的世界变得太快了,不论是世界政局变化还是国内经济发展,很多人都认为未来不会再好了。既然如此,那也不用熬了,直接躺平。躺平是一种生活选择,无关对错,不过我有另一个看法。 你不会说,当我想要收养一只小猫时,我发现猫是有寿命的,最终仍会离开这个世界,那我就不好好对它了。因为,在它陪伴你的每一天,那些美好的时光和片段,就会是最大的享受。另一方面,通过你的悉心照料,小动物可能会拥有稍长的快乐生活时光,而这个是你可以掌控的。 我们虽然希望享受结果,但过程一样重要。 保持好奇心与观察力 我读书期间去过国外一段时间,当时回国前,一位老师对我说,”Keeping curious“,随后我将那天的照片放在博客,直到今天。我的好奇心与观察力似乎一如往常,而如果我有机会再遇到他,我想好好的感谢他对我的鼓励。 不知道有没有人像我一样,会因为小区晚上更加明亮而发现物业更换了一批更节能的路灯,发现平日上班的小道被市政凿开重新铺了砖块,也会发现航班上的小桌板不再每次都保持干净,发现外出就餐时餐厅工作人员变少以及更多的引导我们自助扫码点单。我们工作时,大家不再考虑我们一起做出一款卓越的产品,而是更多考虑这个功能的投入产出比以及是否有用户需求。当我们购买电子设备时,导购员也不再无脑鼓吹你下单,也会给你提供一些优惠券的领取建议。 世界还是我们从小到大的那个世界,但似乎又在细微之处变了许多模样。充满好奇心,对周边事物持续观察,我仍享受着由此带来的乐趣与自由。此刻的我即将踏上再次前往上海的旅途,而我记忆深刻的仍是年初在上海的打车日记以及年中去上海与网约车师傅的一路交谈。 这一年我还做了些什么 三月份,达成了一个人做手术的顶级单身成就。我在手术当天提前到医院候着,在护士的引导下换上病服,但刚走进手术室便开始犯嘀咕了,”这手术室简陋的怎么跟电视剧里演的不一样呢?“ 这一年,除了几次去医院以及附随的康复期,我几乎每天都坚持到健身房打卡。自从去年同事鼓励我尝试器械锻炼后,我便一直坚持了下来。虽然没有健身房那些霸榜大哥的爆炸肌肉,但更有型一些的身材以及每次拳击时挥洒汗水的快乐,已经让我快乐满满。 虽然没有明确的出游计划,但今年因为各类事情的凑巧,还是逛了不少地方,也攒下了不少游客照。而”读万卷书,行万里路“里的读也仍在状态。 在公交车上,在地铁里,在商场等号就餐间隙,在上下班路上,对着那个电子屏幕,不断地翻页,不停地阅读。c除了书籍外,年初我还定了一个目标,即追更完今年所有的《财新周刊》,除了当下因为发烧无法继续的最后两期,我几乎坚持了下来。从财经、商业、宏观世界到人文落地,这份稳定且有质量的信息源,很好的扩充了我的世界观与从信息中攫取价值的能力。 今年,也并不都是美好。我坚持了多年的居家做饭习惯,中断了。一方面是享受做饭准备时的放空感,另一方面是真正尝到自己动手成果的自豪感,这难免不让我觉得遗憾,希望明年能拾起这中华民族自古以来的”优良传统“。 写在最后 这一年,不能说没有遗憾,但能够更坦然的应对失误、不纠结当下,我的世界观与认知明显正在变得更加完整,这让我感到充实、自由。虽然这可能不是我努力的结果,而是岁数到了。 轻舟已过万重山。新的一年,要加油。

2024/12/31
articleCard.readMore

车里的微光

刚到虹桥 下了飞机,我沿着通往停车场的道路走去,同时打开手机叫网约车。每次在机场叫车,貌似都需要跟司机沟通一番确认上车地点,软件的上车指引貌似只是一纸友好但过期的提示,并不具备实际参考价值。没过多久就有司机接单,很快一个电话打来,司机让我到另一层等他,我毫不犹豫地答应,径直朝向约定地点走去。当车到达,我把行李放入后备箱,像往常一样打开后座门坐了上去。 “师傅,不走高速哈,其他随意”,我说。 “好的,这一路没有高速,只有些高架”,他回答,“如果你在浦东叫车,那边可能有”。 “浦东啊,我前几个月来过一次,当时是从浦东机场出发的,那边可远了”,我抱怨道,“后来,我都注意选到虹桥机场了”。 我沉默了一会,继续说道:“浦东的客流是不是比虹桥少一些,毕竟远离中心市区嘛”。 “其实也不少,我们也能接到不少单。那边虽然远,但我更愿意接,赚的会更多一些”。 “是的,路途远价格就会高些”,想着师傅这么晚接我的单,于是我鼓励到:“师傅,你这么晚还跑车,家人肯定也挺心疼你吧”。 “就我一个人在这边,家人都在老家呢。对了,等你回去的时候可要注意,从哪个机场出发,别走错了,不然可就麻烦了”。 “好的”。 激烈的竞争 平时外出,我都会主动给家里报平安。在给家人回复完消息后,我又主动与师傅搭话:“上海的高架桥挺多呢,还有地道,车开着也不会堵吧,感觉比北京要好很多,经济也比北京有活力”。 “是啊,这里的路,建设的很好,到哪都方便”,他说道,“北京是首都嘛,上海还是比较多搞经济的人儿。但是啊,这两年也没以前好了啊。社会上那么多公司,又是裁员又是降工资的。就拿我们自己说,这半年赚到的也比原来少了很多”。 我说:“确实,我也有听说,好像滴滴提升了不少抽成比例吧?” “是的,比如平常你付 100 块钱的单,我们能拿到 80 块,今年可能就只有 70 喽,尤其今年过完年之后,这不就是压榨我们司机嘛”,从话语中能听到师傅对现实的无奈,但他仍在坚持。 “经济不好,大家就都卷起来了,同行互相卷,平台卷司机”,由于聊的比较投机,我继续说到,“现在,不仅滴滴抽成,你们内部也有危机感吧。前段时间新闻不是提到萝卜快跑嘛,也会抢走大家一些饭碗吧”。 “是啊,那萝卜在武汉多火啊,抖音上天天刷到。不过说回来现在道路这么复杂,你说我们都开不明白,他机器还能开明白咯”,师傅继续说道,“你看新闻不是也说两个萝卜在转弯的时候互相卡住了嘛,一动不动,给路上堵得哦。“ 师傅继续,“人还能听交警的话,那萝卜哪会听啊?路上要都是萝卜,那得乱套了。我看啊不太行,这开车还是需要人”。 电车与保险 “但现在电车真的很便宜,你觉得呢”,师傅谈兴正浓,开始饶有兴趣地给我介绍车市行情:“你看前阵子,比亚迪那车一出降价消息,价格就低了不少!依我看,其他车企啊都得跟着降。电车以后肯定会越来越便宜,大家都能买得起车”。 我突然有个疑问,便向师傅问道,”师傅,你说这路上跑的有多少是新能源车呢?” “一百辆里,至少得有五、六十辆吧”。 “那还挺多的。北京虽然也有新能源车,倒没这么多。可能因为天气冷吧,电池不经扛?” “是的,天气冷,电池掉电起来非常快,电车还是南方多些“。 我继续追问师傅:“话说,电车你考虑过蔚小理吗?相比比亚迪,他们的车型应该会更便宜些吧,性价比更高?” “比亚迪也不贵呢,而且质量多好呀。你看这次他们降价,又便宜了不少“,说到这,师傅扭了下身子,继续说道,“要说贵啊,还得是保险”。 “我之前倒是有了解过,好像是因为新能源车更容易出事故,再加上发展起来时间还太短,所以保险定价也比较困难?” “事故确实多,发生得也快啊。就像上一次我在路上开车,眼看着前方一辆车冒烟了,就开一会到跟前的功夫,那车已经全部烧起来了,你说这多严重啊!” 我紧握着收集,听着师傅的描述,仿佛能看到那些惊心动魄的场景在眼前一幕幕上演。 师傅似乎还有很多经验继续分享,“不仅是容易着火,平时啊你一个不注意,保费都会往上涨点。我去年续保费用涨了 20%,当时业务员也很纳闷,后面一查发现是违章、扣分啊这些,影响最终的价格”。 “但这保费啊,就算再涨也得买呀。这年头,你要不上保险,哪敢开车往路上跑啊。万一撞到人,误工费、住院费、治疗费这些各种算在一起,哪赔的起啊“,他说着说着有些激动,”你知道我们最怕什么吗?” 我摇摇头,表示不知道。 “最怕那些跟你耗着的。遇到个事故,就算不是你的责任,人家是弱势群体,你都得搭进去好些时间和精力,还有赔偿。就说去年那会吧,我的车直接被交警扣押了一周多”。 我问道,“你当时遇到什么事了吗?” 师傅说:“当时在小区里,我开的很慢,突然不知道从哪个缝里窜出一辆电瓶车,‘咣’地一下撞到我车上。你说明明是他没看路撞上来,检查后也没发现什么大问题,但他就是躺着不肯走。最后没办法,我只能报警。警察来了后,了解了一下情况,直接把我车拖走。后面赔了钱,才把我的车拿回来。” 我又疑惑道,“按理说,这事故也不是你的责任啊,为什么交警要扣你的车?” “不管谁的问题,你们之间没有协商好,交警就会先把车拖走,权当个抵押物吧”,他带着些许抱怨的语气说道,“必须等到双方协商好签完字,才能把车拿走。要是没法达成协议,对方还可以让你的车继续往后拖个十天八天的。车扣一天,我就少赚一天的钱,我在上海也要生活下去啊。你说,我哪拖得起呀?” 我安慰道:“有人就故意碰瓷,没事也说有事”。 “是啊,但你保不准会遇到什么样的人。现在买保险了,遇到事故就交给保险公司去处理了”,他说道。 她还在坚持 “还好有保险”,我感慨道。 “有了保险,也没太多改善啊,一样攒不下钱”,师傅感慨道,“你就说,我这一年跑车下来,也能赚个十几万不少了,要是在老家干活,一个月也就三四千,但还是攒不到钱啊”。 此时,路程已经好一会了,窗外的风景在多个高架桥和隧地道之间切换,一会明亮,一会阴暗,快速切换的光景让我时而可以放空发呆,给大脑一阵小憩。 车辆向前,貌似不再有地道了,具有经典上海街景的马路映入眼帘,两边整齐排列精致且小巧的楼房,在外饰灯光的映衬下还挺好看。即便如此,我还是感觉有些不对,说不上哪来的一股隐隐压抑感,突然,我想到,是对师傅印象的那种忸怩与割裂感,对的,就是这种不太真实的割裂感。 一个深夜这么努力跑车赚钱的师傅,对乘客出行给出热心建议,对新能源车行业也有自己的学习与了解,对激烈的市场和经济不好的大环境有所提防,同时还不忘配置保险保障家庭,怎么还会感慨攒不到钱呢。他的热情、努力与那份真实感,怎么都让我无法将他与那种赚到钱就去大手大脚消费、月光的人联系在一起。我心里犯着嘀咕, 而此刻,师傅开始主动搭话。 “我平时除了睡觉、跑车,也没啥开销,赚到的钱都往家里寄。你知道,我 88 年的,活到现在这个岁数,养家糊口啊开销很大,我这生活啊已经不是为自己而活了“。 我突然明白,原来师傅的钱都用在了家人身上,那确实花钱。还记得同事经常说,养娃就是个无底洞,师傅将花销都花在了孩子身上,那想必也是幸福的烦恼吧,我一阵释然。 师傅继续说道:“上有老下有小的,今天女儿要上个补习班,明天儿子要去学个兴趣课程,到处都花钱,就跟流水一样”。 我轻松应答道:“是啊,养孩子嘛,为了孩子定位茁壮成长,还有上学,都很花钱的”。 师傅继续:“小时候,我就在读书上吃过亏,现在不想他们再吃亏了,我多跑车,让他们可以多学一些吧”。 “可怜天下父母心啊,孩子长大后会明白你的好的”,我说道。 “倒不奢求他们将来如何回报我们,现在社会上那么多不孝顺的新闻,见怪不怪了。为他们付出了这么多,要真等我老了,他们不管我了,我也不能怎么办”,师傅补充道。 “是啊,这就是单纯的付出与爱,是不求回报的”,此刻的我由于对亲子教育没有太多经验,也不太想聊,于是借着上有老下有小的话题,我开始向「上有老」延伸,但没想到接下来引出了非常沉重的话题。 我对师傅说道,”孩子嘛,至少还有个盼头,就是不求他们孝顺回报,但这么一天天看着他们长大,也算有所慰藉。但是家里的老人啊,这事就不那么好处理了“。 听了我的话,师傅似乎没有那么主动想接话,由于我对父母养老这个话题也很敏感,所以每当有机会,我都会拉着人一起聊聊,于是我继续说下去,”父母啊随着年龄增长,不管是生病还是养老陪护,都需要花精力、花钱,有的时候这些事情才让人烦恼“。 师傅向前挺了挺身子,然后回复到,“可不是嘛,父母这一病,不停地吃药、治疗,每个月那么多钱,压力很大“。 师傅的声音突然低沉下来,他紧紧握住方向盘,一字一句的吐露着:“我妈每天都在吃药,每个月花很多钱在买药上,但依旧在病痛中度过,已经很久了。花费这么多,但还是没法好,而我们也不能多做些什么,除了多赚些钱“。 “她得了癌症,熬到现在有三年了”,他补充道。 我的转过头,看着窗外快速略过的夜景,试图平复自己的情绪,但师傅的话语却像一根针,深深地刺入我心底。昏暗的夜晚,只能靠着不断来往的车辆折射的灯光,隐约看到师傅的身影,此刻,我透过后视镜扫了师傅几眼,发现他的眼眶已有些湿润,闪着微光。此刻,我想安慰他,却发现任何言语都显得是那么的苍白无力。 尽力而为 只见师傅眼眶越来越红,他深吸一口气,仿佛在平复自己的情绪,然后继续说道:”你说做子女的哪能不管呢,但这三年来,不停地检查、更换治疗方案、换药治疗,花了很多,她每次忍着病痛的样子,让我看到真是如刀割一样。但我们已经尽力了“。 “是啊”,我憋出两个字回应师傅。 师傅继续说道:“我们家,我到上海来赚得多些,我爸在家打工,我老婆也在家打工,为了孩子和我妈,不停地攒钱,又哗哗的花出去,你说哪攒的下钱呐”。 “三年前她刚确诊癌症,当时每个月的钱还少些,但每隔两个月旧的检查一次,一次六七千,还要不断地买药。刚开始药便宜,后来药不管用了,医生就让我们换药吃,不断的换药,价格也不断上涨。上个月医生又跟我说之前的药不管用了,要换另一种药试试,一个月一两万。药越来越贵,也得继续吃着啊,她治疗着痛苦,但治不好,我们也难受。“ 这时我想起了医保,于是忙问师傅:“你妈有买医保或者农村保险之类的东西吗,那个应该可以分担一些支出费用?” “买啦。早几年,有个上门卖保险的,当时就给他们买了,赔了七八万吧,但要早知道,当时就该多买些,那样可以赔得更多。医保嘛,期初还能报一些,但后来不断加药、换药,那些进口药都不在里面,是不能报销的”,师傅一口气说了很多,但明显还没说完,他清了清嗓子,继续说道:“我妈是真遭罪,就这么一直扛着,扛了三年了,不知道还能撑多久了。我们真的尽力了”。 看到师傅的眼眶明显有些红润,我平静的说道:“你尽力了”,我不知道自己的表述是否恰当,于是停顿了一会,才继续说道:“可能努力改变不了结果,但至少让自己不留遗憾吧”。 ”你说尽孝吧,我们也一直在努力,但就没个希望。过个一阵,就听到医生说这个药效没啥效果了,需要换新的药。你说就我们县城,大家都是一个月三四千的收入,我在上海还能赚不少钱,这要换其他家里可能早就放弃了“,师傅的声音开始颤抖,”我朋友经常说我太拼了,为了父母,为了孩子,我也得继续拼搏啊!” “尽力而为,不留遗憾”,我说道。 “生活就是这样啊,但不还得继续努力嘛,总不能就这么放弃了。我妈都那么坚强,我也要继续努力。话说回来,我还是挺喜欢上海的,我能在这赚不少,让他们活的好些……” 车快到酒店了,司机放慢了开车速度,直到把车停在酒店大厅旁。他还在说,似乎没有喊我下车的意思,我也就继续听着。 “还是要买保险啊,有机会多了解些,这还是很有用的”,“多谢师傅,加油!” 这是我跟师傅最后的对话,此后我便下车,径直走向酒店。师傅也开车离去,继续他的人生旅程。放下行李后,我直奔健身房。跑了半小时步,我的心情好似才没有那么堵了,多亏运动帮我发泄一番。 尾声 就是这么一次再普通不过的打车经历,两个青年相互交换了各自生活中一个又一个的故事,这是每个普通人都会遇到的日常,也是每个普通家庭都可能会面对的生活难题。 虽然他口口声声说不再为自己而活,但我仍能感受出,他对自己奋斗目标的在意与上心,对平淡、幸福生活的向往。我跟师傅这辈子可能也不再会有机会见面,不知道他的家庭生活未来会去向何方,他的母亲病情会如何发展,他的两个孩子长大会做什么工作。 但我想,我应早已知道这些答案。这样一个个真实而努力的身影,每天都在我们周围发生,他正是千千万万个普通人的缩影。 为了赚钱补贴家用深夜跑滴滴的司机; 不论刮风下雨仍坚守岗位的建设工人; 牺牲自己睡眠坚守夜班以保障城市基本运转的服务人员; 起个大早为了路面清洁的环卫工人; 精心备菜在食堂为大家准备放心食物的厨师; 以及,每一个为生活努力的你我。 为每一个认真生活、奋斗拼搏的身影加油,愿每一个像他般努力、坚持且热爱生活的人,都能幸福。

2024/7/25
articleCard.readMore

来简单聊聊 AI Gateway

写在最开始 在当今科技领域,大型语言模型(LLM)和生成式人工智能(AIGC)已成为引领潮流的热门话题。它们的出现不仅颠覆了我们对传统人工智能的认知,还为各行各业带来了前所未有的变革。然而,随着这些技术的广泛应用,如何有效地将这些强大的 AI 模型集成到实际应用场景中,成为了一个亟待解决的问题。在如此背景下,一个名为 AI Gateway 的概念近期被大家所了解,作为一种连接 AI 技术与各类应用的关键平台,它又为当前火热的 AIGC 带来了什么? 本文将详细介绍 AI Gateway 的概念、功能,并通过丰富的应用场景展示其在实际应用中的巨大潜力。通过阅读本文,相信你会对 AI Gateway 有一个全新的认识,并为你在广阔的 AI 世界中探索工具箱增添一个新的技术,那么我们就开始吧。 说说什么是 AI Gateway 提及工业界的实践,要追溯到 Cloudflare 在去年 11 月推出的 AI Gateway 测试版了,Cloudflare 在发布时表示,AI Gateway 可以使 AI 应用更具可监测性、更可靠、可扩展性更强。所以我们首先来回答这个问题,什么是 AI Gateway 呢? AI Gateway 也被称为大模型网关、AI 网关,是一个用于部署和管理人工智能(AI)模型的平台,在开源社区有对应技术实现。它为用户提供了一种方便的方式来部署和管理 AI 模型,无论这些模型是预训练的模型,还是用户自己开发的模型。AI Gateway 还提供了一种方式,让用户能够在需要的时候轻松地调用这些模型,例如在进行数据分析或开发新的 AI 应用程序时。此外,AI Gateway 还提供了各种工具,可以帮助用户监控模型的性能,以及进行模型的优化。 当然,除了上述功能外,AI Gateway 的特点不仅限于些,它还提供了高度的灵活性和可扩展性,用户可以根据自己的需求选择部署模型的规模,以满足各种业务需求。用户也可以根据自己的需求,调整模型的参数,以满足特定需求。 此外,由于具有对模型的权限管理及实时监控功能,加上可以缓存、重试、调整模型调用优先级等优化措施,AI Gateway 还可以保护数据隐私,稳定、高负载、安全的运行。 AI Gateway 的优势及对比 AI Gateway 和 Gateway 虽然两者不如雷锋和雷峰塔之间的巨大区别,但除了都是某种形式的关卡外,两者在服务对象、应用场景以及主要功能上,都存在不少差异。 如上文所描述,AI Gateway 是一个 AIOps 类平台,作为服务和推理提供者之间的代理,无论模型位于何处,为管理和扩展生成式 AI 工作负载提供了统一的接口。相比之下,Gateway,即传统网关,则更多地用于网络连接和数据传输,是网络连接到另一个网络的“关口”,实现网络互连,是最复杂的网络互连设备。 简单来说,AI Gateway 专注于 AI 模型的集成和管理,而传统网关则侧重于网络连接和数据传输。 AI Gateway 与直接使用大模型 大部分朋友接触 AIGC 应该都是从 chatGPT 开始的,因此,当了解到 AI Gateway 之后,难免不产生疑问,为什么我不直接用大模型呢,还要多走你调用一层?当然,chatGPT 作为一个人工智能对话程序,能够借助自然语言实现人机对话,对终端消费者已经够用了,然而,AI Gateway 作为一个 AI 模型的集成于管理平台,对于开发 chatGPT 这类服务的开发者来说,可能更具吸引力。 AI Gateway 和直接使用大模型之间的主要区别也在于 AI Gateway 提供了一种集中化的接口管理机制,使得应用程序能够更高效、安全地调用多种大语言模型,而直接使用大模型则涉及到与模型的直接交互,会涉及更多的技术细节和复杂性。此外,AI Gateway 还有以下几方面的特点,使得其相比直接使用大模型更具优势。 首先,AI Gateway 作为连接服务和推理提供者之间的代理,无论模型位于何处,为管理和扩展生成式 AI 工作负载提供了统一的接口,这便允许我们通过统一的调用方式,根据自身需要在多个大语言模型之间切换调用,以获得我们的需要。 其次,缓存 API 调用让 AI 应用开发成本更加可控与便捷。通过 AI Gateway,可以对 API 调用进行缓存,这在行业高速发展期,面对 API 调用次数快速增长的背景下,可以快速地节省成本开销以控制研发成本。 AI Gateway 也可以组合一系列技术和策略确保数据隐私,包括加密、访问控制、审计日志等,以保护用户数据不被未授权访问或滥用,达到保护数据隐私的目的。 此外,还有一些 AI Gateway 实现可以通过严格的用户认证和基于角色的访问控制(RBAC)系统,确保只有经过授权的用户才能访问和修改数据模型。这种访问控制机制是防止未经授权人员访问 AI 数据模型的关键。 应用场景与发展趋势 AI Gateway 的应用场景广泛,适用于多种人工智能应用场景,包括自然语言处理、文本生成、语音识别等,无论是个人开发者还是企业级应用,都可以从中受益。相比之下,AI Gateway 可以帮助开发者更好的管理 AI 应用及监控,同时更便捷、高效的实现对多种大语言模型的有效整合与调用,从而满足用户在各类 AI 场景下对于模型选择、策略配置以及数据安全等方面的专业需求。 作为仍在快速发展期的一项 AI 技术平台,AI Gateway 的未来仍有很多可能: 技术创新:AI Gateway 需要在技术底层,继续在提高性能和扩展性方面进行创新,以适应不断增长的 AI 模型和服务需求; 支持更多模型和服务:随着 AI 技术的进步,AI Gateway 也需要不断适配更多先进模型和服务,以满足用户对 AI 体验的更丰富的需求; 增强的安全性和可靠性:AI Gateway 需要加强安全性和可靠性功能,以保护用户数据和模型安全,同时确保服务的稳定运行; 融合更多行业方案:通过与物联网、大数据领域的融合,开拓出更多可以落地具体行业场景的 AI 应用; 写在最后 AI Gateway 在连接 AI 与各类应用中起着至关重要的作用。作为一个崭新的技术平台,它不仅提供了一种简便、高效的方式来集成和管理 AI 模型,同时也在实现 AI 技术与各类应用的无缝对接上发挥了巨大的作用。无论是自然语言处理、图像识别,还是语音合成和推荐系统等各种场景,AI Gateway都能大大提高 AI 技术的应用效率和便利性,从而推动 AI 技术的广泛应用和快速发展。 面向未来,不论是更大范围的 LLM 支持、更精细的查询加速与缓存机制建设、更全面的应用监控与安全防护策略,还是应用层更便捷的操作和低使用门槛,都是 AI Gateway 可以继续努力的方向。 参考 https://blog.cloudflare.com/zh-cn/announcing-ai-gateway-zh-cn https://github.com/Portkey-AI/gateway

2024/6/27
articleCard.readMore

冬日打车日记

今晚打车,司机停在一个靠近上车点拐弯口的路边,一直没开进来,期间他一直跟我站内信确认“出来了吗”,我和往常一样,快速回复说我就在定位点等他。回复完,貌似司机也没有动弹。 过了一阵他发来消息,问我能不能出去找他。他给我的理由是门口不让他开车进来。由于天气特别冷,我不太想动,于是文字回复他,“车子需要绕商场一圈才能进来,入口那是单行道”。回复完,对话框又陷入了沉默。 其实没有啥事,但我就是有点急,于是主动问他,到底是我出去找他还是他开进来,我说我可以出去,让他告诉我上车点。隔了一阵,他回复我,“我进来找你”。 由于绕行进来的这段路在下班点很堵,于是我又回到了室内大厅,那里会暖和点。期间我还在跟家人打电话,聊天过程中我带着一丝抱怨的语气提到,今天这师傅感觉对路不熟使我在外面等了很久,冷死了。 / 我期间也有一丝疑惑,司机跟我文字沟通这么多,为什么没直接打电话直接问我呢。过了好一会,车终于来了,我照常报了一下手机尾号,就全程沉默,直到快下车。 我发现临近目的地,司机还没有要停的意思,于是我赶紧说已经到了,但他似乎没听到,车仍旧向前多开了一会儿。 收拾好行李,正当我开门下车时,我发现他半侧着转过身来,双手合十,面带微笑,反复对我点头示意。 啊,我才反应过来,原来他是一个聋哑人。 / 在互联网企业工作久了,貌似自己的耐心都被削弱了不少,针对一些看似不寻常、不高效的事情,我甚至会在缺少观察和理解的前提下,直接下意识的设定立场与抱怨,不知道司机师傅有没有感觉到我的不耐烦。 从防止资本无序扩张、加速信息茧房、奶头乐理论到拉大贫富差距,互联网企业这些年一直没落得个好名声。但我想,他确实通过不断推出创新产品,给人们的生活带来便捷,从线上聊天、手机购物、扫码支付到方方面面,这都在深切的改变着我们的生活。线上打车不就给予了先天残障人士另一种更体面、适当、不风吹日晒的赚钱方式吗? 所以,互联网还是挺好的。

2024/1/27
articleCard.readMore

基于一次应用卡死问题所做的前端性能评估与优化尝试

问题背景 在上个月,由于客户反馈客户端卡死现象但我们远程却难以复现此现象,于是我们组织了一次现场上门故障排查,并希望基于此次观察与优化,为客户端开发提供一些整体的优化升级。当然,在尝试过程中,也发现了不少适用于通用前端项目开发的一些故障排查与性能评估的手段,于是总结此文,希望可以对读者有所帮助。 需要注意,在本文中所指的客户端均指通过 electron 开发出来的客户端应用,所以本质上还是属于前端应用开发范畴,关于 electron 框架的介绍可以参考 https://www.electronjs.org/ 现象复现 在客户那边,反馈过来的现象表现为“系统 CPU 资源未被占满,但客户端在操作一段时间后便卡死无法响应”。起初,我们根据用户的描述尝试在本地复现,但却没有收获;此外,由于客户的网络限制,也不方便频繁的远程连接以方便我们查看现场现象。 考虑到可能是机器部分配置较差(比如显卡)或者网络、机器自身运行软件过多等原因,而我们的开发机器由于要支持本地编译与调试,一般都是顶配机器,于是我们尝试让本机变慢,以模拟复现其现象,简单来看,存在如下几个思路: 卡死/卡顿复现:最好在虚拟机中操作,虚拟机本身分配资源相对主机较少,再加上 chrome devtools 配置增加延时 throttle 时长,比如500ms;电脑中再开启几个占用 CPU 性能的软件,比如 vscode,firefox 等等,可以一定程度上模拟卡顿现象,不一定稳定复现卡死现象; 操作卡顿复现:通过频繁的交互操作,制造同时多个请求并发发出的现象,加上 performance 录制,可以一定程度加重渲染进程的负担,以模拟操作卡顿现象; 定位问题 来到客户现场,作为首要尝试,当然是通过 top 、netstat 或者 cat /proc/cpuinfo 等命令来查看系统的 CPU、内存与网络的运行状态,但不出所料,这些信息在当前看来并没有太大异常。 由于从系统本身的一些状态上没能找到突破口,我们将目光转向客户端本身,希望在更小的范围内定位问题所在。通过 devtools 查看 netowork、performance 以及 DOM 渲染状态,我们只能发现貌似有些响应耗时过长的接口调用以及较长时长的 long task 任务,这当然需要我们进一步排查。 说到调试排查,首推的当然是 console.log 大法,为了让 log 打印复用,一个简单的技巧是写一个 HOC,以节省在每个地方都写一遍 debug log 的代码: export const debugRender = <T=any>(BaseComponent: FC<T>) => (props:any) => { console.log(`Rendering ${BaseComponent.name} at ${performance.now()}`); return <BaseComponent {...props} />; } 通过添加一些基于经验的断点信息打印,我们发现一些 Modal/Drawer 的显示/隐藏会较为明显的加重页面卡顿甚至到卡死现象上,通过排查代码实现以及查看对应 UI 库的 API 实现,会发现其中 Modal/Drawer 等组件上在隐藏时触发了其对应 DOM 节点的卸载,而在显示时又会重新渲染与插入,由于这些任务都需要在浏览器的渲染进程执行,而当 DOM 节点过多时频繁的节点装载与卸载便会对页面渲染效率产生影响。 于是,第一步便是定位到主要的几个组件,避免其在隐藏时执行 DOM 卸载(保留节点),通过这一步改变,我们直接消除了卡死现象。 部分优化尝试 为了更好的模拟卡顿现象,我们可以通过 chrome devtools 中 performance tab 中的 CPU throttling 配置来模拟卡顿: 在 Windows 高配版机器上,我们先将 CPU 降低配置 4x 情况,然后录制一段操作,从下图中可以看出有明显的任务执行耗时过长 & CPU 占用过高的现象: 以耗时最长的任务中占用时间最长的活动为例,我们搜索一下该关键词可以查到一个讨论 https://stackoverflow.com/questions/39916356/reacterrorutils-invokeguardedcallback-in-react-fires-event-repeatedly-in-ie-brow,简单来说,我们可以尝试优化点击事件不进行冒泡来减少事件的触发,例如: event.stopPropagation(); 通过优化该事件,我们可以一定程度上对事件在 DOM 上的传递 & 调用进行优化,但说到交互事件模型,我们在实际优化尝试时,也需要对 Web API 有些了解,以防用错 Web API 而南辕北辙,比如一个常见的面试题就是对比 Event 上暴露的两个 API stoppropagation 与 stopimmediatepropagation 的用途区别,可别用错了。关于此细节可以参考回答 https://stackoverflow.com/questions/5299740/stoppropagation-vs-stopimmediatepropagation 但假如我们需要针对不同事件切换不同的 API 该怎么办呢,这里可以简单写个函数封装一下,再加个类型守卫来实现,比如如下的伪代码通过传入一个点击回调事件,而后在实际事件触发时通过判断 Event 类型从而调用不同 API 以达到优化效果: const isMouseEvent = (event: Event | MouseEvent): event is MouseEvent => 'stopImmediatePropagation' in event export const stopPropagationWrapper = (handleClick: Func) => (event: Event | MouseEvent) => { if (isMouseEvent(event)) { event.stopImmediatePropagation(); } else { event.stopPropagation(); } handleClick(event); }; 我们继续针对卡顿问题的调用情况进行梳理。从录制的执行队列中选取较长的一个 long task 进行分析,可以看到在模拟卡顿时排名靠前四的调用任务分别如下: 其中 fsync 函数调用时间占第一,而拆分 fsync 的活动调用可以看到主要调用了 fsyncSync: 此处未对 fsync 进一步分析以确定优化策略,但对于 fsync 的作用可以参考如下一段描述: fsync 函数只对由文件描述符 filedes 指定的单一文件起作用,并且等待写磁盘操作结束,然后返回。fsync 可用于数据库这样的应用程序,这种应用程序需要确保将修改过的块立即写到磁盘上。 这说明应用中有可能有数据库读写操作,也可能有文件读写操作,所以如果要进一步优化的话可以从这个方面展开,囿于时间限制,我们继续探索可行的快捷优化方案。 在最初解决卡死问题时,我们看到了过多的 DOM 卸载/挂载现象,但回到前端框架本身,我们也可以用一些常规的手段来减少组件不必要的 rerender,这些方案通常通过仔细阅读 React 文档便可以略知一二,比如在必要的地方增加 memo 以减少不必要的渲染执行,一个示例代码如下: import { FC, memo, } from 'react'; const Detail: FC = ({}) => { return ( <div>Detail</div> ); } export default memo(Detail); 此外,还有什么写法可能会影响 Web 应用的性能呢?闭包。 我们检查了客户端代码仓库里的两个列表文件,发现其中组件包含过多闭包变量,大多数写法是在一些函数定义中直接从上层作用域引用了一些变量进行操作,而不是通过参数传入函数,这样的数据/函数在使用后无法及时释放内存空间,可能会对内存存在持续占用的现象,因此,这也是优化的方向之一。 后续可能的优化空间 在一些 long task 任务的分析中,我们还可以具体定位到代码来进行优化,这里再举一个例子。 通过录制卡死情况下的堆栈调用情况,可以发现有一个 2.7s 任务中包含很多活动,如 Minor GC、react event、fsync、ReactElement 等等,其中 mergeProps 函数调用耗时250+ms。 针对这些函数调用,有些可能是 React 内部实现 API,有些可能是 UI 库 API,所以要想一一优化,也需要逐个分析,看是优化代码的调用与响应方式,还是合并组件 props 的传递与调用。 此外,通过监控 layers 变化情况,也会发现一些 slow scroll rects,这在 chrome 中都会通过红色区域以标注出来,通过定位这些在滚动中可能会造成缓慢的区域并检查代码,也有提升应用性能的可能性,因此,也是优化方向之一。 比如针对我们的场景,通过调整 layer 布局,可以看到虽然 layer 层级很多,但是主要的 slow scroll rects 区域还是集中在主内容区,即分页列表本身。 Electron 注意事项 本来,为了可以针对这些数据进行持续的分析,想从 performance 中将数据下载下来,以便之后有空时继续调试,但由于 Electron 的某些限制或者说是错误,我们目前无法保存 performance tab 下的性能数据到本地以便进行更深入的分析和查看。如果有涉及到 electron 开发的场景,需要注意下这个问题。问题现象详见 issue https://github.com/electron/electron/issues/39818 优化效果 为了提高客户端的性能和用户体验,我们进行了一系列的优化措施。首先,我们分析了卡死现象,包括客户端出现卡死时的 CPU 占用率/JS 堆栈/DOM 节点数情况、虚拟机运行状态等。然后,我们尝试了一些优化措施,如去除Modal/Drawer的 unmountOnExit 配置等。接下来,我们梳理了卡顿问题调用情况,分析了排名靠前的四个调用任务。为了减少组件不必要的rerender,我们在必要的地方增加了 memo。此外,我们还提到了组件中包含过多闭包的问题,以及右键菜单卡顿问题的排查。 由于客户端需求迭代过快,在前端技术上没有做较多的数据监控、性能评估等建设,这都对我们评估用户体验与定位问题产生了影响;此外,由于生产工具链的不完善,在生产环境进行定位与调试都给我们带来了比较大的挑战与时间消耗,这也会是我们持续要跟进与解决的一些开发链路的效率提升工作之一。 通过这些优化,我们希望能够解决客户端卡死问题并改善卡顿现象,并提高用户的使用体验。当然,从具体效果上来看,我们确实在如下两个方面进行了改善: 交互性能上,问题页面在切换时,即便将 CPU 降低配置 4x 情况下也再无出现卡死现象,卡顿现象有减轻趋势; 渲染效率上,从数据上看,频繁出现的 500ms-700ms long task 已减为当前观察范围内没有超过 300ms 的 long task,代码执行效率上有较大提升; 以下为优化后效果采样图: 简要总结 通过分析与优化尝试,我们解决了客户端卡死问题,并改善了卡顿现象,但其中暴露出一些编程规范与用法不够优雅的问题还需要在日常中持续完善,这也是这次优化未尽事宜,需要在未来不断排期以彻底解决。 当然,此中涉及到的一些调试与问题定位方法,也不仅局限于客户端的问题排查,而是通用 Web 应用性能评估时调试可以用到的手段,而更深入的研究则要开始涉猎到框架代码等内部函数调用的地方了,这也是本文未涉及部分,有待后续继续研究与定位。

2024/1/3
articleCard.readMore

2023年终总结

这一年里充满了各种变化,也有不少东西值得记录,比如令人满意的健身打卡,逐步调整的投资仓位,以及通过阅读学习和出行游玩收获的喜悦。 但当我准备动笔记录今天的忙碌故事时,却突然感到思绪断片,不知从何说起。他们就像一段段孤立的片段,突然间收起了各自本该伸出的突触,毫无关联。让我努力编织下,希望可以拼凑出一个完整的年度回忆。 一顿操作猛如虎,最后像个二百五 虽然本就没几年经验,但在我的投资生涯里,很早便认可了“投资是自我认知的变现”这一投资信条。面对年复一年地亏损,我一直保有谦逊的态度,认为这是我对事物认知不够的结果,也是我所需要交的学费。年复一年,而我却越挫越勇。每当我收到工资时,我首先想到的是”我有钱可以增加投资了”,直到钱花光,然后我又开始努力工作,等待下个月的薪资。不断地增加投资,不断触及新低,让我不禁感叹,我自己就是那个最健康、拥有永续现金流的优质资产(在中年危机被裁员之前)。 在不断学习的过程中,我尝试过使用美林时钟来辅助我在当前世界的变化中调整不同资产的投资比例;通过关注恐惧贪婪指数、北上资金动向以及全市场成交量来控制我的资金进出节奏;还构建了自己的价值评分系统,用于评估购买资产和确定应对策略。可惜,直到最后都逃不过“一顿操作猛如虎,最后像个二百五”。 但这并没有阻止我对投资越来越沉迷。今年,在各种空闲时间里,我仍然花了大量时间阅读书籍、观看纪录片与调整资金进入策略,也主要补齐了对2008年金融危机及欧债危机期间世界各国发生的事情与各大央行的应对策略,而对这些历史事件的了解,也让我对当前发生的许多时事有了更敏锐的感触。当然,最深刻的印象仍然是通过真金白银的投入去理解和观察这个世界究竟是如何运行的。 投资是生活的投影 尤记得刚接触投资不久,我便困惑于两个问题,他们是如此明显但我却找不到答案,以至于我开始怀疑自己的信息检索能力。 “为什么有很多关于价值投资的声音都在介绍通过定投降低风险与长期持有,但却很少提及何时卖出与落袋为安?”,这让我很不解,涨的再多,没有在合适的时机卖出,也没法落袋为安啊。而后来,随着“核心资产”泡沫的狂欢在2021年春节后戛然而止,伴随着飞流直下三千尺式的暴跌,那些宣扬十年定投赚十倍之类的响亮声音也从市场上消失了。我逐渐开始明白,这并不是因为市场没有这类声音,而是我一直追逐的都是“跟风”和“主流”,而不是真正的“价值”。 另一个问题,从我开始规律地研究公募基金定期报告以来,无论是谈到跨过刘易斯拐点带来的挑战,漫长的三年疫情带来的创伤,还是面对欧美的科技封锁与孤立,基金经理们貌似都一直坚定地看好中国。我很好奇,这个国度究竟有什么是世界上其他国家所无法企及与不可替代的吗?后来我发现,原来股市是不可以做空的。 再后来,我所遇到的问题也越来越多,但一个个也在不断的探索与学习中得到了解答。虽然我相信权益类资产在长期来看会是最有吸引力的投资标的,但离钱越近的地方聪明人也就越多,这就意味着我需要长期投入、学习与进步。投资就如同生活的投影,预设目标,不断努力、尝试,达到目标、总结与规划,如此反复,而这也是他一直吸引我的原因所在。 为了前方的未知与愉悦,直到最后一页 一本书可能很厚,但一纸书页很薄。每一次翻页都如同一程短暂的摆渡、一场微小的跋涉,身后欧律狄刻的目光仍未消散,远望伊西斯的面纱已然显影。 这是在今年世界读书日,给读者推送我的书摘时,从豆瓣上摘抄的一句话。以前,不论是地铁通勤,还是周末进城,抑或是出远门见朋友,我都时常手捧一个 iPad 会看上几页,就这么零零星星地,每年能看上几十本书。但今年因为运动打卡挤占了原有的时间,加上工作强度增加,以及频繁跑医院,少了很多碎片时间,分配给读书的时间也有所减少。有鉴于此,周末没事时,我时常花上整个整个的半天,用来阅读。期间去过几次图书馆,一呆就是一个下午,除了接水也不起身。安安静静的,啥也不做,就盯着屏幕,希望从字里行间收获快乐。 虽然从时间上相比去年有明显减少,但今年的收获仿佛更加实在,说说几个比较贴切的例子吧。想起年初去医院看病,为了治疗痤疮,前后一共吃了好几个月的药。后来,在阅读《皮肤的秘密》时,我对许多现象以及对待皮肤问题的方式有了新的领悟。当我们的皮肤状况变差时,真的需要那么多昂贵的护肤品来挽救吗?也许不是,也许只需要一些药膏就能解决大部分问题。当然,更重要的是我们不要过度清洁皮肤,保持规律的作息习惯。 当然,由于对身体机理运作以及病菌原理感兴趣,我又淘到了一本《我们为什么生病》。在阅读时,不仅有“疾病不是因为我们弱,而是这个世界有些东西变化太快了”的感慨,还在豆瓣偶遇到张一鸣同学的书评“其实进化论强调:你看到的是结果”。阅读之后,虽然对于癌症、衰老、过敏以及身体机理应对自然变化的机制有了更多了解,但更现实的是,我逐步认识到了时间对世间万物的一视同仁:不论君王庶民,我们都无法与之对抗。在时间面前,我们无论做些什么都无法避免衰老、死亡,而这引发我对生命存在的意义更具象的追求。 经济类书籍每年都必不可少。对经济危机与大萧条研究颇深的伯南克在《行动的勇气》中详细描述了自己在美联储工作的那段经历,从房地产泡沫破裂到雷曼兄弟的大坝决堤,及其引发的全球金融系统崩溃等事件,事无巨细,同时也花了很大篇幅揭示他与保尔森、盖特纳一起协力、果断扑火的各种努力。从全球合作到最终退出量化宽松政策,伯南克感慨到自己还是做了不少努力并卓有成效,他最后为美联储在危机之后所作的努力总结道: 我意识到金融冲击往往是不可预测的,因此还鼓励幕僚们寻找金融体系的结构性弱点,想办法使它更有弹性。这个想法已经体现在了我们的许多改革中,比如要求更高的银行资本充足率,提高银行体系吸收损失的能力。 每当阅读此类书籍,都会让我对世界上各种复杂、高级别的组织更加了解,而满足这些好奇心也是促使我坚持阅读的一大动力。为了前方的未知与愉悦,直到最后一页。 怀旧、养生与散步,是提前步入老年生活的主旋律 作为一个准奔三青年,我仿佛变得越来越怀旧了。还记得从上大学之后开始就再也没看过快乐大本营这类综艺节目了,但今年却一股劲又盯上了很多芒果台的综艺,而且还是反复观看。从时光音乐会到声生不息,从宝岛季到家年华,我发现我非常偏爱音乐类节目。很多耳熟能详的老歌,再配上我“听歌很少关注歌词,而只享受旋律”的习惯,当那一阵阵旋律响起时,仿佛把我又拉回到那些历历在目而有印象深刻的故事中。 今年养成的习性不仅怀旧,而且养老。今年我还尤其喜欢逛公园,奥森、颐和园、北海公园、圆明园、什刹海以及各色大大小小的北京园子都被我逛了个遍,一是趁着天气晴好看看应季花景,再者也是与许久未见的朋友散心聊天、联络感情。 当然,除了养老之外,我还异常养生。我跟朋友说起我每天的生活时,他们都觉得我已经是个新时代的合格健康老头了。每天上班第一件事便是到茶水间泡一杯热茶,按时吃饭,以及没有意外时会规律的去健身房转转练练,晚上也尽量避免熬夜,一有点啥问题也会跑到医院抓个医生问个究竟。周末呢,要没啥事,就到楼下超市买个菜回来做饭,虽然不是什么复杂菜品,但那些健康而平淡的家常味道,已经让我感到非常满足。 刚说到今年经常跑医院,如何形容这个经常呢,我统计了一下截止今天的医保支出,一年23000+,这还是在没有什么大病的基础上的花费。仿佛年龄越大,就越怕死,今年的我,时常因为一些小毛病而频频往医院跑。虽然确实有一些值得一看的小病,在遵循专业医师的建议与处方下,也让自己变得稍微健康一些、好看一些了,但不可否认,还是有一批是来自“怕死焦虑”的变现。上个月我刚体检完,报告上标红了五六项,我辗转反侧,无法理解为什么坚持锻炼的我还有这么多毛病,于是,几个三甲医院一顿约,主任副主任医师一起抢,我一定要搞出个究竟来。不过到头来,好几个科室的医生面对来自我“如果这不是问题,那为什么我有别人没有”的有罪推论式发问,都不耐烦的回复“不要过度焦虑,这些只是个人差异,而不是病症”,终究还是让我宽心了不少。 说到健身,最让我自豪的便是今年里在大部分时间我都持续着高强度的锻炼节奏。从每天游泳打卡,到下班后跑步,以及在同事的辅导下开始器械训练,年末时也参加了几节团课训练。每次运动完,都能明显的感觉自己的状态好了一些,而要不了多久,便又开始期待下一次的健身打卡及其带来的快乐。想起前几天看到一位投资者面对记者采访时说到,因为自己前一天熬夜状态不好,希望摄影师用一些“手段”将自己拍的更得体与优雅些,“一个好的状态与形象,既是对自己、也是对观众的交待”,这是他给的理由。逐渐沉溺于健身的我,非常认同这番话(当然,只是自己长得丑,和他不像而已)。取悦自己,找到自己愿意去做的事情,仿佛是一个奔三青年眼前最重要的事。 冲破黑白灰的人生单色调 今年的我不仅变得异常怕死,同时也希望对自己查漏补缺。今年,我预约过几场心理咨询,也从中获得不少收获。探寻自己在家庭沟通上的一些失控情绪表达,找到内心潜在的一些心理缺陷并尝试修复,而这些都是我以前不曾涉足的领域。 我从原生家庭继承了一些执念,而时常又不自觉将这些执念寄托回他们身上。由于自己的认知仍在不断拓宽,一些强行灌输给他们的想法,在没有得到妥善处理时,便引发了不可避免的矛盾,这通常体现为我的大声说话与争吵。今年看的一本书《原生家庭》,帮助我对亲密关系以及性格缺陷有了更本质的一些理解,虽不至像书中一些案例一样中毒过深,但自己的成长或许也有从原生家庭习惯中隐性的吸到一些“毒气”。他们可能在生活的一些方面上具有闪光点,但却因为用力过猛而导致在其他一些方面上造成失控。与好几个朋友聊天时,他们对我都有相似的形容——能在工作上所向披靡,但回归生活发现很多事情都没有规划和过多想法。而在心理咨询后,我的这种行为被具象成了“由于无法得到满足,而对某些关系进行转移与嫁接”这样的标签。 年中出差成都,约了一个从小玩到大的朋友见面,我们聊了很久直到深夜,差不多绕着成都的高新区转了半个圈,期间探讨了很多事情,包括工作、未来发展、定居以及生活的方方面面,但在最后,他给我了一个标签,“你确实活得非常自律、严谨,就像个机器人,仿佛你的生活里只有黑白灰这三种颜色”。 我一时不知怎么接话,因为他说的确实在理,我只能笑笑,随意找了个借口回应道:“我确实没有什么物欲啊,很多人喜欢通过花钱来达到满足感,但对我不太适用;当然,投资亏钱除外。至于为什么要赚钱,一方面是为了‘安全感’,另一方面呢,也算是一种获胜的姿态吧,可以满足我的好胜心”。 就是这么一个黑白灰人格,既对亲人如此关心甚至到有些焦虑,而又对自己无欲无求、活得过于机械化,这也成为我要在新的一年去努力攻克的课题之一。 写在最后 今年因为经常挂到医院一大早的号而早起,但也因此看到很多往常不曾见到的风景。阳光从树梢穿过,零星撒向地面;骑着单车,听到林间鸟叫、看到小区晨起锻炼的人儿;迎面与一个个充满朝气的少年相遇,从他们眼里真的能看到光。这是令人向往的风景,便也为此努力奋斗。 一点一滴,日积月累,这既是果实,也是漫漫人生。季节更替、时间流转,也望诸君可以缓慢而坚定地前进,去做自己能做的事情。新的一年,好好吃饭,好好锻炼,好好生活。

2023/12/24
articleCard.readMore

结合 React Fiber 结构与 chrome 插件,谈谈无侵入自动化表单的技术尝试

本文亦有分享 Slides,详见 https://hijiangtao.github.io/slides/s-Common/Technical-Attempt-of-Non-intrusive-Automated-Forms-with-React-Fiber-and-chrome-plugins.pdf 或扫二维码查看。 前言 作为一名前端工程师,不论你处于什么业务方向,肯定都与表单打过交道,当然如果你是服务端、产品、测试同学,想必也早已接触过表单这类场景。让我们试想一下,如果研发需求的功能测试依赖一个复杂表单的填写而得以继续,那么频繁的表单填写在研发自测和 QA 验证过程中就会占用过多碎片化的时间,此类需要频繁执行以生成测试数据或推进执行流程的事情,简单一想貌似规则可循、可以被工具替代。既然可以自动化来实现,那为什么还要我们一个个手动点呢? 不要着急,这篇文章的目的,就是想与大家分享一下这样一个自驱型技术产品的诞生故事。这其中既包括技术与实现细节,同时也涵盖这个产品的设计过程。 问题初探:表单场景究竟麻烦在哪 首先,让我们来看看表单,到底麻烦在哪了。 从前端开发者视角看去,表单是由一个表单组件包裹多个表单控件组成,用 JSX 语法层层嵌套实现,当需求开发完成后需要自测时,最直接且简便的用法当属用 initialValue 属性或者 form 实例上提供的 API 方法(比如 setFieldsValue API)来赋值;但是等代码部署到开发/测试环境,想要这么灵活的变更初始数据就不太可能了,频繁的发布部署流程会让变更测试成本直线上升。 另一方面,在产品测试等同学的眼中,表单并不涉及到代码形态,只是一个有很多输入项的丰富 UI 页面,通过点击、输入、选择等操作,来完成数据的输入,是一个需要消耗一定时间的流程。而当表单项很多时,花费的时间也直线上升。 通过抽象,我们可以列举几个从前端角度观察到的例子,以方便我们更熟悉填写表单时涉及到的各类复杂场景: 对接完产品需求,终于把字段与各类逻辑组装进表单,想自测看看交互效果,简单来做,可以代码写一些 mock 拦截来实现 功能提测后,为了测试新功能,需要先填一遍复杂表单,造数据,但这个时候 Form 里嵌套 FormList,完成功能开发就用了很久了,现在造数据还需要再来一遍 每次填写表单,由于某个字段是存储主键,每次填写不能完全一致,即在特定规则下随机生成一些字符串,可能是年龄、中文姓名或者邮箱等 登陆态过期太频繁,一过期就要重新输入用户名密码再点击按钮登陆一遍,当然,现有的工具中我们可以通过 chrome 的记住密码来实现,但我们仍然需要在填充完成后点击确定按钮进行登录操作 总结来看,以上这些场景按照用途可以汇总成以下几类: 研发功能开发自测 测试数据构造 符合规则的个性化填写 日常操作,比如登陆 技术调研:开源社区与插件是市场的已有技术实现 在明确了需求之后,在是否需要动手之前,我们需要先调研看看有没有现有技术或者工具可以帮助我们达到目的,毕竟,反复造轮子在哪里都是被抵触的。开发工具的目的是为了解决问题,如果问题已经有了解决方案,我们就不需要自己去实现了。 回顾一下表单需求,仔细想想,可能存在几种解决思路呢?首先是辅助工具,比如浏览器插件这种,作为业务开发无感知,无接入成本(无侵入式)的技术方案,其特征也显而易见: 不依赖 UI 框架,通用性强 无需具体业务感知,对业务代码无侵入,接入成本低 识别与填充成功率低,支持控件有限,尤其在当下很多 UI 库针对不同表单控件会有自己的实现(以及事件拦截),只能支持简单的 input 框以及一些 radio 场景 随机 mock 数据能力有限,在自定义规则集中生成 不支持页面上表单与事件连续操作,比如派发表单填充后的点击行为 既然无侵入式方案能力有限,那么做些侵入式改造是不是会更加有用呢?比如,通过约定 url 传参或者业务代码内嵌入开关,来允许用户显式控制代码的执行逻辑,这样用户可以在打开页面时对表单做指定的赋值操作,对实际点击行为后触发的回调函数进行调用,这是一个大概的实现思路,其特点罗列如下: 基于具体表单结构定制,通用性弱 完美填充,支持全部表单控件 不支持页面上表单与事件连续操作 填充数据变更时需重新打包,成本高昂 由于辅助工具和侵入式改造都或多或少有些缺陷,熟悉自动化测试的同学肯定会说,这些要做的事情,自动化测试方案不是早就覆盖了吗?是的,自动化测试方案是一个完美的解决方案,基于 puppeteer 或者 e2e 框架,不仅方案通用性强,填充也很准确,但是从开发者以及使用者的便利性角度来看,基于这类方案用户在上手使用时存在成本,研发要实现对应功能成本也相对较高。还记得初衷么,我们是希望有一个可以解决表单场景的工具,我们既希望他能解决一些复杂场景的问题,同时也希望他简单易用成本低。 回顾一下,我们调研过的几个实现思路,能不能把无侵入式改造与高识别率结合?即“取其精华,取其糟粕”。 需求拆解:我们究竟需要一个怎样的工具 做完现有技术调研后,我们来将需求做拆解,从远期来看,我们当然希望有一个不侵入用户代码,却可辅助用户自动化识别页面内存在表单、支持用户自定义 mock 规则生成表单数据进行填充的工具,来帮助我们在各类表单场景中提效。 具体来看,我们将需求细化,希望覆盖这么几个场景: 接入零成本:开发者不用对当前业务代码做任何改造,零代码侵入便可使用 表单准确填充:当下很多方案基于 DOM 解析与处理进行实现,通过这类方案进行表单填充,会因为组件库自身实现做了事件拦截或者托管,而导致表单填充很多情况无法生效的情况,而用户在意的大多数字段却无法触发 表单准确识别:准确获取与开发者完全一致的表单结构,防止 DOM 解析不准确的情况,大多数工具只能解析简单的 input、radio 等场景 填充内容自定义:支持 mockjs 类语法对填充数据进行自定义构造 支持事件派发:在登陆场景下,一般除了填充表单外,还可以直接替用户点击「确定」进行登录操作,工具支持增加事件派发,将表单填充和点击等事件一体化流程处理 拆解了需求,就可以规划一步步来实现,将产品需求做成一期、二期不断迭代的交付节奏,我们在这一块遵循和正常产品研发相同的节奏。第一步,当然是识别表单结构,因为只有准确识别到表单,后续的数据构造、表单填充、事件派发才有意义。 技术方案:如何准确识别表单 怎么识别才准确呢?侵入式的方式肯定是最准确的,但我不能每个组件都包一个 wrapper 吧,如果一个项目有100处表单的调用,那我就需要做100次改造,而且从前面的调研来看,我们还是希望从无侵入方案入手,因此,如何提高无侵入识别方案的准确性,成了一个需要攻克的难题。这个时候,让我们先来看看一个面试常被问到的点,从 React Fiber 说起。 我们都知道,Virtual DOM 是对真实 DOM 的模拟,也是一棵树,通过 Diffing 算法和老树对比,得到差值,再同步给视图要修改哪些部分。Fiber 是对 React 核心算法的重构,Fiber 对象是一个用于保存「组件状态」、「组件对应的 DOM 的信息」、以及「工作任务 (work)」的数据结构,Fiber node 是 Fiber 对象的实例。 先不看 React Fiber 树的实现方式,如果我们自己来实现一遍,大抵会想到两种思路:数组或者链表。数组的组织方式可能更符合我们的直觉,但是想一想在这个树如果我们要查找遍历、调整结构(分割、替换节点)或者随时重建新树,链表的方式似乎更加灵活,事实上,React 也是这么做的。 Fiber 树的组织与遍历 我们先整体来看一下遍历过程。Fiber 树的遍历需要一个指针指向当前遍历到的节点,workInProgress 就是这个指针,进一步是 performUnitOfWork 的 next 指针,遍历在指针为 null 的时候结束。 next 先从 beginWork 获取,如果有则直接将当前遍历的指针 workInProgress 指向 next;如果没有,就到 completeUnitOfWork 中进一步处理。这里 beginWork 是“递”,即不停向下找到当前分支最深叶子节点的过程;completeUnitOfWork 是“归”,即结束这个分支,向右或向上的过程。 关于 performUnitOfWork 的更完整代码详见 https://github.com/facebook/react/blob/c1d414d75851aee7f25f69c1b6fda6a14198ba24/packages/react-reconciler/src/ReactFiberWorkLoop.new.js#L2051-L2077 在递归过程中,beginWork 过程比较简单,大体上是在深度优先搜索中,对遍历到的节点进行 component 更新处理,然后返回第一个字节点,这里就不介绍,我们看看 performUnitOfWork 的具体逻辑。 在“归”的过程中,我们需要避免遍历造成死循环,即若我们向下遍历时遇到的节点,在向上过程中出现时,我们不应该让其再次进入 beginWork。 completeUnitOfWork 内部又创建了一层循环,搭配一个向上的新指针 completeWork,然后循环该指针节点,如果有兄弟节点就更新当前遍历到的节点指针,返回交还给外层循环;没有就向上到父节点继续循环,直到新指针为空(即已经到达根节点);最后再处理标记最顶层的根节点处理状态。 关于 completeUnitOfWork 的更完整代码详见 https://github.com/facebook/react/blob/c1d414d75851aee7f25f69c1b6fda6a14198ba24/packages/react-reconciler/src/ReactFiberWorkLoop.new.js#L2173-L2271 整个遍历流程示意图可以参考《如何理解 React Fiber 架构? - 几木的回答》中的贴图 Fiber 树的构建与 Diffing Fiber 树是边创建边遍历的,每个节点都经历了「创建、Diffing、收集副作用(要改哪些节点)」的过程。其中,创建、Diffing要自上而下,因为有父才有子;收集副作用要自下而上最终收集到根节点。—— https://www.zhihu.com/question/49496872/answer/2517859568 在 React 中,同时最多会存在两颗树,一个是当前被渲染出来的 Fiber 树,称为 current,另一个是正在构建的 Fiber 树,称为 workInProgress,上文中提到的遍历均在后者身上进行。 找到两棵任意的树之间的最小的差异是一个复杂度为 O(n3) 的问题,React Diff 算法通过一些假设,最终达到了接近 O(n) 的复杂度。 这里提到的假设主要包含以下几点: 假设一:不同类型的两个元素将产生不同的树,遇此情况时 React 会拆卸原有节点并且建立新的节点(触发重建流程)。 假设二:默认情况下,在 DOM 节点的子节点上递归时,React 只会同时遍历两个子节点列表,并在存在差异时生成一个更新操作。 假设三:用户给每个子节点提供一个 key,标记它们“是同一个”,在有 key 的情况下能保证二者都复用仅做移动,但无 key 就会造成两个不必要的卸载重建。 副作用与收集过程 Fiber 树的构建以及 Diffing 都是同时进行的,不是说构建完 Fiber 树之后再开始 Diffing 寻找差距。同样的,两棵树 Diffing 的过程中,就已经决定了哪些旧节点需要复用、删除、移动,哪些新节点需要创建,这些操作会以 Effect 的形式挂到节点上,他们随着 Diffing 过程同步完成收集。 由于需要保证所有后代节点的副作用信息,副作用的收集有两个约定: 副作用是向上收集的,每次在 completeUnitOfWork 中循环经过一个节点时,会同时合并后代节点的 effectList 以及自己的 effectList; 副作用同样采用链表的方式存储,并通过 fisrtEffect —> nextEffect —> lastEffect 的关系串联起来,但此链表与 Fiber 树的链表结构没有关系; 关于副作用以及 Host 实例更新的更多细节,本文不再深入,此时,让我们重新回到最初的目标,即识别表单上来。 利用 Fiber 识别表单 关于 React Fiber 相关的知识补充,我们就讲到这里。接下来,我们看看如果利用 Fiber 来识别表单,这主要分为三步: 从 DOM 中找到目标 form 元素 获取有效的 Fiber 实例 读取目标属性值,解析表单结构 下方代码解释了我们如果从指定 form 元素中提取 Fiber 实例的过程。 /** * 获取 Fiber 实例 * @param dom * @param traverseUp */ function getFiberInstance(dom: HTMLElement, traverseUp = 0) { if (!dom) { return null } const key = Object.keys(dom).find((key) => { return ( key.startsWith("__reactFiber$") || // react 17+ key.startsWith("__reactInternalInstance$") ) // react <17 }) const domFiber = dom[key] if (domFiber == null) return null // react <16 if (domFiber._currentElement) { let compFiber = domFiber._currentElement._owner for (let i = 0; i < traverseUp; i++) { compFiber = compFiber._currentElement._owner } return compFiber._instance } // react 16+ const getCompFiber = (fiber) => { let parentFiber = fiber.return while (typeof parentFiber.type == "string") { parentFiber = parentFiber.return } return parentFiber } let compFiber = getCompFiber(domFiber) for (let i = 0; i < traverseUp; i++) { compFiber = getCompFiber(compFiber) } return compFiber } 当我们拿到 Fiber 实例后,那么 UI 库的部分属性就可以通过 Fiber 实例暴露出来,比如 setFieldsValue 等,此时,我们即可以轻松的拿到表单本身的结构,此部分暂略。 工具完善:构造数据与表单填充 我们再来回顾一下,对于表单来说,我们都需要构造些什么数据来作为填充数据: 固定取值:填入,每次填入相同值即可,无需特殊处理 规则取值:每次填入的字段都需要取一个符合相同规则但取值不同的数值 指定集合:针对单选、多选等场景,需要从指定选项中随机选取一个填入 时间取值:在有效的时间范围内随机生成一个时间串 布尔取值:checkbox、radio 等组件实际取值为 true/false 二选一 …… 让人开心的是,除了基于已知选项集合的数据和固定值外,其他类型数据都可以通过类似 mock.js 的规则来描述生成规则,而固定值和已知集合,我们暂且先让用户自己手动填写就好了。 需要注意的是,除了表单填充外,我们最开始还提到希望在表单完成填充后能够辅助用户对按钮进行点击操作,即事件派发能力,所以在表单填充上,我们至少要解决这两个问题: 多步操作:表单存在字段之间的联动,无法一次完成赋值 填充与事件组合:表单填充完下一步可能就是点击事件 关于这一部分,更多是在产品功能完善上的思考,而非技术调研上的难点,下面贴一张流程图来解释工具的工作流程: 工程开发:功能集成与插件开发 在完成了需求收集、技术调研以及分步骤拆解实现后,貌似大部分难题我们都获得了答案,接下来要做的便是另一方面,在一个单独的工具中将这些功能集成,当下最合适的方式应该是通过浏览器插件来实现它,插件形式上小巧,但借助 chrome API 以及共享 DOM,我们又能拥有强大的能力。 现代化的插件开发体验 开发过浏览器插件的同学,想必都感受过 chrome 开发文档与当下现代开发方式格格不入的开发体验,手写 JavaScript、HTML 以及 manifest 声明文件,貌似开发流程还停留在刀耕火种的时代,作为一名开发者,我不仅希望我的产品体验良好,也希望开发流程更加现代化,具体来说,对于插件开发,开发工作流至少得满足如下几个方面吧: 代码构建打包 TypeScript + React 支持 插件声明 manifest.json 自动生成 跨 script 持久化存储 不同 script 间 (content script / background / popup) 通信 幸运的是,我们也不用完全从头改造插件的开发工作流,当下已经有开源框架在做相关的事情了,我们可以直接用上,比如 plasmo,他使得我们可以像开发 React 项目那样开发一个 chrome 插件。 当然,我们确实需要额外关注几点,考虑到工具开发过程中遇到的几个难点,我这里着重强调下插件通信以及插件安全。 插件通信方案简介 通信是这个工具绕不开的一个功能点。举几个例子,比如 popup UI 和 content script 之间需要通信,以控制 content UI 的展示与否;比如插件脚本与 MAIN 的通信,以控制在页面内执行特定的脚本以收集一些信息;比如 content script 与 background script 之间的通信,以控制插件在后台需要做的一些计算处理逻辑等等。 为了实现这些功能,需要选择合适的通信方案。好在大多数 Web 通信方案都可以直接用在插件上,此外,插件还可以额外调用一些 chrome API 来触发特定的通信事件,简单来说,存在这么几种方案: 通用的通信机制,通过 postMessage 广播消息 非广播传递,MessageChannel 传递消息 通过 chrome API 进行消息通信 chrome.devtools. inspectedWindow.eval chrome.tabs.sendMessage chrome.tabs.connect chrome.extension.getBackgroundPage …… 其中,关于跨线程通信相关的技术方案,我在《Service Worker 实践指南》一文中有详细介绍,感兴趣的同学可以查阅 https://hijiangtao.github.io/2021/04/13/Service-Worker-Practical-Notes/ 插件安全问题汇总 由于浏览器对插件安全的设计,插件虽然可以通过 HTML/JavaScript/CSS 来编码开发,但其在运行上还存在一些安全限制,从我的开发过程来看,具体有这么三个方面值得注意: 插件权限:chrome 插件在运行中涉及到的权限调用需要在 manifest permissions 中声明 script 对 chrome API 权限:content scripts 中只允许如下几类 chrome.***.api 调用 chrome.extension(getURL , inIncognitoContext , lastError , onRequest , sendRequest) chrome.i18n chrome.runtime(connect , getManifest , getURL , id , onConnect , onMessage , sendMessage) chrome.storage 共享 DOM 权限:content scripts UI 部分不支持针对 DOM 的 Expando 属性的共享 工具功能集成 解决完插件开发的问题后,我们接下来需要做的便是,作为一个产品经理,去思考我们的产品在面世之前需要完成哪些功能的集成,比如: 支持表单自定义 mock 规则生成填充数据 不同规则适配不同页面地址 配置数据的导入与导出 表单识别后的规则提取与拆分 支持自定义事件组合 …… 总结 表单类形态在开发场景中非常常见,如果研发需求的功能测试依赖一个复杂表单的填写而得以继续,那么频繁的表单填写在研发自测和 QA 测试中就会占用过多碎片化的时间,此类需要频繁执行(以生成测试数据或推进执行流程)但规则可循的场景如果可以被工具替代,那么将可以极大的提升产研研发效率。 从远期目标来看,我们需要有一个不侵入用户代码,但可辅助用户自动化识别页面内存在表单,并支持用户自定义 mock 规则生成表单数据进行填充的工具,涵盖各类表单场景。 相比现有社区的方案中,有几个明显的优势/改善点,使得该类工具具有广泛的应用场景: 不依赖代码侵入,对开发人员无接入成本; 识别准确率高,理论情况下可以达到100%,不受前端框架以及 UI 开源库的选型影响; 数据构造灵活,可以完全自定义规则,生成中英文、数字、日期等各类数据,做到随机+灵活; 支持事件派发,支持多步骤表单填充,拥有组合能力; 使用者无需额外的软件安装,通过浏览器插件的方式使用,简单易用,成本低; 但从当下做起,通过技术调研,我们发现当下社区中并不存在一个低成本、无侵入且高准确性的工具,于是借助 React Fiber 结构以及浏览器插件的能力,我们先期实现了一个无侵入式、高准确性的表单识别和填充工具,更多功能会在后续迭代中不断完善。 参考 https://xyy94813.gitbook.io/x-note/fe/react/react-diff-algorithm https://www.zhihu.com/question/49496872/answer/2517859568

2023/11/30
articleCard.readMore

拔牙日记

上两周去拔牙,遇到一个操作非常仔细的医生,不仅细心交待,还给我分析牙齿生长情况,以及可能存在的术后问题。 好景不长,拔完不到5小时,嘴中开始大量渗血,浑身疼痛,在吐了几大口鲜红的液体后,急忙请假赶到医院,找到了上午给我看病的大夫。 谁能想到呢,接下来医生在我嘴里简单捅了几刀,我就开始血流不止了。医生没有过多考虑,便开始给我止血,直到材料塞满了嘴巴,等到开始缝针才想起没有给我打麻药,而我已经疼到有点晕厥,旁边的护士姐姐还提醒道:“要不让他喝了这葡萄糖吧,我看他脸色不好”。 但医生本着专业素养,在动完刀后,立马把自己的老师叫来验收成果,老师看着我满眼的泪珠,语重心长的说:“你这没打麻药,小伙子受不了吧”,我听闻后赶忙应和点点头,随后他叮嘱该医生,以后一定记得先打麻药再…… 随后,医生还留了我一会,本以为是要叮嘱些注意事项,没想到是想在病历上把这突如其来的遭遇仔仔细细记录一番。我明明已说不出话了,但为了记录下这个“疑难杂症”,他还是让我努力说一说,最后促成了一大段文字描述作为补充病情???能看出来,这是一位非常好学的医生。 接下来,由于嘴巴塞满材料且无法闭合,我跟粥汤以及水饺度过了两周,肉眼可见的瘦了。由于担心过久没让医生观察我的牙齿情况,于是我提前约定时间两天加挂了号,同时也做好了准备让医生拆线。果不其然,就在医生给我拆完线之后,又继续血流不止了。 医生紧急给我止血,往我嘴里塞了些材料,还让我继续咬着纱布呆上半小时观察,期间那种疼痛感仿佛又回来了…… 临走前记得医生说要等塞入的胶原蛋白棉片自行溶解在牙槽内,可能要持续一到两周,但,好景不长,第二天吃饭的时候,也不知道是不是太饿了,直接一咕噜,整个棉片随着一口汤全给我吞到肚子里去了。 这苦涩的人生啊。 虽拔牙遇到插曲,但仍然感激医生们的辛勤付出,希望大家都健健康康,远离病痛。

2023/11/11
articleCard.readMore

《四千周》读书摘要

“人这一辈子太短了,短到荒唐,短到可怕,短到没礼貌” 在网友的推荐下,最近在看《四千周》。虽然从书名上看,有点口水或者畅想榜的嫌疑,但实际上可能不少朋友读完后也会由此感想。不过好在书内容不多,可以快速浏览一遍,也不大费时。 以下摘录整理一下文末给出的帮助你接纳人生有限性的十个工具,附上部分摘要描述: 1. 划定边界:采用”定量”的生产力策略 许多工作建议都隐含着这样的承诺:它可以帮你完成所有重要的事情。但这根本不可能,而且为此奋力挣扎只会让你更忙。更好的办法是首先就假设艰难的选择是不可避免的,然后集中精力做好选择。限制手头的工作数量这样的策略肯定有用,但最简单的办法是保留两个待办清单,一个采用”开放式”,另一个采用”封闭式”。在开放式清单中列出你手头的所有事情,它肯定会非常长,长到让人感觉可怕。幸运的是,你并不需要处理这个待办清单,你要做的是将开放式清单中的任务放进有数量限制的封闭式清单中(最多十个)。你需要遵守一条规则:只有完成一项任务,才能往里面添加新的任务(或许你还需要第三个清单,列出需要等待别人给你答复的”搁置”任务)。 2. 专注一事:在完成一项工作前有意推迟其他工作 同样的道理,你需要一次只专注于一个大项目(最多在一个工作项目之夕卜,加上一个非工作项目),完成之后才能进行下一个项目。 3. 要事优先:提前决定放弃哪件工作 你永远有短板,这不可避免,因为人的时间和精力是有限的。但是,策略性的表现不佳(提前计划好哪些方面你不需要做得很好),最大的好处就是你可以集中使用有限的时间和精力。 4. 注重完成:关注已经完成的事,而不是只关注尚未完成的事 真要说的话,完成所有工作的追求可谓永无止境,因此你很容易就会绝望且自怨自艾:在所有工作完成之前,你无法自我感觉良好,但工作永远都有,这意味着你永远无法让心态变好。 5. 聚焦关注:把有限的注意力集中起来 为了有所作为,必须将有限的关注集中起来。 6. 拥抱乏味:选择枯燥且用途单一的技术 你可以将设备变得尽量枯燥一首先,删掉社交媒体应用程序,如果你愿意,甚至可以删掉电子邮件,然后将屏幕从彩色模式切换到黑白模式。”转为黑白模式后,我并不会一下子变成另一个人,但感觉自己可以更好地控制手机了。它现在看起来像是工具,而不是玩具。 7. 寻找新意:更深入地体验日常生活 随着时间一年年过去,体验变成了例行公事。对抗这一现象的常规建议是用各种新奇的经历填满生活。这确实有效,但它很可能导致另一个问题,也就是”存在的应接不暇”。寻找新奇感不是去做完全不同的事情,而是更深入地投入现有以下是重新排版并转换为Markdown格式的文本: 8. 保持好奇:做人际关系的”研究员” 保持好奇心是与他人建立深入联系的关键。当你与他人交流时,保持开放的心态,关注他们的故事、兴趣和观点。将人际关系视为一个不断学习和探索的过程,你将能够建立更加丰富和有意义的连接。 9. 即时慷慨:立刻释放你的善意 善意和慷慨是让人与人之间关系更加和谐的重要因素。不要等待”合适的时机”或条件,立即表达你的善意和慷慨。无论是一句赞美的话语、一份小礼物还是一项帮助,即时慷慨将为他人带来积极的影响,同时也增强了你与他人之间的联系。 10. 静默无为:练习什么都不做 严格来讲,什么都不做是根本不可能的:只要你还活着,就一直在呼吸,身体也会保持某些姿势,等等。因此,训练自己”什么都不做”指的是训练自己抵制冲动,不去控制周围的人和事,让事情呈现其原本的样子。这种静默无为的练习可以帮助你培养内心的宁静和平和,同时减少无谓的忧虑和焦虑。 附 豆瓣地址 https://book.douban.com/subject/36093214/ 简介:如果能活到80岁,你在地球上的时间也只是勉强超过4000个星期。人生不应只是快进,知名的《卫报》心理学专栏作家奥利弗·伯克曼借鉴了古代和当代哲学家、心理学家及精神导师的见解,摒弃了现代人对“完成所有事情”的徒劳迷恋,将肤浅的高效解决方案放在一边,向读者介绍了通过接纳时间和自我的有限性构建有意义生活的方法,将我们从无休止的时间传送带上解救出来,摆脱焦虑、分心、缺乏耐心等消极状态,重新认识真正的自我,选择你想要的活法。

2023/9/23
articleCard.readMore

风雨过后见彩虹:公募基金2022年度报告摘录与解读

去年,我通过问答的形式将阅读完公募基金年报后的一些感想进行了总结,详见《十问十答,从公募基金年报中读懂未来》。如今,已过去一年,按照《公开募集证券投资基金信息披露管理办法》规定,所有公募基金过去一年的年报也已经全部生成,我计划今后将其作为一个年更栏目发表于个人博客,暂且就叫《时间的朋友》吧。那么,接下来就让我们开始2023年版的报告解读吧。 过去一年都发生了什么 大家都在说去年很难,俄乌地缘冲突、海外货币紧缩、疫情扩散等等关键词,可能很深刻的印在了大家的心海,但这些困难关联到资本市场的变动究竟有多难、难在哪,饶刚经理给我们完整梳理了一番: 2022年无论国内还是国外都出现了诸多超预期的因素,比如欧美发达国家货币政策超预期收紧、俄乌冲突、国内疫情反复等,从而导致宏观经济和资产的波动均明显放大, 其中“海外通胀超预期”和“内需疲弱”成为全年牵引资产价格的核心线索:复盘来看,在年初美欧等地区逐渐宣布经济正常化+俄乌冲突之下,供需因素共振导致大宗价格飙涨,海外高通胀压力之下,美联储3月开启加息进程,6月以来连续4次75BP的加息创下历史最快加息纪录,美元指数也一度上行至近20年来高位。而国内在房地产信用风险与疫情反复等因素扰动下,经济运行面临更大不确定性和挑战,内需疲软这一主要矛盾逐步显现并贯穿全年。 ——睿远稳进配置两年持有期混合型证券投资基金 2022 年年度报告 而回顾资本市场的实际变动,以4月、11月为两个关键时点,张清华经理也为我们做了详尽的事件梳理: 2022 年的市场值得审视与反思。回顾历史,我们极少经历如此长时期“弱现实”与“强预期”的对立,预期相对于基本面更难以研究与分析,这对投资带来了极大的挑战。从各种复杂的信息中提炼出市场的主要矛盾并迅速做出调整应对,就显得尤为重要,这需要我们时常审视自己的组合是否规避了极端配置、是否保持足够的灵活性以应对各种可能发生的情形、对未来路标的挑选与迭代是否有效。另外,在理财净值化大背景下,11 月债券市场大幅调整引发了银行理财赎回的负反馈,机构行为对市场价格造成如此剧烈的影响,且影响的时长与幅度均超出预期。市场的一致预期与投资者的一致行动,很容易形成过度拥挤的交易,并可能短期内对市场价格造成超预期的巨大波动,这需要我们对市场更加心存警惕。 ——易方达裕丰回报债券型证券投资基金 2022 年年度报告 再往前,我们或许可以跟着焦巍经理复盘过去三年的操作以对过去的三年都做一个总结: 首先我们在行业的配置调整过程中,随着白酒在 2021 年年初估值和基本面的同时见顶,不断加仓了医药中的消费部分和创新药产业链。随着医药行情在 2021 年 6 月的见顶,我们在 2022 年对医药的调整是滞后和被动的。本基金对医药的 CRO 的减仓始于 2022 年一季度,而同时对中药的加仓则标的没能集中在受益行业。唯一能够在底部加仓并坚持的是医美部分的投资,整体而言,医药部分的投资对本基金的消费部分造成了拖累,而这正是由于 2021 年年初为了避免白酒的估值见顶进行的资产迁移所致 ……其次,在 2021 年年末面对 2022 年布局时,出于对医药现有模式的考虑,本基金小幅配置了军工和半导体行业,这部分投资在 2022 年一季度就证明是失败的,我们随后尽管进行了清仓,但实质上的损失是存在的。 ……第三,我们在某些消费的投资确实在估值过高时没有减持,而在熊市中,高估值叠加基本面的不达预期,造成了其贝塔效应远远大于调整过的低估值公司。——银华富裕主题混合 2022 年年度报告 继续做时间的朋友 我们都说要长期持有,但是什么才叫长期持有呢,或许”保持较高的持股集中度和组合延续性”会是可选答案之一: 报告期内,本基金投资策略上有以下一些特点……前十大股票在基金的净值占比处于45-50%的区间,前二十大股票的净值比例,上半年超过70%,下半年该比例提高到77%左右。重点公司中约40%的持有周期伴随着产品成立至今,“找到一批优秀公司,分享其成长过程中创造的价值”一直是我们搭建组合的理念。 ——睿远成长价值混合型证券投资基金 2022 年年度报告 而除了一些论点外,投资仍旧需要合适的方法辅以帮助,张坤经理在年报中也给出了其对投资这场”无限游戏”的一些生存之法: 很多时候,那些不可知的概括性论断吸引了我们的注意力,而让我们忽视了具体的、可知的、有作用的分析。仅仅因为担忧短期经济形势的变化或者规避股市的短期波动,从而放弃买入甚至卖出一家具有长期盈利能力的公司,并不可取,这实质上是用一项不确定的原因去否定了一件更确定的事情。……考虑一个投资者通常要面对数十年投资生涯,建立稳定的投资体系,保持平和的心态,避免无效的对时间和财富的浪费,以及持续不断学习复用性强的知识,才更有希望在这场无限博弈中不断积累复利。——易方达优质精选混合型证券投资基金 2022 年年度报告 此外,投资也是我们认知的变现,通过了解、判断以及制定应对策略,最终我们的观点会在资本市场付诸实践,并通过真金白银来证其真伪,关于投资持有期以及布局行业上,王崇经理给出了自己的观点: 从未来两、三年的视角看,经过一年多股价的回调,大部分公司股票估值已具备价格优势,甚至存在部分竞争力突出的公司股价估值合理或偏低。拉长投资视角,目前“强预期、弱现实”并充满迷茫的经济和市场低迷阶段可能给中长期投资人提供比较好的布局机会,未来几年有望实现不错的年化收益率。 后续本基金将继续坚守能力圈,积极寻找消费、服务、软件和汽车零部件等行业内估值合理的优质公司股票做中期布局,努力为基金持有人创造较好回报。——交银施罗德新成长混合型证券投资基金 2022 年年度报告 还有一些基金经理会在年报中描述未来投资方向时会带些理想主义色彩,对未来生活和社会的技术发展做一些”预测与展望”: 具体而言,在移动互联网兴起以来,生产关系(商业模式)的优化主导着社会的进步,而生产力(技术)进步缓慢,在这个大背景下,我们将持续看好有望实现生产力突破的领域,比如更深度能源变革(碳捕获、利用与封存技术,更远期的核聚变技术等)、合成生物学、人工智能等。此外,如果跳出地球这个系统,星空、星际探索将让我们获得系统外的劳动资料和劳动对象,虽然还比较早期,但我们也会积极寻找相应的机会。——易方达瑞程灵活配置混合型证券投资基金 2022 年年度报告 未来的路该如何走 我们都知道2023年经济肯定会复苏,但是复苏到多大强度呢,有基金经理表示乐观: 我们认为股票市场有望迎来新一轮上行周期。2022 年困扰市场的因素主要有美联储引领下的全球货币紧缩、国内受到新冠疫情冲击、地缘政治冲突带来的市场风险偏好下降,而这些因素在四季度均出现逆转,资产定价面临重估。新冠病毒毒性降低后,及时调整防疫政策使得经济发展前景变得清晰。只要外部环境正常化,凭借中国人民的勤劳和智慧,任何困难都可以被克服。——景顺长城绩优成长混合 2022 年年度报告 但也有基金经理提示,或许我们不能过于乐观: 展望2023年,中国经济预计将呈现恢复性增长。政策已经把促进内需和经济增长放在首要位置,我们预计经济的下行风险已大幅下降,但复苏过程可能仍然存在波折,一些长短期因素会持续对经济复苏进程带来不确定性,政策及其给予的信心可以托底经济,但经济复苏的强度和节奏仍需观察。 ——睿远均衡价值三年持有期混合型证券投资基金 2022 年年度报告 此外,还需要知道一点,任何外有经验都不能直接生搬硬套运用在国内,中国地大物博,我们的发展道理放在全世界范围内都没有完全可靠可以照搬的案例,我们还是要坚持走中国特色社会主义道路,而擅长债券投资的胡剑经理也给出了类似的观点: 展望未来,中国经济进入后疫情时代,经济基本面企稳回升的方向是确定的。 ……从海外经验看,消费反弹前三个月最为强劲,后续或跟随疫情反复有一定波动,但消费增长以及服务业的复苏带动整体经济向上的大趋势毋庸置疑。然而中国疫后的经济复苏又不能照搬海外经验。其中一方面是供给侧情况反差较大,海外疫情结束后一般都面临供给不足并拉动商品价格上涨的压力,而中国则不一样,由于疫情期间三年来供应链并未受损,且制造业投资较为积极,较低的产能利用率以及多余的工业产成品库存使得市场供大于求的状态在疫后可能会持续一段时间。 另一方面疫情期间的中国经济,遭受了疫情带来的前所未有的影响,还经历了地产行业收缩和平台经济整改等一连串收缩性事件,但随着政策调整的不断完善,如果能成功逆转这些因素带来的影响,则经济将会在未来疫情修复过程中迎来多重利好的共振。 需要重视的是,今年是二十大会议后的首年,二十大历史性地将实施扩大内需战略视作应对外部冲击、稳定经济运行的有效途径。这使得我们可以对支持经济增长的政策抱有更高的预期,使经济增速向上的弹性也更值得期待。——易方达岁丰添利债券型证券投资基金 2022 年年度报告 中国经济自2010年跨越刘易斯拐点之后,劳动力报酬占比上升伴随着经济总量的增长推动了消费的持续增长,带来了2010年到2020年经济增长的黄金时期。很多知名投资者一直在说要相信国运,要相信未来,但也就这两三年,从双减政策公布开始,到经历了互联网平台企业的持续性裁员、及各行各业艰难生存不敢扩张之后,我们或许都对未来有了不少担忧。可能这时候有些投资者会告诉我们要更加乐观一些,要逆向投资,但事实上我们可能确实需要持续性保持谨慎: 产业转移带来的海外竞争使得中国劳动力报酬很可能在未来一段时间处于停滞甚至下降,经济增速下降,很多行业的需求增长将大幅放缓,行业的周期属性将超过成长属性。而过去很多年的行业整合,龙头公司的市场份额已经较高,虽然企业护城河仍然宽广,但如果缺乏第二成长曲线,龙头企业的收入和利润也会呈现增速下行、周期波动加大。 ——睿远均衡价值三年持有期混合型证券投资基金 2022 年年度报告 中概人中概魂,我们单独再将中概股的发展趋势拉出来说说: 展望 2023 年,中国经济增速有望领跑全球主要经济体,财政和货币政策工具相对充足,稳增长措施也将逐步发力。短期来看,需要关注全球金融条件和海外中概股公司的业绩披露。中长期来看,价格的中枢由行业未来发展前景和上市公司业绩基本面决定。中证海外中国互联网 50 指数的成份股是境外上市的中国互联网企业中总市值及流动性综合排名最好的头部公司,是中国数字经济和平台经济领域的代表性企业。伴随未来中国经济的企稳和消费的复苏,中国互联网公司也有望迎来持续、良性健康的发展局面。——易方达中证海外中国互联网 50 交易型开放式指数证券投资基金 2022 年年度报告 当然,看完了国内,我们可能也可以扩大到国外看看,毕竟国外的经济衰退如果板上钉钉,势必会影响我们的外需: 美国经济回落的幅度,取决于美联储愿意为控制通胀而牺牲经济的程度,而这也对应着美联储后续加息的高点以及高利率持续的时间。根据美联储主席鲍威尔介绍,美国目前所面临的通胀压力,主要来自于三点,一是核心商品通胀率;二是住房服务通胀率;三是住房以外的核心服务通胀率。首先,核心商品通胀率,随着美国巨额财政补贴的消耗以及供应链问题缓解,核心商品通胀率已经从非常高的水平下降且未来将延续下降趋势;其次,住房服务通胀率,由于租约重置滞后于房价涨幅半年时间,所以过去一年时间房租均呈现上升趋势,随着美联储加息美国房价已然下跌,这会反映到2023年通胀中,所以住房服务通胀率在2023年也是趋于下降;最后,住房以外的核心服务,主要涵盖了从医疗保健和教育到理发和招待等广泛的服务,劳动力市场是理解这一类别通胀的关键。目前来看,疫情期间致使美国劳动力缺口大约为350万人次,其中200万人是由于超额退休所致,而150万则是由净移民人数骤减和疫情期间死亡人数激增所致。所以综合来看,2023年美国通胀趋势向下只是还高于2%长期中枢目标。通胀的压力主要体现在劳动力市场端,要不然增加劳动供给,要不然美联储加息抑制劳动需求。 找到与自己风格匹配的产品 你适合什么样的基金产品?与其抓着基金名称或者抓阄乱选,不如看看你的投资理念、趋势把握与基金经理是否相似,只有合适自己的才是最好的,我在这摘录几位经理的观点,其中不乏”捡石头”者: 朱少醒 我们并不具备精确预测市场短期走势的可靠能力,理性的长期投资者应该做的是以合理的价格耐心收集前景远大的优秀公司的股票,等待公司自身创造价值的实现和市场情绪在未来某个时点的回归。个股选择层面,本基金偏好投资于具有良好“企业基因”,公司治理结构完善、管理层优秀的企业。——富国天惠精选成长混合型证券投资基金(LOF) 二 0 二二年年度报告 林虎、李中阳 组合将保持中性偏短久期,维持偏高杠杆水平,以中短期限高等级信用债为底仓品种,获取票息收益和骑乘收益。同时,组合将根据对基本面和货币政策的判断,结合对机构行为的分析,适当逆势操作利率债和中长期限信用债,灵活调节组合久期,增厚收益。——易方达安心回馈混合型证券投资基金 2022 年年度报告 姚志鹏 当下,电动车、计算机、军工和医药等行业在市场悲观预期下大部分行业都跌到了十年估值最低的区间,同时符合中国经济未来新时代下安全和发展的需求,当下市场更多在贪婪的追逐稳增长的老经济,对于新经济的偏见则导致了这些资产再度出现了较好的估值水平,我们将继续在这些资产中寻找中期能够推动中国经济复苏的那些优秀企业,在当下市场的低潮中积极配置。 凡事有利有弊,我们一直以来是坚持寻找战略方向的大空间行业、寻找趋势上行和头部企业的思路在进行投资。这样的方法在市场恐慌的 2022 年遇到了较大的波动和挫折,投资者对于经济前景呈现出比较负面的情绪,估值收缩幅度非常大。而我们的方法更多是通过产业和企业的盈利增长来获取价值增长。这种方法比较依赖于产业机会的挖掘和获取以及投资者信心的维持。——嘉实新能源新材料股票 2022 年年度报告 葛兰 伴随我国居民人均收入及认知水平快速提升,医疗服务以及消费性医疗的需求仍在快速增长且未得到充分满足,未来空间依然巨大,这些公司的价值终将有公允的市值体现。 整体而言,短期市场波动难以避免,但中长期而言,我们继续看好医药生物板块的配置价值,我们也将继续努力为持有人创造长期投资回报。——中欧医疗健康混合型证券投资基金 2022 年年度报告 刘涛 2023 年一季度,国内经历首轮感染高峰,春节后生产和出行逐步恢复,货币政策呵护资金面,两会前后财政和宽信用政策继续落地,债市震荡偏熊。二季度至三季度,经济从衰退转为复苏,地产基本面或初现修复迹象,货币政策或由松转平,利率调整压力或加大。四季度,海外衰退形成,国内财政和宽信用政策力度或减弱,可以等待复苏至顶带来的超跌机会。——鹏华丰禄债券 2022 年年度报告 秦毅 今年引发市场巨幅调整的原因,多为俄乌冲突、奥密克戎疫情等突发性事件,难以事先做出准确判断,情绪的冲击更多于基本面的影响。因此,本组合在仓位方面并未做出过多调整,基本保持了原先的仓位水平。 ……个股配置方面,本产品始终坚持深度研究、精选个股的原则,尽管市场波动较大,我们仍然坚持这一理念,选择投资未来最有投资价值的标的。——泓德泓华灵活配置混合型证券投资基金2022 年年度报告 谢治宇 未来我们一方面在周期逻辑向上时寻找好的投资机会;另一方面在电子、半导体、消费等行业中寻找风险收益比长周期合理的品种进行组合配置,以为投资者创造合理的中长期价值为首要宗旨。——兴全合宜灵活配置混合型证券投资基金(LOF)2022 年年度报告 石雨欣 报告期内,本基金继续按照“固收+”策略布局投资,仓位维持中性水平,风格均衡偏成长,稳健参与市场结构性机会。债券部分以高等级信用债配置为主,阶段性参与利率债的波段交易投资机会,择机配置商业银行金融债,灵活调整组合久期,积极防范信用风险。——华安安康灵活配置混合型证券投资基金 2022 年年度报告 林英睿 事实上,由于股价改变的基本动力是投资者的决策和行为认知发生改变。因此市场的独立思考者越少,市场就越容易累积风险而被群体的反身性定价。对于投资人而言,能够有多种底层思路不一样的投资策略供选择是真正能系统性提高夏普的路径。分散化的核心在于低相关而不是数量多,而能从低相关获益的核心在于时间价值。这是市场上一种最普遍但又最昂贵的价值。——广发多策略灵活配置混合型证券投资基金 2022 年年度报告 丘栋荣 从股息率与10年国债到期收益率比值看,息债比基本处于2009年以来的最高区域。估值水平至极低位置,往往是价格压至极限的表现,再结合风险溢价水平、个股组合可得性等维度的比较,股票性价比最为突出之时,代表着系统性机会,需要坚定和果敢,燃起希望去把握投资最好的时候。——中庚价值领航混合型证券投资基金 2022 年年度报告

2023/4/1
articleCard.readMore