Blog
Blog
PHODAL

Viewing posts from May, 2018

就我而言,一年里我也没写出几篇让自己满意的文章。因为写一篇好的技术文章真的很难。

很遗憾的是,在今日的我看来,仍旧是两年前的那个观点:全栈是未来。这次并不是因为大公司全职业,小公司全栈,而是技术的门槛越来越低——人工智能 API 化、后端无服务器、跨平台应用。 在过去的一年里,我的主业仍然是前端开发。而如大家所见,我在这些日子里,也尝试了不同的技术领域移动开发,如 React Native 乃至于原生的 Android 开发,又或者是使用 Serverless 开发的后台应用。尽管仍遇到一些大大小小的挑战,这样一来,也有一些新的收获。不免还是觉得自己还是幸运的,不是在四年的工作里重复一年的工作经验。 很遗憾的是,在今日的我看来,仍旧是两年前的那个观点:全栈是未来。这次并不是因为大公司全职业,小公司全栈,而是技术的门槛越来越低——人工智能 API 化、后端无服务器、跨平台应用。 跨平台移动应用 --- 跨平台,一种特别有意思的技术,它在底层上个隔离了不同系统,因此也在某种程度降低了开发难度。 也因此能支撑越来越多的开发人员,更容易走上全栈的道路。它可以是使用同一种语言,如使用 JavaScript 可以开发前端、后端、移动端的应用;它也可以是使用某一特定的技术栈,如 React 来开发不同类型的应用。 过去,我们可以使用 jQuery 来开发前端 UI 界面,使用 jQuery Mobile 来开发混合移动应用。后来,当这样的移动应用性能不行时,又出现了 React Native、NativeScript、Flutter 等等。但是不论是使用哪种跨平台技术,它都意味着在这个领域,技术的门槛已经越来越低了——当然了,位于底层的开发人员,仍然有着相当的门槛。对于一般的跨平台移动应用,仍然面临着不少的兼容性、安装量和崩溃问题。 更进一步的,还有最近两年大火的微信小程序——它可以让开发人员,快速的开发**轻量级**的跨平台应用。 后端无服务器 --- 对于中小公司来说,小程序可以说是一种非常 MVP 的方式。 同样的,适用于后端快速开发的 Serverless 技术,也是一种快速的验证方式。而,它与一般的 MVP 不同的是:它可以自动扩容,能快速满足大量用户访问的需求。 Serverless 技术见证的是 DevOps 技术的不断提升,运维的门槛不断的降低。从过去的手动部署,到各种类型的自动部署,再到各式各样的虚拟化技术的使用。直到今天,使用 Serverless 技术,就可以直接将函数部署到服务器上,直接运行。 又诸如适用于小程序的 Wafer2,也是一个符合国情的,其是基于腾讯云强大的 IaaS 能力搭建了一个 PaaS 小程序解决方案,用户只需要开通,即可使用开发者工具上传、部署、调试小程序后端代码,无需了解服务器运维、数据库部署搭建即可使用。 有兴趣的读者可以访问:[https://serverless.ink](https://serverless.ink) 了解更多 Serverless 技术相关的实践。 人工智能 API 化 --- 在上次,我使用 Serverless + 小程序开发 “代码协作” 应用的时候,引入了对图片进行文本识别,以实现代码识别的功能。计算机视觉作为人工智能的一部分,它在使用上与传统 API 并没有太大的区别。并且,在这一领域已经有相当多成熟的开源软件,如 Tensorflow。 而,我在使用 AWS Rekognition 作为图片识别引擎时,我并不需要过多关注底层的细节。而当我在实现一些简单的推荐系统时,我也只需要在现有的算法上做一些微调。而随着 AI 的 API 不断的丰富,也就同上面的服务端与大前端一样,门槛会不断的降低。这时,如果使用自己的服务器和别人的服务没有太大的区别,那么使用别人的服务反而早期成本更低。 值得注意的是,人工智能时代**最值钱的不是算法,而是数据**。 结论 --- 尽管多种领域开发的门槛越来越低,但是在关键时候还是要掌握自己的核心技术。 末了,顺便推荐一下我去年写的《全栈应用开发:精益实践》

结束了五一国庆的八天假期后,便开始着手为微信小程序《代码协作》制作一个图片识别代码的功能。这个需求的主要来源是,在有的公司、组织、团队上,代码是不能直接拷贝出来的。但是,拍照是允许的。为了协作方便,一般会拍照在微信群里讨论。对于我而言,因此这样一个真实需求的存在,我便想试试能不能做这样的一个功能。

之前做过一个 Angular 下的路由重用,即记录 SPA 应用的上一个页面的内容。最开始的时候,并没有考虑 Lazyload,因此实现起来就比较简单: ``` export class SimpleReuseStrategy implements RouteReuseStrategy { public static handlers: { [key: string]: DetachedRouteHandle } = {}; public shouldDetach(route: ActivatedRouteSnapshot): boolean { return true; } public store(route: ActivatedRouteSnapshot, handle: DetachedRouteHandle): void { SimpleReuseStrategy.handlers[route.routeConfig.path] = handle; } public shouldAttach(route: ActivatedRouteSnapshot): boolean { return !!route.routeConfig && !!SimpleReuseStrategy.handlers[route.routeConfig.path]; } public retrieve(route: ActivatedRouteSnapshot): DetachedRouteHandle { if (!route.routeConfig) { return null; } return SimpleReuseStrategy.handlers[route.routeConfig.path]; } public shouldReuseRoute(future: ActivatedRouteSnapshot, curr: ActivatedRouteSnapshot): boolean { return future.routeConfig === curr.routeConfig; } } ``` 后来项目中添加了 Lazyload,因此便添加了一个 reusePath 的参数来控制是否缓存,最后实现如下: ``` export class SimpleReuseStrategy implements RouteReuseStrategy { public static handlers: { [key: string]: DetachedRouteHandle } = {}; public shouldDetach(route: ActivatedRouteSnapshot): boolean { if (!!route.data && !!route.data.reusePath) { return true; } return false; } /** 当路由离开时会触发。按reusePath作为key存储路由快照&组件当前实例对象 */ public store(route: ActivatedRouteSnapshot, handle: DetachedRouteHandle): void { SimpleReuseStrategy.handlers[route.data.reusePath] = handle; } /** 若 path 在缓存中有的都认为允许还原路由 */ public shouldAttach(route: ActivatedRouteSnapshot): boolean { if (!!route.data.reusePath && !!SimpleReuseStrategy.handlers[route.data.reusePath]) { return true; } return false; } /** 从缓存中获取快照,若无则返回nul */ public retrieve(route: ActivatedRouteSnapshot): DetachedRouteHandle { if (!!route.data && !!route.data.reusePath) { return SimpleReuseStrategy.handlers[route.data.reusePath]; } return null; } /** 进入路由触发,判断是否同一路由 */ public shouldReuseRoute(future: ActivatedRouteSnapshot, curr: ActivatedRouteSnapshot): boolean { if (future.data && curr.data && future.data.reusePath && curr.data.reusePath) { return future.data.reusePath === curr.data.reusePath; } return false; } } ``` 为了保存路由,需要单独额外的 在 Routing 里 添加一个 key : ``` const routes: Routes = [ { data: { reusePath: 'hello/hello' }, path: 'hello/hello', loadChildren: './hello/hello.module#CheckinModule' } ] ```

最近几天,博客所使用的 EC2 服务器一直不稳定。最开始,我以为是又双双叕叕叕敠被攻击了。

Feeds

RSS / Atom

最近文章

关于作者

Phodal Huang

Engineer, Consultant, Writer, Designer

ThoughtWorks 技术专家

工程师 / 咨询师 / 作家 / 设计学徒

开源深度爱好者

出版有《前端架构:从入门到微前端》、《自己动手设计物联网》、《全栈应用开发:精益实践》

联系我: h@phodal.com

微信公众号: 最新技术分享

存档

分类

标签

作者