SegmentFault 最新的文章 |
- 十年老友记 | @杨成功:没有什么能比写代码更让我快乐
- Lerna --多包存储管理工具
- 如何用pkg打包nodejs可执行文件
- JS判定一个给定的时间在某个时间范围内
- react-router-middleware-plus开源啦 | 基于react-router v6的零成本式路由权限解决方案
- 还在从零开始搭建项目?这款升级版快速开发脚手架值得一试!
- JS实现的接粽子小游戏,愿你好运接粽而至
- 云计算的未来在哪?破解亚马逊云科技增长神话
- JS自动生成24小时时间区间,时间跨度为60或30分钟
- SegmentFault 思否技术周刊 -- Node.js 进阶之旅,看看那些还需要学?
- 十年老友记 | @边城:恰当的编程是会产生幸福感的
- 文字轮播与图片轮播?CSS 不在话下
- 2022 前端开发报告:TypeScript 成 84% Web 开发者的“最爱”|无障碍性、边缘渲染成大趋势
- 一文搞懂四种 WebSocket 使用方式,建议收藏!!!
- 如何写出高性能代码之优化数据访问
Posted: 31 May 2022 07:56 PM PDT 不要浅尝辄止,做精一件事,总会有回报的。——杨成功 十年前的今天,SegmentFault 思否正式创立,如一颗嫩绿的幼芽开始成长,期间承载过和煦的日光、沐浴过柔和的春风,也挑战过滂沱的暴雨、体会过凛冽的冬雪。所幸,今日呈现在我们面前的 SegmentFault 思否,已经长成了一棵足以抵御一些风雨的大树,这样的成长离不开各位管理员的修剪,更离不开社区每一位用户的栽种。 正如 SegmentFault 思否创始人之一祁宁所言: "SegmentFault 思否是一个属于大家的社区,因此,在这个特殊的时刻,我们想跟社区的成员一起为它喝彩。" 这十年中,有成千上万的开发者加入了 SegmentFault 社区,我们雀跃于看到每张不同的新面孔,也感动于社区里的那些老朋友们多年如一日的陪伴,见到他们就像见到一位相识多年的老友。或许老友们会在某一段时间里突然消失,但消失并不代表着再也不见,而是重逢后的那句:好久不见。 今天,我们有幸邀请到老朋友 @杨成功 参与我们的十年老友记系列访谈。 杨成功成为程序员的路途比较坎坷,在访谈中他表示自己是在大学时期,感觉对所学的专业并不感兴趣,于是退学后学了编程,为了当一名合格的程序员,他放弃了许多。 我本想问他会不会后悔当年退学的决定,但他却说没有什么能比写代码更让他快乐,听他说完这句话后,我意识到我的想法是多余的,就算他在通往编程的路上遇到更多困难,我相信他的心里也一定觉得所有这些为了接近编程而遭受的磨难都是值得的。 以下为 SegmentFault 思否与杨成功的访谈内容: 1、还记得和 SegmentFault 思否的初识吗?是在什么样的机缘巧合下踏入这个社区的? 我和思否相识很早,大概在我做程序的第二年吧,经常能从 SegmentFault 中搜到有用的信息。有一次我遇到了个难题,看到 SegmentFault 上有提问的板块,我就注册了账号提了问题,结果一个小时就收到了答复,帮我解决了问题。当时我就点头说,嗯这个网站比较靠谱。 其实我对思否最大的感悟就是这么多年一直保持纯粹,问答和专栏依然是最纯粹的技术贴,几乎没有见过水军,我觉得这个是相比其他社区最难得的。我在思否的这几年,从一个提问者和查阅者,变成了一个回答者和输出者,或许也或多或少的帮助了别人,这是我最大的成长。 对我来说是梦想吧,因为我是大学退学学的技术,成为一名程序员放弃了很多。但在这个过程中让我更加坚定了没什么比写代码更让我快乐的事情,我可以 coding 到 60 岁哈哈。 也许会做一名老师吧,继续教小孩写代码,或者成为一名技术博主 多看看 95 后,他们可能比你想像的更时尚。 工作任务是基本,对我而言更多是一项事业。可能多数程序员并不是单纯的喜欢写代码,更重要的是攻克了一个难题所带来的成就感,以及用编写的代码来解决实际的问题,并且带来商业价值,这是非常酷的一件事。 有啊,焦虑就是技术更迭太快啦,环境越来越卷了,很担心掉队。还有圈内会有各种比较,让你觉得自己不够优秀。我认为有效的方法就是选择一个方向持续深耕下去,保持专注,成为专家。不要浅尝辄止,做精一件事,总会有回报的。 肯定是有的,35 岁危机所有人都有嘛,只不过对程序员来说更突出一些。我觉的抵御危机的方法就是尽早的建设自己的不可替代性,尤其是需要时间积累才能出成果的东西,这会是你手里代表价值的一张王牌。 首先感谢 SegmentFault 思否十年来坚守初心,深耕中文技术社区,为开发者提供了一片分享交流的乐土。祝 SegmentFault 思否十周岁生日快乐!希望下一个十年思否依然乘风破浪,扬帆远航! 为了梦想努力前进的人,都不会被辜负。 希望杨成功会在下个十年依然如此热爱编程,希望下个十年,我们都能在历尽千帆后仍觉得一路坎坷值得。 | |||||||||||||||||||||||||||||||||||||||
Posted: 08 Jun 2022 08:25 PM PDT lerna最近在看vue-cli的源码部分,注意到这一个仓库下维护了多个package,很好奇他是如何在一个repo中管理这些package的。 我们组现在也在使用组件库的方式维护项目间共用的业务代码。有两个组件库,存在依赖的关系,目前联调是通过 lerna的文档还是很详细的,因为全是英文的,考虑到阅读问题,这里我先是自己跑了几个demo,然后做了中文翻译。后续我会出一篇专门的lerna实战篇 lerna 是干什么的?Lerna 是一个工具,它优化了使用 git 和 npm 管理多包存储库的工作流。 背景1.将一个大的 package 分割成一些小的 packcage 便于分享,调试 2.在多个 git 仓库中更改容易变得混乱且难以跟踪 3.在多个 git 仓库中维护测试繁琐 两种工作模式Fixed/Locked mode (default)vue,babel 都是用这种,在 publish 的时候,所有的包版本都会更新,并且包的版本都是一致的,版本号维护在 lerna.jon 的 version 中 Independent mode
独立模式,每个 package 都可以有自己的版本号。版本号维护在各自 package.json 的 version 中。每次发布前都会提示已经更改的包,以及建议的版本号或者自定义版本号。这种方式相对第一种来说,更灵活 初始化项目
标准的 lerna 目录结构
启用 yarn Workspaces (强烈建议)Workspaces can only be enabled in private projects. 默认是 npm, 每个子 package 下都有自己的 node_modules,通过这样设置后,会把所有的依赖提升到顶层的 node_modules 中,并且在 node_modules 中链接本地的 package,便于调试 注意:必须是 private 项目才可以开启 workspaces
hoist: 提取公共的依赖到根目录的 workspaces: 所有依赖全部在跟目录的 常用命令lerna init初始化 lerna 项目
[lerna create <name> [loc]](https://github.com/lerna/lern...创建一个 packcage
lerna add为匹配的 package 添加本地或者远程依赖,一次只能添加一个依赖
运行该命令时做的事情:
Command Options以下几个选项的含义和
Examples
lerna bootstrap将本地 package 链接在一起并安装依赖 执行该命令式做了一下四件事:
Command Options
lerna link将本地相互依赖的 package 相互连接。例如 lerna1 依赖 lerna2,且版本号刚好为本地的 lerna2,那么会在 lerna1 下 node_modules 中建立软连指向 lerna2 Command Options
lerna listlist 子命令
Command Options
| |||||||||||||||||||||||||||||||||||||||
Posted: 08 Jun 2022 07:33 PM PDT 使用pkg可以将Node.js项目打包为可执行文件,甚至可以在未安装Node.js的设备上运行。 实验环境 操作系统:windows 操作过程
咱们可以选择全局安装,在任意目录执行:
先写一个简单的程序,比如server.js内容
进入nodejs项目根目录,执行如下命令
第一次报错 这时候会报错
大意是,当前环境只支持编译为windows系统的可执行文件,也就是win 调整指令为:
其中-t win等同于--targets win,也就是说只为windows编译文件。 第二次报错 编译时候再次报错:
大意是缓存里缺少相应的二进制文件fetched-v16.14.2-win-x64,咱们只要下载到相应的文件,放到相应的缓存目录就好。 1、去官网下载相应版本文件,比如我的是node-v16.14.2-win-x64 官网地址:https://github.com/vercel/pkg... 2、将上一步下载的文件node-v16.14.2-win-x64重命名为fetched-v16.14.2-win-x64,放到当前用户的缓存目录中。 比如我的缓存目录是C:\Users\MangoDowner.pkg-cache,拼接上fetch的tag就变成了最终的目录,参照报错中的信息,可以得到tag为v3.3
咱们可以得到最终的父目录为C:\Users\MangoDowner.pkg-cache\v3.3, 再次编译,成功!
| |||||||||||||||||||||||||||||||||||||||
Posted: 08 Jun 2022 06:00 PM PDT 有这样的一个场景:给定一个时间,需要判定这个时间在哪个时间范围内. 比如时间范围如下:
现在给定一个时间 15:28 ,那么就需要返回 ["15:00","16:00"] 这个时间范围,具体的实现代码如下:
测试一下,传入时间 15:28
执行后返回的结果如下:
如果传入临界点的时间,比如 16:00,那么结果是什么呢?
执行后返回的结果如下:
在实际的应用场景中,对于临界点时间,如何划分其位于哪个区间,通常有以下几种情况: (1)同时算两个时间区间内,比如 16:00 ,既算做位于 ["15:00","16:00"],也算做位于 ["16:00","17:00"] 区间; (2)临界时间作为结束时间,比如 16:00 ,那么就只算做位于 ["15:00","16:00"] 区间; (3)临界时间作为起始时间,比如 16:00 ,那么就只算做位于 ["16:00","17:00"] 区间; 如果想要同时兼容上面的几种情况,那么就需要对判定比较方法进行改造,通过相应的参数进行控制,具体改造后的代码如下:
下面分别测试一下上述的三个场景: 场景一:
输出结果如下:
场景二:
输出结果如下:
场景三:
输出结果如下:
| |||||||||||||||||||||||||||||||||||||||
react-router-middleware-plus开源啦 | 基于react-router v6的零成本式路由权限解决方案 Posted: 08 Jun 2022 08:05 PM PDT 一、你的苦恼~~你还在为 你还在翻遍了社区react路由权限相关文章发现都是V4、V5版本的而烦恼吗? 你还在为自行适配react-router v6版本的权限步骤繁杂,多重鉴权逻辑嵌套而烦恼吗? 他来了!他来了!他带着礼物走来了! 二、react-router-middleware-plus
路由组件声明:
middleware:
middleware处理流程图: 三、快速开始
四、Props介绍
五、middleware callback介绍这里提供下类型声明,
再次强调一下,如果拦截路由就在 六、求Star如果你通过使用 同时非常欢迎小伙伴们提 | |||||||||||||||||||||||||||||||||||||||
Posted: 08 Jun 2022 06:38 PM PDT 关注我Github的小伙伴应该了解,之前我开源了一款快速开发脚手架 SpringBoot实战电商项目mall(50k+star)地址:https://github.com/macrozheng/mall 聊聊mall-tiny项目可能有些小伙伴还不了解这个脚手架,我们先来聊聊它! 项目简介mall-tiny是一款基于SpringBoot+MyBatis-Plus的快速开发脚手架,目前在Github上已有 项目地址:https://github.com/macrozheng... 项目演示mall-tiny项目可无缝对接 前端项目地址:https://github.com/macrozheng... 技术选型这次升级不仅支持了Spring Boot 2.7.0,其他依赖版本也升级到了最新版本。
数据库表结构化繁为简,仅保留了权限管理功能相关的9张表,业务简单更加方便定制开发,觉得mall项目学习太复杂的小伙伴可以先学习下mall-tiny。 接口文档由于升级了Swagger版本,原来的接口文档访问路径已经改变,最新访问路径:http://localhost:8080/swagger... 使用流程升级版本基本不影响之前的使用方式,具体使用流程可以参考最新版 升级过程接下来我们再来聊聊项目升级Spring Boot 2.7.0版本遇到的问题,这些应该是升级该版本的通用问题,你如果想升级2.7.0版本的话,了解下会很有帮助! Swagger升级
Spring Security升级升级Spring Boot 2.7.0版本后,原来通过继承
MyBatis-Plus升级MyBatis-Plus从之前的版本升级到了3.5.1版本,用法没有大的改变,感觉最大的区别就是代码生成器的用法改了。 在之前的用法中我们是通过new对象然后set各种属性来配置的,具体参考如下代码:
而新版的MyBatis-Plus代码生成器已经改成使用建造者模式来配置了,具体可以参考
解决循环依赖问题
解决跨域问题在使用Spring Boot 2.7.0版本时,如果不修改之前的跨域配置,通过前端访问会出现跨域问题,后端报错如下。
具体的意思就是
总结今天分享了下我的开源项目脚手架 项目地址开源不易,觉得项目有帮助的小伙伴点个 | |||||||||||||||||||||||||||||||||||||||
Posted: 08 Jun 2022 05:31 PM PDT 端午节虽然已经过了,但是美好的生活以旧在继续。这里用 JS 实现了一个简单的接粽子小游戏,寓意美好接粽而至。能接到多少粽子,完全看你手速,不用担心端午没粽子了。线上体验地址 游戏设计在游戏屏幕内,会随机的从顶部掉落粽子,通过鼠标移动到粽子上并点击,成功接住粽子,得到积分。在设置面板中,可以设置游戏难度,分为简单、很难、超级难三种等级,不同等级的积分也是不同的,玩家可根据自己的手速进行设置。游戏结束后,可看到自己的成绩。实现出来的效果如下: 游戏实现添加粽子元素在游戏屏幕内,需要源源不断的添加我们的主角--粽子大哥,可以让玩家点击,并且可以移除掉被点击的粽子元素。
把
该样式给粽子设置了宽高,当我们设置游戏难度时,我们可以动态改变粽子的宽高,粽子越大,越容易被点击到,所以难度越高时,可以调小粽子的宽高,需要更厉害的手速才有可能点击到。 粽子掉落掉落动画没加什么动效,所以比较简单,用
难度选择使用
监听 radio 元素的 change 事件,而不是 click 事件,因为 click 重复点击时还会继续触发,不是我们需要的。只有在难度等级发生变化时才需要触发。 当难度变化时,主要是改变粽子的大小和下落速度来实现玩家更难接住粽子,根据 difficulty 值来设置粽子元素的样式类。
开始游戏游戏开始时,进入倒计时,粽子开始掉落,并计算玩家得分。
总结整体实现还是比较简单的,不过也还是存在很多可以优化的地方。像点击粽子后,可以有一些接住的效果后再消失,粽子的掉落路径,可以多一些花样等,可以给游戏增加一些乐趣。 | |||||||||||||||||||||||||||||||||||||||
Posted: 07 Jun 2022 08:43 PM PDT 本文转载自公众号:CloudTech2030 之前看亚马逊云科技创新大会直播,尤其是顾凡的主题演讲"重构云底座,加速向未来",相比 re:Invent 的隆重的会场和丰盛的议题,这次更能总览亚马逊云科技全局产品和方案,我恰好在思考中美云计算的发展,本文有感而发。 云计算被形容为自来水,方便快捷。早年自来水没有表,按人头交钱浪费严重。仅剩一些农村这么干。可是你能想象到吗,中国的云计算过去十年跟农村自来水一样。最终用户不省钱,服务商也不赚钱。 本文有点儿长,先说结论。亚马逊电商有一套飞轮增长哲学,云计算业务也同样采用类似增长飞轮策略。"主动降价"增加客户粘性、"架构创新"客户实现业务价值,看起来简洁易懂,却蕴含着深厚的产品哲学。众多跟随者求而不得,无法模仿,我们来解读亚马逊云科技的产品之道,破解云计算增长之谜。 重构云底座相对于总部的 re:Invent 大会,中文版的直播更好理解,而且信息浓缩,看一遍不过瘾,又看回放。终于"会当临绝顶,一览众山小"。keynote 关于云底座基础架构产品的演讲,让我从更全局的角度,再次认识云计算产品战略。萦绕在心中的问题,逐渐有了答案。为什么那么多用户选择亚马逊云科技,为什么 620 亿美元的规模,增长率还能达到 37%? 云计算产业的问题和思考"亚马逊云业务 2021 年总营收 622 亿美元,同比增长 37%。四季度营收 177 亿美元,同比增长 40%。全年营业利润 185 亿美元,营业利润率为 29%。"年初看到这条新闻,感叹这么大的营收规模,如此高的利润率,是否因为绑定客户,产品定价过高? 反观国内的云计算亏钱降价策略,这样难道不应该更能做大市场吗? 先说结论,亚马逊云科技采用智慧的产品定位和不同定价战略,聪明地为客户省钱,同时获得利润投入技术创新和全球化。前文是总体战略的增长飞轮,以下是产品角度的分解。 云产品的增长飞轮: 对比云计算厂商的增长刺轮(部分跟随者),刺轮需要额外推力才能保持运转,比如客户补贴,重投入客户关系,定制化等。这也许就是很多厂商持续亏损,份额却无法增长的原因。 云计算为客户创造价值到目前为止云计算还没有颠覆性技术发明,还没有人讲清楚未来它的价值在哪,有多大? 顾凡引用了 McKinsey Quarterly 报告,"到 2030 年云计算为 500 强创造价值规模超一万亿美元,节约成本 4300 亿,创造价值 7700 亿"。成本节约大大降低客户自建 IT 软硬件成本,同时,利用云上更加易用的 AI 和大数据技术,为企业业务创造价值。 文章有点长,咱们用麦肯锡的金字塔思维框架,结论先行。 云产品用户粘性和竞争力有以下 3 个方面:
后面主要从前两个方面分享我的思考。 本文先重点讨论 1 和 2。 1. 重新定义IT,实现成本节约还是结论先行,亚马逊云科技为客户节约成本,不靠低价格,而是靠贴近用户 IT 模型的产品定义。比如按量付费的 Amazon EC2,承诺用量的节省计划,到灵活切分的容器,低价抢占的 Spot,无服务器的 Amazon Lambda,再到自动降级省钱的 Amazon S3。 比如 Amazon EC2 的按秒付费,比常规包年的价格虽然单价高 50%,如果你的应用 1 天内高负载时间低于 16 小时,按量付费就更省钱。聪明的产品不靠低价,而且双赢。 传统 IT 玩法过去:IT 老兵都知道,这个领域过去的玩法。IT 软硬件产品市场操作复杂,有厂商-渠道-代理-集成商,代理还分总代/一代/二代。厂商还要建团队去管理渠道、管理价格体系、行业/区域/代理级别折扣体系都不一样,还要防窜货,厂商花费大把资金用来做渠道激励和管理。 从客户侧看,甲方企业还要养着一个强大的采购团队,议价、比价、入围、签单,中间环节复杂且不透明,甲方老板也不放心,还需配套后端廉政、合规、审计。 比如我们常见的企业级高端服务器、存储、网络和安全产品定价官网是查不到的,折扣范围巨大,最低可以到 1 折,也可以 5 折。议价能力弱的客户,就需要找多个渠道询价,各种供应商比较,各种手段压价。本来 1 个月可以下单到货,经过多伦博弈要折腾半年,然后多家组合集成,再用半年来交付。 其他玩家捆绑大法云计算被形容为自来水,方便快捷,按需使用,按量计费。但是最早是没有水表的,按月收费,现在还有农村这么操作。结果喝水的嫌贵,卖水的亏钱,只有浇田的没意见。 参见某云产品 3 年价格调价通知: 2. 亚马逊云科技从哪些产品方面为客户考虑?1)持续降价的产品战略客户选择云计算,综合评估 TCO、性能、可靠安全,体验和服务能力; 如果服务商用低价来抢单,要小心是否有陷阱,是否会以次充好?是否先进店后宰客?超低折扣能否长期持续? 亚马逊云科技产品数十次降价,当相对其他玩家来讲,不采用低价策略,而是双赢的产品设计策略,值得思考。 我们接下来重点分析营收主力产品。企业的 IT 开支 IaaS 一般占大头,其中最大的产品是计算、存储加起来一般超过 50%。我们来看看云厂商的产品策略。 2)越来越轻的产品架构从应用架构上节约: 虚拟机 Amazon EC2--> 容器 Amazon ECS/EKS--> Amazon Fargate--> Amazon Lambda 从过去物理服务器的形态,到越来越细粒度的切分,最终实现仅调用时占用资源。资源开销可以更加贴近客户的IT负载曲线。减少浪费,帮客户省钱。 从定价模式上节约: 按量付费-->预留实例-->节省计划--Spot,主打按量付费的同时,给用户多种灵活选择。 3)坚持按量付费模式云计算提供的是服务与传统 IT 最大的区别,就是按订阅收费。常见的软件订阅一般按照月或者年的方式。但亚马逊云服务更加激进,服务订阅按秒付费(最小 60 秒),不做长时间绑定,恰恰解决了客户 IT 峰值痛点问题。按照当前的定价比例,如果每天使用时间低于 16 小时,按量比包年更划算。 表-多种付费方式的差别 长期坚持按量计费,提供多种弹性方案和定价策略,培养市场对按量使用资源习惯,自己也孵化出 Serverless 产品。从本次演讲也可以看出,客户弹性用的非常普遍。每天新创建 6000 万个实例,按照每实例 4vcpu 估算,代表 300 万台服务器,云上超50% 应用负载采用弹性方式创建。 过去 IT 服务厂商硬件设备无法实现按量订阅,只能按峰值需求采购。但是国内其他云厂商为什么不跟随?为什么还主推这种模式(很多服务商希望用低价包 N 年方式绑定客户) 本质来看,付费包服务商需要预留资源、容量、性能,保证在需要弹性的时候,兑付成功率高。背后需付出巨大的成本来支持,预留充足的服务器资源池;还要建设规模足够大的可用区机房并支付成本。亚马逊云计算在美国本土的 Region 一般 3-4AZ,国内服务商 AZ 数量经常达到 2 位数。节约短期成本,却造成资源池碎片化,影响客户弹性扩容体验。 4)抢占式实例--共享资源新范式B2B 共享资源的新范式,闲置资源拍卖 使用 Amazon EC2 Spot 实例,可以请求 Amazon EC2 备用计算容量,与按需实例的价格相比,这类实例最多可以节省 90% 的成本。 计算过去 30 天内与按需相比节省的费用 中断频率表示 Spot 在过去一个月间回收容量的比率。 过去按量售卖,客户峰谷会非常多,削峰填谷非常难调度,导致经常有 30-40% 的限制,采用 spot 方式,可以低价抢占剩余资源。 实际上有不少做算力的公司把这种空余资源低价买入,分发给需要计算的客户;比如并行计算类似玩家,二次售卖 HPC 业务。 5)手中无剑--开创无服务器新赛道一个做云服务器起家的服务商,竟然开启了无服务器新赛道。顶级高手追求手中无剑,心中有剑的层次。 基础设施无论怎么按量、弹性的方式使用资源,让人有 scale-out 水位,一般应用工作水位 30%,启动扩容的水位是 50-70%,缩容更加谨慎,需要等实例内的最后一个客户服务结束。 开创性地发布产品 Amazon Lambda,完全按照业务负载付费,把资源占用和浪费压缩到 0。 Amazon Lambda 费用=计算时间+请求次数+内存+存储+并发。 咱们看一个官方案例,一个具备峰谷特点的外卖订餐系统;每月处理 300 万个请求。函数计算实现执行时间为 120 ms,每次内存 1536 MB。扣掉 100 万免费额度,一个月下来才 20 美元; 当然,Serverless 还不是万能的,仅支持脚本语言、启动慢(50ms+)、有调用限制。 6)自动省钱的 Amazon S3Amazon S3 是对象存储,是亚马逊云科技营收最大的存储产品。从开发中角度,数据在产生之时,并不知道未来如何使用,未来算冷还是热数据。而 Amazon S3 存储提供了冷热自动分级,超过 90 天不用,可以自动降级; 我想问一个问题,这么主动帮客户省钱,PD 不用承担营收 KPI 吗? 设计一个产品尽量从客户那儿多收钱,这才是职业化的 PD 。 Amazon S3 不只是一个产品,而是一个系列,有多种热度和性能的存续范式。 Amazon S3 的产品价格随着用量增加,单价下降。按照我的期待,容量达到 PB 后应该继续降价。后面应该留给了销售去申请折扣。 美中不足的是,Amazon S3 的收费复杂度,由六大成本组成:存储定价、请求和数据检索定价、数据传输和传输加速定价、数据管理和分析定价、复制定价以及使用Amazon S3 Object Lambda 处理数据的价格。 如何选择趁手兵器--购买方式总结大胆设想,目前大客户还是有额外折扣的,有额外议价空间,未来的产业互联网,按照采购量自动生成阶梯折扣,更加透明,期待有云厂商早日迈出这一步。 主动帮助客户省钱,这也许是敢于用按量收费,而且客户粘性越来越强的原因。 成本管理和优化工具的七种武器好的产品设计要对财务友好,企业IT部门每年都有降本 KPI。亚马逊云科技有如此多的工具组合,功能强大,很多账单还可以导出 excel,二次架构处理。 丰富的工具包: a.Amazon Pricing Calculator 在亚马逊云科技中国区域估算云使用成本 技术创新围绕客户价值 自底向上的基础技术创新-芯片亚马逊云深耕客户 IT 多年,为云原生场景设计芯片,从减少虚拟化损耗开始,逐步接管客户通用负载、ML 负载: Amazon Nitro:就是支持虚拟化的智能网卡,带火了 DPU 概念。快速创新,性能让利给客户 Amazon Nitro 加速应用性能亚马逊云科技早在 2006 年就推出了 Amazon EC2 虚拟主机服务,早期可用的虚拟化技术只有 VMware 商业软件和开源的只有 Xen 技术,KVM 刚刚诞生还未成熟。 Xen 的虚拟化采用全虚拟化技术,也就是靠软件虚拟出内存、IO、外设等设备,CPU 性能损耗达 20-30%,主流云服务商都切换到了 KVM,2013 年收购了 Annapurna labs。还在忍受低效的老技术。被 VM 性能吊打两年后,终于在 2017 年发布了Amazon Nitro 和 Amazon Nitro hypervisor,实现优化虚拟化负载。 表-Amazon EC2 Virtualization Types 过去 KVM 软件虚拟化虽然实现了 SRIOV,但是 vNIC、vBlock 设备还是需要大量内核来处理设备 IO,与应用负载争抢 CPU 资源。负载的比例大概 10-20%。采用 Amazon Nitro 硬件虚拟化技术帮客户应用实现性能提升,同时意味着降低资源需求,降低成本: Memcahed:Amazon Nitro 领先 9-26% Amazon Nitro SSD 优化存储时延:从 0.08ms 降低到 0.02ms;数据库、ML 需要更低时延提升应用响应速度。过去应该采用商用方案,现在 Amazon Nitro 加速,实现 SSD 虚拟化,统一监控和管理,且降低时延。 Amazon EC2快速推出新实例亚马逊云科技主要以服务形式提供给客户,后台技术迭代,客户不需要感知,一个产品系列类型可以收敛到 1-3 个形态。但计算产品不同,客户的应用会感知到 CPU 平台的差异,不同应用也有不同的需求,这导致 Amazon EC2 产品实例系列快速爆炸,比如 CPU 分为 Intel、AMD、ARM,内存分为1:2、1:4、1:8 和 1:16,加速器分为推理、训练、FPGA、媒体转码,此外还有 IO 增强,如网络增强、本地盘等形态。几种组合,每一代有数十种硬件架构形态。亚马逊云科技可以快速推出新实例,得益于Amazon Nitro 实现了虚拟化卸载。 自研 Amazon Graviton-高性能低价格随着 Intel 这几年挤牙膏,服务器处理器的性价比提升放缓,尤其是能耗快速增长。亚马逊云科技推出 ARM 处理器 Amazon Graviton 2 和 3 系列。 最近分析 ARM 技术,推测应该采用的是 Nerverous V1 架构,代号 Zeus,比 N1 核性能提高 50%(实际 SVE 提升更大) 创新的云原生芯片设计理念:
Amazon Graviton 3 比 G2 增加 200 亿晶体管;但是处理器主频不增加,核数没变,推测战略定位如下:
ML芯片赋能AI场景
EFA 支持 SRD 协议,帮助客户优化 HPC、ML 并行能力,减少 TCP 通信开销占比。 云上创新技术赋能业务AI 赋能业务CTO 格言:每一行代码都是业务逻辑。从 OPPO 案例可以看到,采用云上 Amazon EC2-Inf1,快速构建语音助手的案例。 智能运维亚马逊云科技利用自身电商积累的经验,通过亚马逊云科技云服务帮助客户运维。包括对事件的分析、响应进行的机器学习.比如 trusted advisor,为客户提供超过 5000 万智能运维推荐。根据 Amazon 电商积累的经验,输出给客户,此外还有 IEM 等工具。 数据价值数据为客户创造这块儿也很精彩,可以让只懂 SQL 的人玩转 AI。先不做详述,我把回放链接放在文末,感兴趣可以了解下。 数据服务提供: 冷热数据快速恢复 思考和启发因为价值所以选择 通过为客户节约成本,创造业务价值,让亚马逊云科技受到全球用户欢迎。另外,云计算消耗占半壁江山的互联网企业,告别内卷奔赴全球化是 2022 年主题,全球化需要强大的安全、合规特性产品能力,需要全球网络。因此国内企业出海纷纷选择亚马逊云科技。 根据统计报告,虽然在国内市场亚马逊云科技只占 6%,但加上中国企业出海份额占到了 26%,足以说明亚马逊云科技强大的竞争力和客户粘性。 亚马逊云科技的秘籍你能学会吗IT 服务商存在的意义就是为客户创造价值。最后我提几个问题,你的企业文化真的是客户第一吗?今年营收 KPI 和客户粘性需要牺牲一个,你怎么选择? 破解了云计算增长之谜,亚马逊云科技的产品之道,你能学会吗? | |||||||||||||||||||||||||||||||||||||||
Posted: 07 Jun 2022 11:41 PM PDT 1、时间跨度为60分钟(1)时间区间为字符串有时候可能需要用到24小时的时间区间,跨度为60分钟,比如下面这样的:
如果手动去写,则有点麻烦,这个时候可以使用一个简单的 JS 函数去自动生成,示例代码如下:
当然,上面的方法,也可以简写成下面这样的,只需要一行代码即可
(2)时间区间为数组
生成的时间区间如下:
(3)时间区间为对象
生成的时间区间如下:
2、时间跨度为30分钟如果时间跨度为30分钟,也就是说1天24小时,需要分成48个时间区间。 (1)时间区间为字符串
生成的时间区间如下:
(2)时间区间为数组
生成的时间区间如下:
(3)时间区间为对象
生成的时间区间如下:
3、时间跨度任意指定除了常见的时间跨度为60分钟或者30分钟,有的时候还可能需要其他的时间跨度,那么是否可能写一个相对通用的方法,参数为时间跨度(以分钟为单位),当然是可以的,具体实现代码如下(这里仅生成时间区间为字符串的,其他格式参考上面):
比如想要生成时间跨度为120分钟的时间区间,可以直接传入120即可
生成的时间区间如下:
需要注意的是,如果时间跨度无法被整除,那么生成的时间区间可能无法完全覆盖24小时。 | |||||||||||||||||||||||||||||||||||||||
SegmentFault 思否技术周刊 -- Node.js 进阶之旅,看看那些还需要学? Posted: 07 Jun 2022 08:20 PM PDT 简单的说 Node.js 就是运行在服务端的 JavaScript。
| |||||||||||||||||||||||||||||||||||||||
Posted: 31 May 2022 07:59 PM PDT 任何一件事情,只要能沉浸进去,去感受其中的酸甜苦辣,总会从好奇到喜欢,从喜欢到厌烦,从厌烦到习惯 …… ——边城 十年前的今天,SegmentFault 思否正式创立,如一颗嫩绿的幼芽开始成长,期间承载过和煦的日光、沐浴过柔和的春风,也挑战过滂沱的暴雨、体会过凛冽的冬雪。所幸,今日呈现在我们面前的 SegmentFault 思否,已经长成了一棵足以抵御一些风雨的大树,这样的成长离不开各位管理员的修剪,更离不开社区每一位用户的栽种。 正如 SegmentFault 思否创始人之一祁宁所言: "SegmentFault 思否是一个属于大家的社区,因此,在这个特殊的时刻,我们想跟社区的成员一起为它喝彩。" 这十年中,有成千上万的开发者加入了 SegmentFault 社区,我们雀跃于看到每张不同的新面孔,也感动于社区里的那些老朋友们多年如一日的陪伴,见到他们就像见到一位相识多年的老友。或许老友们会在某一段时间里突然消失,但消失并不代表着再也不见,而是重逢后的那句:好久不见。 今天,我们有幸邀请到老朋友 @边城 参与我们的十年老友记系列访谈。 小编有话说: 在我加入思否后,经常能在社区中见到边城老师,他会在一段时间里突然沉默,又在某个时刻突然归来,频繁产出高质量高赞的文章。 采访中印象很深的一段是,他说思否已经不是当年的思否了,而他还是当年那个他。或许他一直觉得自己停留在原地,但他的 2355 篇问答和 107 篇文章,都是他一直在前进着的证明,而社区,就是最好的见证者。 他说,编程会带给他幸福感,同时,也会带给他一些焦虑。但在他的字里行间,都在传达着一个信息:编程带给他的快乐远远大过编程带给他的负面情绪。 我想,能从事自己热爱的职业并为之奋斗,是一件再治愈不过的事情。 以下为 SegmentFault 思否对边城的访谈内容: 1、还记得和 SegmentFault 思否的初识吗?是在什么样的机缘巧合下踏入这个社区的? 边城老师说他对自己的职业规划还很迷茫,但我想说的是,我们每个人都是在迷茫中慢慢摸索前进的,只要不停在原地,我相信未来的光总会照亮这段暂时昏黑的道路。 希望在下个十年,我们再次相遇的时候,都会感谢现在步履不停的自己。 | |||||||||||||||||||||||||||||||||||||||
Posted: 06 Jun 2022 07:30 PM PDT 今天,分享一个实际业务中能够用得上的动画技巧。 巧用逐帧动画,配合补间动画实现一个无限循环的轮播效果,像是这样: 看到上述示意图,有同学不禁会发问,这不是个非常简单的位移动画么? 我们来简单分析分析,从表面上看,确实好像只有元素的
到这里,你可以暂停思考一下,如果有 20 个元素,需要进行类似的无限轮播播报,使用 CSS 实现,你会怎么去做呢? 逐帧动画控制整体切换首先,我需要利用到逐帧动画效果,也被称为步骤缓动函数,利用的是
如果你对 好的,还是文章以开头的例子,假设我们存在这样 HTML 结构:
首先,我们实现这样一个简单的布局: 在这里,要实现轮播效果,并且是任意个数,我们可以借助
别看到上述有几个 CSS 变量就慌了,其实很好理解:
上述的效果,实际如下: 如果给容器添加上 这样,我们就得到了整体的结构,至少,整个效果是循环的。 但是由于只是逐帧动画,所以只能看到切换,但是每一帧之间,没有过渡动画效果。所以,接下来,我们还得引入补间动画。 利用补间动画实现两组数据间的切换我们需要利用补间动画,实现动态的切换效果。 这一步,其实也非常简单,我们要做的,就是将一组数据,利用 单独拿出一个来演示的话,大致的代码如下:
非常简单的一个动画: 基于上述效果,我们如果把一开始提到的 逐帧动画 和这里这个 补间动画 结合一下,ul 的整体移动,和 li 的 单个移动叠在在一起:
就能得到这样一个效果: Wow,神奇的化学反应产生了!基于 逐帧动画 和 补间动画 的结合,我们几乎实现了一个轮播效果。 当然,有一点瑕疵,可以看到,最后一组数据,是从第六组数据 transform 移动向了一组空数据: 末尾填充头部第一组数据实际开发过轮播的同学肯定知道,这里,其实也很好处理,我们只需要在末尾,补一组头部的第一个数据即可: 改造下我们的 HTML:
这样,我们再看看效果: Beautiful!如果你还有所疑惑,我们给容器加上 完整的代码,你可以戳这里:CodePen Demo -- Vertical Infinity Loop 横向无限轮播当然,实现了竖直方向的轮播,横向的效果也是一样的。 并且,我们可以通过在 HTML 结构中,通过 style 内填写 CSS 变量值,传入实际的 li 个数,以达到根据不同 li 个数适配不同动画:
整个动画的 CSS 代码基本是一致的,我们只需要改变两个动画的
这样,我们就轻松的转化为了横向的效果: 完整的代码,你可以戳这里:CodePen Demo -- Horizontal Infinity Loop 轮播图?不在话下OK,上面的只是文字版的轮播,那如果是图片呢? 没问题,方法都是一样的。基于上述的代码,我们可以轻松地将它修改一下后得到图片版的轮播效果。 代码都是一样的,就不再列出来,直接看看效果: 完整的代码,你可以戳这里:CodePen Demo -- Horizontal Image Infinity Loop 掌握了这个技巧之后,你可以将它运用在非常多只需要简化版的轮播效果之上。 再简单总结一下,非常有意思的技巧:
最后OK,本文到此结束,希望本文对你有所帮助 :) 想 Get 到最有意思的 CSS 资讯,千万不要错过我的公众号 -- iCSS前端趣闻 😄 更多精彩 CSS 技术文章汇总在我的 Github -- iCSS ,持续更新,欢迎点个 star 订阅收藏。 如果还有什么疑问或者建议,可以多多交流,原创文章,文笔有限,才疏学浅,文中若有不正之处,万望告知。 | |||||||||||||||||||||||||||||||||||||||
2022 前端开发报告:TypeScript 成 84% Web 开发者的“最爱”|无障碍性、边缘渲染成大趋势 Posted: 05 Jun 2022 09:30 PM PDT 近日,The Software House发布了一份"2022 前端开发市场状态调查报告"。 此次报告,共有来自全球 125 个国家 / 地区、超 3700+ 名前端开发专业人士填写了调查,同时也融合了来自前端技术开发领域的 19 位专家的观点与分享,并对前端 2020 年和 2022 年的数据并排呈现作对比后最终得出了一份调查结论。 调查结果显示,高达 56% 的受访者正在进行远程工作,其中仅 5% 在办公室工作。大规模远程工作的概念确实比较新颖,以至于 2020 年的调查甚至都没有对这个数据进行调查。 看得出,大多数工程师显然更喜欢远程工作,因为不需要通勤,不用面对随时随刻有人在肩膀上轻拍你而分散注意力的尴尬等等。然而,远程办公状态下,实时分享信息、复制群组消息及自发讨论等问题仍然是一项挑战。 前端开发较易"入门"此次调查结果中,发现了一个非常有意思的现象:做前端开发的人员,他自身并非仅仅是个前端工程师。据数据显示,在"其他"选项中共享的一些从事前端开发的职位包括:
虽然这个发现似乎有点不足为奇,但这可以很好地表明:前端技术领域是一个容易进入的领域,即使你此前并没有太多前端背景,但快速学习之后依然能参与进来。 开发者在更大的前端团队工作成常态据调查数据显示,有 27% 的受访者表示在一家拥有 50 多名前端工程师的公司工作。与此同时,30% 的开发者分享了 5 个或更少的前端开发者在他们公司的工作方式。50% 的受访者在拥有 10 名或以上前端工程师的公司工作。 这个统计数据也显示了一个有趣的现象:在有着大量前端团队公司工作的前端工程师,与在少数人团队或单独工作的公司的工程师数量几乎一样多。当然,这些公司的开发人员经验和期望大不相同:大公司将更多地拥有开发人员经验和前端平台团队。导师制更为常见;在较小的公司里,每个开发人员的责任更大,获得反馈的选项也会更少。 82% 的前端工程师来自科技型公司数据还显示,有 82% 的受访者被认定为在软件开发公司、开发机构或技术为主或数字为主公司工作。另外,仅 18% 的受访者表示他们在非科技型公司工作。 其中,来自软件开发公司/开发机构的工程师占比为 41.6%,技术为主/数字为主型公司的工程师占比为 41.2%。非技术型公司工程师占比为 12.3%,另外 2.9% 的工程师则来其他领域,1.9% 的工程师来自政府机构。 63% 的开发者关注前端的"无障碍性"根据调查数据,前端开发的"无障碍性"是今年受访者们普遍关注的重点:有 63% 的人预测它在未来几年会越来越受欢迎。而框架则正倾向于提供不同的方法来解决这个问题,其中就包括 Next/Nuxt Image、HTML validator 和 WebHint。 同时,组件驱动的开发也受到了大多数开发人员的欢迎,考虑到 React、Vue、Svelte 甚至 Web 组件的流行(如今年的独立成功案例——Wordle),这一点很有意义。 渐进式 Web 应用程序也越来越受欢迎,开发人员渴望使用相同的核心代码库充分利用跨平台开发。另外,Headless CMS (无头 CMS)也在不断进步,采用率越来越高,并更多地集成到框架中。 前端"边缘渲染"方案将成大趋势通过对 2020 年的调查数据与 2022 年今年的调查数据相比对之后,还发现了一个重要的趋势:前端性能优化的方案 —— 边缘渲染。 边缘渲染最初由 CloudFlare 及其 worker 平台驱动。此次调查的期间,大多数部署目标都发布或实现了自己的无服务器或边缘功能,用户很快就会采用这些功能,因此这一趋势并非偶然。 据悉,Nuxt 3、Remix 或 Sveltekit 等框架正朝着这个方向发展,直接在 CDN 级别支持按需渲染。随着服务器呈现的应用程序在减少延迟和降低成本方面的相应收益,由此可以预测这将是 2023 年的一大焦点。 前端开发者正从"Moment.js"转向"Date-FNS"此次调查结果还显示,在日期处理类库方面,如今的前端开发者们正在从"Moment.js"转向"Date-FNS"。 同时,超过 40% 的人仍然在他们的项目中使用 Moment,尽管该库已经失去了支持,甚至其官方网站上也有创作者留言说"如果你正在考虑使用 Moment,你可能应该寻找替代品"。仅 5% 的受访者希望继续使用该库,看来 Moment 确实正走向衰落。 调查结果中,Axios 网络请求库以超过 60% 的高"得票率",进入了稳定阶段。该库在前端市场已经有很长一段时间了,人们对此很清楚,它更像是一种"标准"而非"趋势"。 另外,由于 Apollo 用于与 GraphQL 的无缝连接,因此它在"使用过的和喜欢的"类别中得票也较高:40% 的开发人员希望在未来学习 Apollo ,这意味着 Apollo 社区正在稳步增长。 TypeScript 成 84% Web 开发者的"最爱"据调查数据显示,相比 2030 年, 2022 年也就是今年使用 TypeScript 的人数上升了 7 个百分点以上,已经达到了惊人的 84%! 看来大家都知道,TypeScript 如今已受到了广大开发人员的普遍欢迎,人们经常称赞"TypeScript 如何在 bug 发生之前就阻止了一整类 bug",这反过来又使得开发速度更快,应用程序更可靠。 那么,什么让这么多开发人员喜欢 TypeScript? 在经历了多年的 Web 开发之后,前端开发人员早就不想重复多次在代码编辑器和浏览器之间来回切换的经历,不用再猜测为什么"未定义不是功能"。 所以,TypeScript 不仅赢得了开发人员的心,而且还努力成为前端行业标准,它让 web 开发方式变得不再像以前那么让人沮丧了。 关于本次调查结果的更多详情,可查看完整报告。 | |||||||||||||||||||||||||||||||||||||||
Posted: 06 Jun 2022 01:19 AM PDT 在上家公司做IM消息系统的时候,一直是使用 WebSocket 作为收发消息的基础组件,今天就和大家聊聊在 Java 中,使用 WebSocket 所常见的四种姿势,如果大家以后或者现在碰到有要使用 WebSoocket 的情况可以做个参考。 上面的思维导图已经给大家列出了三种使用 WebSocket 的方式,下文会对它们的特点进行一一解读,不同的方式具有不同的特点,我们先按下不表。 本文代码:以下仓库中 spring-websocket 模块,拉整个仓库下来后可在 IDEA Maven 工具栏中单独编译此模块。
除了这几个优点以外,我觉得对于 WS 我们开发人员起码还要了解它的握手过程和协议帧的意义,这就像学习 TCP 的时候需要了解 TCP 头每个字节帧对应的意义一样。
那我们既然知道了 WS 主要有以上六种操作,那么一个正常的 WS 框架应当可以很轻松的处理以上这几种消息,所以接下来就是本文的中心内容,看看以下这几种 WS 框架能不能很方便的处理这几种 WS 消息。 J2EE 方式先来 J2EE,一般我把 javax 包里面对 JavaWeb 的扩展都叫做 J2EE,这个定义是否完全正确我觉得没必要深究,只是一种个人习惯,而本章节所介绍的 J2EE 方式则是指 Tomcat 为 WS 所做的支持,这套代码的包名前缀叫做:
接着就是将一个类定义为 WS 服务器,这一步也很简单,只需要为这个类加上
接下来我们来看具体的一个 WS 服务器类示例:
在以上代码中,我们着重关心 WS 相关的注解,主要有以下四个:
以上这几个方法重点可以来看一下 handleMessage 方法,handleMessage 方法中有一个
但是由于
但是总这样写也不是个事,为了避免这些重复性代码,Spring 给我们定义了一个
上面这部分都是对于 Handle 的操作,有了 Handle 之后我们还需要将它绑定在某个 URL 上,或者说监听某个 URL,那么必不可少的需要以下配置:
这里我把我的自定义 Handle 注册到 SocketIO 方式SocketIO 方式和上面两种有点不太一样,因为 SocketIO 诞生初就是为了兼容性作为考量的,前端的读者们应该对它更熟悉,因为它是一个 JS 库,我们先来看一下维基百科对它的定义: Socket.IO 是一个面向实时 web 应用的 JavaScript 库。它使得服务器和客户端之间实时双向的通信成为可能。他有两个部分:在浏览器中运行的客户端库,和一个面向Node.js的服务端库,两者有着几乎一样的API。 所以我觉得使用它更多是因为兼容性,因为 HTML5 之后原生的 WS 应该也够用了,然而它是一个前端库,所以 Java 语言这块并没有官方支持,好在民间大神已经以 Netty 为基础开发了能与它对接的 Java 库:
第二步就是配置一个 WS 服务:
大家在上文的配置中,可以看到设置了一些 Web 服务器参数,比如:端口号和监听的 path,并将这个服务启动起来,服务启动之后日志上会打印这样一句日志:
这就代表启动成功了,接下来就是要对 WS 消息做一些处理了:
我相信对于以上代码,前两个方法是很好懂的,但是对于第三个方法如果大家没有接触过 SocketIO 就比较难理解了,为什么
第四种方式?第四种方式其实就是 Netty 了,Netty 作为 Java 界大名鼎鼎的开发组件,对于常见协议也全部进行了封装,所以我们可以直接在 Netty 中去很方便的使用 WebSocket,接下来我们可以看看 Netty 怎么作为 WS 的服务器进行开发。
第二步的话就需要启动一个 Netty 容器了,配置很多,但是比较关键的也就那几个:
以上代码我们主要关心端口号和重写的
这里面的方法我都不说了,看名字就差不多知道了,主要是看一下这个类的泛型:TextWebSocketFrame,很明显这是一个 WS 文本消息的类,我们顺着它的定义去看发现它继承了 WebSocketFrame,接着我们去看它的子类: 总结洋洋洒洒五千字,有了收获别忘赞。
代码结构如上所示,应用代码分成了三个文件夹,分别放着三种方式的具体示例代码,在资源文件夹下的 templates 文件夹也有三个 HTML 文件,就是对应三种示例的 HTML 页面,里面的链接地址和端口我都预设好了,拉下来直接单独编译此模块运行即可。 | |||||||||||||||||||||||||||||||||||||||
Posted: 05 Jun 2022 05:48 AM PDT 同一份逻辑,不同人的实现的代码性能会出现数量级的差异; 同一份代码,你可能微调几个字符或者某行代码的顺序,就会有数倍的性能提升;同一份代码,也可能在不同处理器上运行也会有几倍的性能差异;十倍程序员不是只存在于传说中,可能在我们的周围也比比皆是。十倍体现在程序员的方法面面,而代码性能却是其中最直观的一面。 本文是《如何写出高性能代码》系列的第四篇,本文将告诉你数据访问会怎么样影响到程序的性能,以及如何通过变更数据访问的方式提升程序的性能。 数据访问速度为什么会影响到程序的性能? 程序的运行的每一个可以简化为这样一个三步模型:第一步,读数据(当然也有部分数据是别的地方法发过来的);第二步,对数据做处理;第三步,将处理完的结果写入存储器。这里我将这三步骤简称为 读算写。 实际上真实的CPU指令执行过程会稍微复杂有些,但实际上也是这三个步骤。 而一个复杂的程序包含无数个CPU指令,如果读取或者写入数据太慢,必然会影响到程序的性能。 CPU犹如大厨,而数据就是CPU的食材,寄存器里的数据就是CPU手边的食材,内存的数据就是在冷库的食材,固态硬盘(SSD)上的数据是还在菜市场的食材,机械硬盘(HDD)上的数据犹如还在地里生长的菜…… 如果CPU在运行程序时,如果拿不到所需要的数据,它也只能等在那儿浪费时间了。 数据访问速度对程序性能有多大影响?不同存储器数据读取和写入的时延相差极大,鉴于大多数场景下,我们都是读取数据,我们就只拿数据读取为例,最快的寄存器和最慢的机械磁盘,随机读写的时延相差百万倍。可能你没有直观概念,我们还是拿厨师做个类比。 假设厨师要做一道西红柿炒鸡蛋,如果食材都有人备好的话,只需要十来秒食材就能下锅炒制。 我们把这个时间比作是CPU从寄存器里取到数据的时间。然而如果是CPU从磁盘获取数据的话,所耗费的时间相当于厨师自己种出西红柿或者养小鸡下蛋了(3-4个月)。由此可见,从错误的存储设备上获取数据,会极大影响程序的运行速度。 再说一个我们之前在生产环境遇到的实际案例,我们在生产环境也出过故障。原因是这样的,我们有个服务容器化改造的时候,和上游服务没有部署在同一个机房,跨机房虽然只会增加1ms的时延,但他们服务代码写的有问题,有个接口批量串行调另外一个服务,串行累加导致接口时延增加上百ms。 本来没有性能问题的服务,就因为迁移了机房,导致性能出现了问题…… 各存储器性能差异 实际上在编码的时候,遇到的存储设备多种多样,寄存器、内存、磁盘、网络存储……,每种设备都有自己的特点。只有认识到各种存储器之间的差异,我们才能在正确的场景下使用合适的存储器。以下表格就是各类常见存储设备的随机读时延参考数据…… 备注:以上数据在不同硬件设备会有出入,这里只是为了展示其差异性,不代表准确值,准确信息请参考硬件手册。 虽然日常我们觉得内存的读取速度已经很非常快了,日常写代码的时候遇到啥数据获取比较慢,加个内存缓存速度简直就起飞了。但内存的访问速度相对于CPU运行速度来说还是太慢,读取一次内存的时间,都够CPU执行几百条指令了,所以现代CPU都对内存加了缓存。 如何减小数据访问时延对性能的影响? 减少数据访问时延对性能的影响也很简单,那就是把数据尽可能放到最快的存储介质上。然而,存取速度、容量、价格三者之间有着不可调和的矛盾,简单来说就是 速度越快容量越小但价格越贵,反之容量越大速度越慢而价格越便宜。
总结下这两点就是,程序大部分时间只会集中访问很小的一部分数据。 这意味着我们可以用较小的存储空间覆盖到大部分被访问的数据。 说直接点就是,我们可以加缓存。 实际上,不管是计算机硬件、数据库、还是业务系统,到处都充斥着缓存。甚至你写下的每一行代码,在机器上运行时都用到了缓存,不知道大家有没有关注过CPU,CPU有个参数,就是缓存大小,我们以intel酷睿i7-12650HX 为例,它就有24MB的三级缓存,这个缓存就是CPU到内存之间的缓存。 只不过现代计算机将底层的细节屏蔽掉了而已,我们日常不太可能主要的到。 在我们自己写代码的时候,也可以加缓存来提升程序性能。举个最近的我们在系统中遇到的例子,我们最新在做数据权限相关的功能,不同的员工在我们系统中有不同的权限,所以他们看到的数据也应该是不同的。我们的实现方式是每个用户请求系统的时候,首先获取到该用户所有的权限列表,然后把所有在权限列表中的数据展示出来。 因为每个人的权限列表比较大,所以权限接口的性能不怎么样,每次请求耗时也比较长。所以,我们直接给这个接口的数据加了缓存,优先从缓存里取,取不到再调接口,极大提升了程序性能。当然因为权限数据也不会经常变动,所以也不用太考虑数据滞后导致的后果。另外,我们缓存数据只加了几分钟,因为一个用户单次使用我们系统时长也就持续几分钟,过几分钟后数据过期缓存空间也会自动释放,达到节省空间的目的。 我在上大学那会,笔记本电脑还是标配机械硬盘的年代,那时候电脑永久了会很卡,后来了解到换装SSD会提升电脑性能,那个时候SSD还挺贵的,普通笔本都不会标配SSD后来我攒半个月的生活费给自己笔记本替换了一块120g的SSD,电脑的运行速度就有明显的提升,本质上还是因为SSD的随机访问时延比机械硬盘快上百倍的原因。 之前某大厂号称将mysql性能提升了上百倍,其实也是基于SSD做的很多查询优化。 缓存不是银弹银弹(英文:Silver Bullet),指由纯银质或镀银的子弹。在欧洲民间传说及19世纪以来哥特小说风潮的影响下,银色子弹往往被描绘成具有驱魔功效的武器,是针对狼人、吸血鬼等超自然怪物的特效武器。后来也被比喻为具有极端有效性的解决方法,作为杀手锏、最强杀招、王牌等的代称。
上文说到其实我们写下的每一行代码都用到了缓存,现在大家已经都知道这个缓存其实就是CPU的Cache。CPU的Cache也是有明显的副作用的,我们在写多线程代码的时候也不得不关注到,那就是多核CPU之间数据一致性的问题。因为CPU Cache的存在,我们写多线程代码时不得不考虑数据同步的问题,导致多线程的代码很难编写,出了问题也很难排查。 有个面试八股文题目其实就很容易说明这个问题——多线程计数器,多线程去操作计数器,累加统计数据,如何保证数据统计的准确性。如果只是简单使用cnt++实现,这里就会遇到多核CPU缓存导致的数据不一致性,具体原理这里不再解释,反正结果就是统计出来的数据会比真是数据少。 正确的做法就是,你必须在累加的过程中加多线程同步的机制,保证同一时刻只可能有一个线程在操作,操作完之后也能保证数据能写回内存,在java中必须使用锁或者原子类实现。而这对于编程新手而言又是一道门槛。 总结数据访问是任何程序不可或缺的一部分,甚至对大多数程序而言时间都耗费在了数据访问的过程上,所以只要优化了这部分的耗时,程序的性能必然能得到提升。 本文全部内容就到这了,下一篇,我们将继续探讨下性能优化到极致该怎么做,敬请期待!!另外,有兴趣也可以查阅下之前的几篇文章。 如何写出高性能代码系列文章 |
You are subscribed to email updates from SegmentFault 最新的文章. To stop receiving these emails, you may unsubscribe now. | Email delivery powered by Google |
Inbox too full? ![]() | |
Google, 1600 Amphitheatre Parkway, Mountain View, CA 94043, United States |
No comments:
Post a Comment