好了,在简单探索完基础类型之后,我们就来看一下我们最关心的Struct吧!
1. 简单结构体
我们先从最简单的开始,先定义一个简单的结构体,里面错落的放一些大小不一的字段:
1 | type A struct { |
然后定义一个变量a,再用上篇文章中的DumpObject函数来看一下其内存布局:
1 | Var Type Address RootOffset LocalOffset Size |
好了,在简单探索完基础类型之后,我们就来看一下我们最关心的Struct吧!
我们先从最简单的开始,先定义一个简单的结构体,里面错落的放一些大小不一的字段:
1 | type A struct { |
然后定义一个变量a,再用上篇文章中的DumpObject函数来看一下其内存布局:
1 | Var Type Address RootOffset LocalOffset Size |
也许是从C++转过来的习惯,学习一门语言,我总是比较喜欢先弄明白它的对象模型,所以自己就做了一些简单的实验,看看Go的对象模型~
为了查看对象的内存布局,我们这里先写一个非常简单的小函数,利用反射递归地遍历对象的所有成员,然后输出其内存位置,从而了解其在内存中的真实状态。
1 | func PrintObjectDumpTableHeader() { |
这样,我们就可以非常简单的调用这个函数来查看任何对象的内存布局了,如下:
1 | PrintObjectDumpTableHeader() |
最近难得放假,想好好学习一下Go,毕竟C++用的我欲仙欲死,而平时比较常用的.NetCore也不是编译语言(Compiled Language),经常遇到一些神奇的限制……
学一门新语言说容易也容易,毕竟语法也就那么一些,而且Go非常精简,只有仅仅25个保留字,但是说难也难,要真正理解一门语言真的需要花费不少的心思,特别我属于那种不了解到一定程度连用都不敢用的人(在工作中经常因为需要使用一些库,就把这些库的实现通读一遍……),于是查找了不少的学习资料。我觉得这些资料对于新手上路真的非常有用,所以把他们都记录在这,希望也会对其他对Go感兴趣的朋友有所帮助。
那就让我们开始吧!
首先,我们先从最基础的开始:
至此,基础入门肯定是没有问题了,但是如果你是从C/C++这种比较传统的编译语言转过来的,估计到这里会一头雾水 —— 语法我都懂了,但是为什么呢?比如,为什么Go的struct成员变量和函数不提供const修饰?为什么没有信号量?使用嵌入代替继承看着很好,但是多态用起来经常却经常踩坑?这些问题我们就需要更多的资料来帮忙了。
服务扩展是几乎每个做后台服务的开发都遇到过的问题,当业务大到一定的水平,当前的服务快要承受不住业务压力的时候,我们就要进行扩展了。一聊起服务扩展,很多人的第一想法都是增加运行实例,但是服务扩展有很多种方法,增加实例只是里面最简单的一种,而有时增加实例并不能改善问题,反而会让情况变得更糟。最近我们项目也在做类似服务扩展的事情,所以想把我之前学的东西大概总结一下,希望也能对项目有所帮助。内容比较粗浅,希望大家不要介意~
在对服务扩展时,我发现有些原则如果扩展过程中可以遵守,对整个过程会很有帮助,所以在讨论具体的方法论之前,我们先来了解一下它们。
首先,我们必须得了解一个事实——业务才是解决用户问题的核心,后台服务的目的是为业务提供支撑。因为如此,一个后台的架构好不好并不是看它看起来有多么的华丽,有没有用到最前沿的技术,有什么技术情节和情怀,而是看它是不是能真正好的服务于产品,服务于业务,所以无论是后台服务的设计还是扩展,都必须由业务驱动,而所有的架构和设计都必须是为了解决实际的问题。有技术追求是好事,但是千万不要为了技术而技术,为了架构而架构。
在执行业务驱动的时候,有两个理论特别好用:奥卡姆剃刀和康威定律。
很多时候我们在设计服务的时候都会纠结,一些地方要不要设计的更灵活一些,但是如果真的那么设计了,实现起来可能会复杂很多,这里我们就可以运用奥卡姆剃刀了。奥卡姆剃刀告诉我们:“如无必要,勿增实体”。要是一个服务可有可无,那么我们就把他砍掉,千万不要为了架构而架构,并不是越大型的架构就越好,后面我们说折中的时候会更详细的讨论这一点。不过,也请不要忘记奥卡姆提出奥卡姆剃刀时的后半句话,过分精简也是不好的。所以请了解自己的业务,做出最适合自己业务的决定。
另外在设计服务的时候,还要注意康威定律的使用。康威定律告诉我们:软件架构是组织架构的一种反映。所以在做任何服务设计和扩展时,我们都应该把组织架构考虑进去,这样我们才能设计出真正“高内聚,低耦合”的服务,让组织之间的沟通成本降到最低。
两年半没有更新过博客了,趁着最近难得的假期赶紧除除草,结果发现………………之前给hexo写的包有各种神奇的bug,于是更新博客变成了修bug…………然后对于我这种超级懒人,烦人的事情就来了————每次在本地执行npm的命令发布安装包真的好烦人,要是可以自动化就好了,于是就抱着试一试的心情看了一下Azure Pipeline,结果工作的相当好,而且还在一定额度之内免费(对我来说真的够用了)!所以在这里记录一下,也算是个安利了~
这里就拿我的hexo-asset-path举例子吧(https://github.com/r12f/hexo-asset-path)。
因为hexo-asset-path的代码在github上,所以在使用Azure Pipeline之前需要先在Azure DevOps上创建一个项目。没有账号的童鞋可以和我一样直接用GitHub的账号注册。
在登录之后的主界面上点击右上角的“New Project”按钮就可以创建新项目了。
Azure Pipeline是一个非常强大而且部分免费的编译和发布工具,我们可以用它来连接GitHub或者Azure DevOps上的项目进行CI和CD的实践。我们经常需要的一个功能就是在CI Build中自动升级版本号,而在Azure Pipeline中,这个功能的实现却不是那么的直接,在尝试了多种方法之后,我终于找到了一种简单而且有效的方法,于是记录一下。
以前从未真正接触过技术团队的管理,所以趁着年末假期,先选了一本比较简单的书入个门。这本书写的比较浅显,但是非常适合第一次接触技术管理的人来读,能帮助新人迅速建立起一些概念,避免很多雷区,虽然有很多不足的地方,不过都还算可以接受,毕竟这种书主要就是看个思想,细节并不是那么的重要,比如结尾的例子结束的过于唐突,看完的时候还以为是我看的版本不全;比如很多技术介绍的部分过于泛泛,比如研发管理体系,另外有些技术也有点过于落后,作为2018年出版的书,源码管理还在讨论vss和cvs,这些难以让读者对其产生同感和共鸣;此外有些观念我也不是特别的认同,比如技术和架构的进化,我觉得理解成演化会更加合适,也能帮助理解技术并没有有高下之分,而主要在于使用的场景。不过总之,对于刚接触基础管理的人来说,这本书还是值得一读的。
和以前一样,读完之后也还是在这里稍稍把这本书的知识点总结一下,方便以后复习:
虽然之前做过后台开发,很喜欢微服务的概念,也用了部分微服务的思想,但是回头再看之前很多事情的做法,觉得路子还是相当野的,特别是在微软呆了几年之后,对于Engineering System的理解加深了不少。最近看到了这本书,感觉算是对于这种后台设计思路有了一个非常好的总结,所以写一个小博客把所有的知识点总结一下。
在了解了如何注入API之后,我们来看一下一些比较复杂的JSRT API的用法吧。
在这一篇里,我们会来尝试做如下几件事情:
Javascript现在在后台都如此被广泛的应用,其最大的好处就在于方便实现异步调用,随着promise和async function的加入,现在在JS中实现异步也越来越方便,代码逻辑也越来越清晰,那么现在我们也来跟上时代,把我们的storage.get API改造成promise吧。
首先,我们把我们注入的API修改成promise的形式,内部实现我们依然可以使用回调函数,这样我们C++的实现部分就不需要做任何的修改:
1 | class APIStorageGet : public API |
在大概了解了ChakraCore的顶层结构和其对应的JSRT API之后,让我们再来看看其他的JSRT API和如何使用它们吧。
为了演示JSRT API,在这一篇里,我们会来尝试如下几件事情:
选择这几个目标的原因是因为——毕竟不管在源码层面使用什么脚本引擎,大家一开始最关注的还是怎么注入自己的API来完成自己想要做的事情呀。
首先让我们建立一个最简单的程序作为开始吧:
1 | ##include "stdafx.h" |