• 关于

    结构可控性什么意思

    的搜索结果

回答

楼主这是节点遍历时,通过函数指针动态加载节点处理函数的设计方法。这个几年前写过,后来不这么写了。主要有以下几个问题。 1、每个节点被访问时,操作可能不一样,通用的函数指针的入口参数,要么可变参,要么多套,入口指针,都是很繁琐的事情,把代码逻辑结构搞的会更复杂。 2、操作函数和操作对象没有绑定,这个在规模开发时,很容易引起混乱。这样设计的代码,我自己到后面都觉得混乱,更别说基于我的架子让别人开发,楼主你的例子不够复杂可能感觉不到。 3、上面两个问题,也导致,代码复用率不高。 现在我的设计思想,如果是基础的数据结构,如同你这个例子中就是个线形表,我都全部独立成模版,在头文件中。 特定数据的处理不会和处理方法绑定,而是调用不同通用模块来处理,这样是尽可能的让数据和处理松耦合。而关联数据再怎么关联,处理时,也是一类整体处理的,同时一批数据再怎么复合,总可以拆成不同大部分串联处理(例如,读取、处理、写出,通过增加cache的方式可以分批分步骤完成,而不是读、处理、写 、一个完整操作周期,仅针对一个单元)。所以这类数据的整体处理落在通用模块里,通过数据和处理的紧耦合的提升效率。 ###### 另外,补充说一下,楼主的函数式风格,和我的函数式风格理解相差颇大。我的理解如下,所谓函数式风格,是将一批数据的若干处理,分解为正交串接的多个子步骤,每个步骤都是对整体数据的某个操作的实现。楼主的方案实质是对一个处理,可以挂接不同的操作方法。 我的理解函数式的风格在于每个独立模块处理极少的有逻辑关联的操作,可以看作针对一个数据池的原子操作。依次将数据池的数据灌入不同的独立模块,实现数据处理。当然差异的模块调用顺序和不同处理模块的组合,可以有不同的效果。 但无论如何,都是函数与数据松耦合的设计。这个和面向对象是反过来的。 ######相互嵌套耦合,牵一发动全身######楼主的代码有很浓重的其他语言的味道######楼主文章不错,我看现在的C模块基本就是你所说的面向对象风格,其实就是用数据结构组织起来。###### 引用来自“中山野鬼”的答案 楼主这是节点遍历时,通过函数指针动态加载节点处理函数的设计方法。这个几年前写过,后来不这么写了。主要有以下几个问题。 1、每个节点被访问时,操作可能不一样,通用的函数指针的入口参数,要么可变参,要么多套,入口指针,都是很繁琐的事情,把代码逻辑结构搞的会更复杂。 2、操作函数和操作对象没有绑定,这个在规模开发时,很容易引起混乱。这样设计的代码,我自己到后面都觉得混乱,更别说基于我的架子让别人开发,楼主你的例子不够复杂可能感觉不到。 3、上面两个问题,也导致,代码复用率不高。 现在我的设计思想,如果是基础的数据结构,如同你这个例子中就是个线形表,我都全部独立成模版,在头文件中。 特定数据的处理不会和处理方法绑定,而是调用不同通用模块来处理,这样是尽可能的让数据和处理松耦合。而关联数据再怎么关联,处理时,也是一类整体处理的,同时一批数据再怎么复合,总可以拆成不同大部分串联处理(例如,读取、处理、写出,通过增加cache的方式可以分批分步骤完成,而不是读、处理、写 、一个完整操作周期,仅针对一个单元)。所以这类数据的整体处理落在通用模块里,通过数据和处理的紧耦合的提升效率。 你说的问题#1和文章中函数式风格一节抱怨employee_read无法和Callback兼容的问题是类似的,说到底就是因为C语言静态类型等语法特性导致了对函数式风格支持不好;同时也反向说明了为什么大多数支持函数式风格的语言会选择“动态类型”,并且支持灵活的可变个数参数等特性,都是为了辅助函数式风格的编码。 #2这一点我不太同意。C语言里虽然没有类的概念把数据和函数在语法层次上绑定在一起,但通过规范地命令提供隐喻,比如代码中,所有操作Employee对象的函数都以employee_前缀开头。而且,这些接口之间也有层级关系,符合下表描述的抽象屏障。如果你把Employee相关的声明、操作独立出来放在一个文件里,然后头文件里只放置公开的接口信息,这样就变得简洁多了。 最高层:使用API的程序 main 基于Employee的接口实现的高级操作 employee_print, employee_adjust_salary 基于最底层的C,对象Employee的最基础的操作,包括读入、释放、遍历等 employee_read, employee_free, foreach, with_open_file C语言本身提供的最底层的工具 struct Empoloyee, for, free, calloc... 例如C语言自带的操作文件的接口同样符合这样的抽象屏障:我们只需要使用fopen、fclose、fread、fwrite等一系列操作FILE对象的接口,无需关心FILE结构体里有些什么内容,表示什么意思,以及各个接口是怎么实现的。 #3的确是一个问题,而且我在文章里也可以没有提及,因为这不是这篇文章要表达的重点。它最本质的问题在于将集合的数据结构和单个对象的信息保存在同一个地方。其他语言,例如Java的java.util.*容器、C++的STL容器,都符合你的设计,将容器这个单一职责抽象出来。当然,我自己实际的工作也是这样做的。 ###### 引用来自“中山野鬼”的答案 另外,补充说一下,楼主的函数式风格,和我的函数式风格理解相差颇大。我的理解如下,所谓函数式风格,是将一批数据的若干处理,分解为正交串接的多个子步骤,每个步骤都是对整体数据的某个操作的实现。楼主的方案实质是对一个处理,可以挂接不同的操作方法。 我的理解函数式的风格在于每个独立模块处理极少的有逻辑关联的操作,可以看作针对一个数据池的原子操作。依次将数据池的数据灌入不同的独立模块,实现数据处理。当然差异的模块调用顺序和不同处理模块的组合,可以有不同的效果。 但无论如何,都是函数与数据松耦合的设计。这个和面向对象是反过来的。 我认为你说的是“责任单一原则”,让每个函数、每个模块责任都尽可能地单一,然后通过类似搭积木一样的灵活组合,完成不同的任务。就像UNIX下的命令,每个单独命令都只完成一件事情,通过管道等把这些功能单一的命令组织在一起,协作完成一个复杂的任务! 我个人认为这是一种设计思想,和源自Lambda演算的函数式风格并没有太大关系。 ###### 引用来自“杨同学”的答案 楼主的代码有很浓重的其他语言的味道 因为其他语言也能写“面向对象风格”和“函数式风格”的代码,并且看起来比C更“专业”。 ###### 引用来自“优游幻世”的答案 楼主文章不错,我看现在的C模块基本就是你所说的面向对象风格,其实就是用数据结构组织起来。 嗯,将数据和操作数据的方法集中在一起会让代码更容易维护。 就像我在六楼回复里提到的,很多C模块往往还会更进一步,把容器和对象也分离开来。这样容器能容纳各种不同的对象,对象则只保留数据本身,不关心和其他对象是以什么形式组织在一起的。 ###### 引用来自“redraiment”的答案 引用来自“中山野鬼”的答案 楼主这是节点遍历时,通过函数指针动态加载节点处理函数的设计方法。这个几年前写过,后来不这么写了。主要有以下几个问题。 1、每个节点被访问时,操作可能不一样,通用的函数指针的入口参数,要么可变参,要么多套,入口指针,都是很繁琐的事情,把代码逻辑结构搞的会更复杂。 2、操作函数和操作对象没有绑定,这个在规模开发时,很容易引起混乱。这样设计的代码,我自己到后面都觉得混乱,更别说基于我的架子让别人开发,楼主你的例子不够复杂可能感觉不到。 3、上面两个问题,也导致,代码复用率不高。 现在我的设计思想,如果是基础的数据结构,如同你这个例子中就是个线形表,我都全部独立成模版,在头文件中。 特定数据的处理不会和处理方法绑定,而是调用不同通用模块来处理,这样是尽可能的让数据和处理松耦合。而关联数据再怎么关联,处理时,也是一类整体处理的,同时一批数据再怎么复合,总可以拆成不同大部分串联处理(例如,读取、处理、写出,通过增加cache的方式可以分批分步骤完成,而不是读、处理、写 、一个完整操作周期,仅针对一个单元)。所以这类数据的整体处理落在通用模块里,通过数据和处理的紧耦合的提升效率。 你说的问题#1和文章中函数式风格一节抱怨employee_read无法和Callback兼容的问题是类似的,说到底就是因为C语言静态类型等语法特性导致了对函数式风格支持不好;同时也反向说明了为什么大多数支持函数式风格的语言会选择“动态类型”,并且支持灵活的可变个数参数等特性,都是为了辅助函数式风格的编码。 #2这一点我不太同意。C语言里虽然没有类的概念把数据和函数在语法层次上绑定在一起,但通过规范地命令提供隐喻,比如代码中,所有操作Employee对象的函数都以employee_前缀开头。而且,这些接口之间也有层级关系,符合下表描述的抽象屏障。如果你把Employee相关的声明、操作独立出来放在一个文件里,然后头文件里只放置公开的接口信息,这样就变得简洁多了。 最高层:使用API的程序 main 基于Employee的接口实现的高级操作 employee_print, employee_adjust_salary 基于最底层的C,对象Employee的最基础的操作,包括读入、释放、遍历等 employee_read, employee_free, foreach, with_open_file C语言本身提供的最底层的工具 struct Empoloyee, for, free, calloc... 例如C语言自带的操作文件的接口同样符合这样的抽象屏障:我们只需要使用fopen、fclose、fread、fwrite等一系列操作FILE对象的接口,无需关心FILE结构体里有些什么内容,表示什么意思,以及各个接口是怎么实现的。 #3的确是一个问题,而且我在文章里也可以没有提及,因为这不是这篇文章要表达的重点。它最本质的问题在于将集合的数据结构和单个对象的信息保存在同一个地方。其他语言,例如Java的java.util.*容器、C++的STL容器,都符合你的设计,将容器这个单一职责抽象出来。当然,我自己实际的工作也是这样做的。 第二个问题其实是不同设计思想的核心问题。你举的例子只能说是些简单的系统中的模块。如果是个大系统中的底层模块特别是引擎方面(会产生数据加工的),这种方法最终组合出来的系统,会比面向对象出来的类套类更复杂。说实话,还不如用面相对象实现。 面向对象,是将数据和操作,进行耦合,并且封装在类里面。这种做法是有它的好处的。这样不会导致数据和操作之间出现问题。而c如果这么写,说实话还不如用c++的类进行实现,因为类描述这些逻辑更为清晰,而且语法和编译器可以帮你做大量的事情。 而相反面向数据,是一批数据(不是一个具体数据单元),存在一批不同操作。如何分析数据之间的无关性和前后操作的无关性是重点,这两个分析清楚,那么并发计算,和分步骤计算就得以实现。并发计算不谈,分步骤计算的思想就是原子操作,或者微指令集管道设计思想。这样设计,可以令复杂的数据处理,根据流程细分到步骤,每个步骤细分到子步骤单元,而每个子步骤单元只负责处理,不负责数据的格式问题。 上面这段的设计思想和面向对象是反过来的,数据和操作松耦合。数据的特殊性导致的操作,是通过各种操作模块组合调用实现(这些操作模块可以看作上面独立的子步骤单元和外部特定数据结构无关的)。 这样做的好处是,模块的设计,可以独立进行,让外部数据格式依赖自身,而不是操作对应数据格式(面向对象是后者,成员变量类型决定了成员函数的实际操作),模块复用率高,同时是整批数据处理,只要数据流程(调用不同模块的系统设计良好),运行效率会很高。而且便于并发操作。 并发操作并不单单是一批数据,分层几组让同一个操作的多个进程处理。流水线技术的使用,一样可以实现。 这里顺带喷下hadoop。貌似hadoop的map reduce并没有在流水线方面有什么突破的思路,这块需要考虑到不同计算单元之间数据流动的费用, hadoop整天扯分布计算,根本不考虑数据整体计算周期内的相关性的问题,基本上都是推给用户自己处理,而用户应该无法控制具体计算硬件设备,最后能有好效果就扯淡了。

kun坤 2020-06-10 09:29:21 0 浏览量 回答数 0

回答

楼主这是节点遍历时,通过函数指针动态加载节点处理函数的设计方法。这个几年前写过,后来不这么写了。主要有以下几个问题。 1、每个节点被访问时,操作可能不一样,通用的函数指针的入口参数,要么可变参,要么多套,入口指针,都是很繁琐的事情,把代码逻辑结构搞的会更复杂。 2、操作函数和操作对象没有绑定,这个在规模开发时,很容易引起混乱。这样设计的代码,我自己到后面都觉得混乱,更别说基于我的架子让别人开发,楼主你的例子不够复杂可能感觉不到。 3、上面两个问题,也导致,代码复用率不高。 现在我的设计思想,如果是基础的数据结构,如同你这个例子中就是个线形表,我都全部独立成模版,在头文件中。 特定数据的处理不会和处理方法绑定,而是调用不同通用模块来处理,这样是尽可能的让数据和处理松耦合。而关联数据再怎么关联,处理时,也是一类整体处理的,同时一批数据再怎么复合,总可以拆成不同大部分串联处理(例如,读取、处理、写出,通过增加cache的方式可以分批分步骤完成,而不是读、处理、写 、一个完整操作周期,仅针对一个单元)。所以这类数据的整体处理落在通用模块里,通过数据和处理的紧耦合的提升效率。 ###### 另外,补充说一下,楼主的函数式风格,和我的函数式风格理解相差颇大。我的理解如下,所谓函数式风格,是将一批数据的若干处理,分解为正交串接的多个子步骤,每个步骤都是对整体数据的某个操作的实现。楼主的方案实质是对一个处理,可以挂接不同的操作方法。 我的理解函数式的风格在于每个独立模块处理极少的有逻辑关联的操作,可以看作针对一个数据池的原子操作。依次将数据池的数据灌入不同的独立模块,实现数据处理。当然差异的模块调用顺序和不同处理模块的组合,可以有不同的效果。 但无论如何,都是函数与数据松耦合的设计。这个和面向对象是反过来的。 ######相互嵌套耦合,牵一发动全身######楼主的代码有很浓重的其他语言的味道######楼主文章不错,我看现在的C模块基本就是你所说的面向对象风格,其实就是用数据结构组织起来。###### 引用来自“中山野鬼”的答案 楼主这是节点遍历时,通过函数指针动态加载节点处理函数的设计方法。这个几年前写过,后来不这么写了。主要有以下几个问题。 1、每个节点被访问时,操作可能不一样,通用的函数指针的入口参数,要么可变参,要么多套,入口指针,都是很繁琐的事情,把代码逻辑结构搞的会更复杂。 2、操作函数和操作对象没有绑定,这个在规模开发时,很容易引起混乱。这样设计的代码,我自己到后面都觉得混乱,更别说基于我的架子让别人开发,楼主你的例子不够复杂可能感觉不到。 3、上面两个问题,也导致,代码复用率不高。 现在我的设计思想,如果是基础的数据结构,如同你这个例子中就是个线形表,我都全部独立成模版,在头文件中。 特定数据的处理不会和处理方法绑定,而是调用不同通用模块来处理,这样是尽可能的让数据和处理松耦合。而关联数据再怎么关联,处理时,也是一类整体处理的,同时一批数据再怎么复合,总可以拆成不同大部分串联处理(例如,读取、处理、写出,通过增加cache的方式可以分批分步骤完成,而不是读、处理、写 、一个完整操作周期,仅针对一个单元)。所以这类数据的整体处理落在通用模块里,通过数据和处理的紧耦合的提升效率。 你说的问题#1和文章中函数式风格一节抱怨employee_read无法和Callback兼容的问题是类似的,说到底就是因为C语言静态类型等语法特性导致了对函数式风格支持不好;同时也反向说明了为什么大多数支持函数式风格的语言会选择“动态类型”,并且支持灵活的可变个数参数等特性,都是为了辅助函数式风格的编码。 #2这一点我不太同意。C语言里虽然没有类的概念把数据和函数在语法层次上绑定在一起,但通过规范地命令提供隐喻,比如代码中,所有操作Employee对象的函数都以employee_前缀开头。而且,这些接口之间也有层级关系,符合下表描述的抽象屏障。如果你把Employee相关的声明、操作独立出来放在一个文件里,然后头文件里只放置公开的接口信息,这样就变得简洁多了。 最高层:使用API的程序 main 基于Employee的接口实现的高级操作 employee_print, employee_adjust_salary 基于最底层的C,对象Employee的最基础的操作,包括读入、释放、遍历等 employee_read, employee_free, foreach, with_open_file C语言本身提供的最底层的工具 struct Empoloyee, for, free, calloc... 例如C语言自带的操作文件的接口同样符合这样的抽象屏障:我们只需要使用fopen、fclose、fread、fwrite等一系列操作FILE对象的接口,无需关心FILE结构体里有些什么内容,表示什么意思,以及各个接口是怎么实现的。 #3的确是一个问题,而且我在文章里也可以没有提及,因为这不是这篇文章要表达的重点。它最本质的问题在于将集合的数据结构和单个对象的信息保存在同一个地方。其他语言,例如Java的java.util.*容器、C++的STL容器,都符合你的设计,将容器这个单一职责抽象出来。当然,我自己实际的工作也是这样做的。 ###### 引用来自“中山野鬼”的答案 另外,补充说一下,楼主的函数式风格,和我的函数式风格理解相差颇大。我的理解如下,所谓函数式风格,是将一批数据的若干处理,分解为正交串接的多个子步骤,每个步骤都是对整体数据的某个操作的实现。楼主的方案实质是对一个处理,可以挂接不同的操作方法。 我的理解函数式的风格在于每个独立模块处理极少的有逻辑关联的操作,可以看作针对一个数据池的原子操作。依次将数据池的数据灌入不同的独立模块,实现数据处理。当然差异的模块调用顺序和不同处理模块的组合,可以有不同的效果。 但无论如何,都是函数与数据松耦合的设计。这个和面向对象是反过来的。 我认为你说的是“责任单一原则”,让每个函数、每个模块责任都尽可能地单一,然后通过类似搭积木一样的灵活组合,完成不同的任务。就像UNIX下的命令,每个单独命令都只完成一件事情,通过管道等把这些功能单一的命令组织在一起,协作完成一个复杂的任务! 我个人认为这是一种设计思想,和源自Lambda演算的函数式风格并没有太大关系。 ###### 引用来自“杨同学”的答案 楼主的代码有很浓重的其他语言的味道 因为其他语言也能写“面向对象风格”和“函数式风格”的代码,并且看起来比C更“专业”。 ###### 引用来自“优游幻世”的答案 楼主文章不错,我看现在的C模块基本就是你所说的面向对象风格,其实就是用数据结构组织起来。 嗯,将数据和操作数据的方法集中在一起会让代码更容易维护。 就像我在六楼回复里提到的,很多C模块往往还会更进一步,把容器和对象也分离开来。这样容器能容纳各种不同的对象,对象则只保留数据本身,不关心和其他对象是以什么形式组织在一起的。 ###### 引用来自“redraiment”的答案 引用来自“中山野鬼”的答案 楼主这是节点遍历时,通过函数指针动态加载节点处理函数的设计方法。这个几年前写过,后来不这么写了。主要有以下几个问题。 1、每个节点被访问时,操作可能不一样,通用的函数指针的入口参数,要么可变参,要么多套,入口指针,都是很繁琐的事情,把代码逻辑结构搞的会更复杂。 2、操作函数和操作对象没有绑定,这个在规模开发时,很容易引起混乱。这样设计的代码,我自己到后面都觉得混乱,更别说基于我的架子让别人开发,楼主你的例子不够复杂可能感觉不到。 3、上面两个问题,也导致,代码复用率不高。 现在我的设计思想,如果是基础的数据结构,如同你这个例子中就是个线形表,我都全部独立成模版,在头文件中。 特定数据的处理不会和处理方法绑定,而是调用不同通用模块来处理,这样是尽可能的让数据和处理松耦合。而关联数据再怎么关联,处理时,也是一类整体处理的,同时一批数据再怎么复合,总可以拆成不同大部分串联处理(例如,读取、处理、写出,通过增加cache的方式可以分批分步骤完成,而不是读、处理、写 、一个完整操作周期,仅针对一个单元)。所以这类数据的整体处理落在通用模块里,通过数据和处理的紧耦合的提升效率。 你说的问题#1和文章中函数式风格一节抱怨employee_read无法和Callback兼容的问题是类似的,说到底就是因为C语言静态类型等语法特性导致了对函数式风格支持不好;同时也反向说明了为什么大多数支持函数式风格的语言会选择“动态类型”,并且支持灵活的可变个数参数等特性,都是为了辅助函数式风格的编码。 #2这一点我不太同意。C语言里虽然没有类的概念把数据和函数在语法层次上绑定在一起,但通过规范地命令提供隐喻,比如代码中,所有操作Employee对象的函数都以employee_前缀开头。而且,这些接口之间也有层级关系,符合下表描述的抽象屏障。如果你把Employee相关的声明、操作独立出来放在一个文件里,然后头文件里只放置公开的接口信息,这样就变得简洁多了。 最高层:使用API的程序 main 基于Employee的接口实现的高级操作 employee_print, employee_adjust_salary 基于最底层的C,对象Employee的最基础的操作,包括读入、释放、遍历等 employee_read, employee_free, foreach, with_open_file C语言本身提供的最底层的工具 struct Empoloyee, for, free, calloc... 例如C语言自带的操作文件的接口同样符合这样的抽象屏障:我们只需要使用fopen、fclose、fread、fwrite等一系列操作FILE对象的接口,无需关心FILE结构体里有些什么内容,表示什么意思,以及各个接口是怎么实现的。 #3的确是一个问题,而且我在文章里也可以没有提及,因为这不是这篇文章要表达的重点。它最本质的问题在于将集合的数据结构和单个对象的信息保存在同一个地方。其他语言,例如Java的java.util.*容器、C++的STL容器,都符合你的设计,将容器这个单一职责抽象出来。当然,我自己实际的工作也是这样做的。 第二个问题其实是不同设计思想的核心问题。你举的例子只能说是些简单的系统中的模块。如果是个大系统中的底层模块特别是引擎方面(会产生数据加工的),这种方法最终组合出来的系统,会比面向对象出来的类套类更复杂。说实话,还不如用面相对象实现。 面向对象,是将数据和操作,进行耦合,并且封装在类里面。这种做法是有它的好处的。这样不会导致数据和操作之间出现问题。而c如果这么写,说实话还不如用c++的类进行实现,因为类描述这些逻辑更为清晰,而且语法和编译器可以帮你做大量的事情。 而相反面向数据,是一批数据(不是一个具体数据单元),存在一批不同操作。如何分析数据之间的无关性和前后操作的无关性是重点,这两个分析清楚,那么并发计算,和分步骤计算就得以实现。并发计算不谈,分步骤计算的思想就是原子操作,或者微指令集管道设计思想。这样设计,可以令复杂的数据处理,根据流程细分到步骤,每个步骤细分到子步骤单元,而每个子步骤单元只负责处理,不负责数据的格式问题。 上面这段的设计思想和面向对象是反过来的,数据和操作松耦合。数据的特殊性导致的操作,是通过各种操作模块组合调用实现(这些操作模块可以看作上面独立的子步骤单元和外部特定数据结构无关的)。 这样做的好处是,模块的设计,可以独立进行,让外部数据格式依赖自身,而不是操作对应数据格式(面向对象是后者,成员变量类型决定了成员函数的实际操作),模块复用率高,同时是整批数据处理,只要数据流程(调用不同模块的系统设计良好),运行效率会很高。而且便于并发操作。 并发操作并不单单是一批数据,分层几组让同一个操作的多个进程处理。流水线技术的使用,一样可以实现。 这里顺带喷下hadoop。貌似hadoop的map reduce并没有在流水线方面有什么突破的思路,这块需要考虑到不同计算单元之间数据流动的费用, hadoop整天扯分布计算,根本不考虑数据整体计算周期内的相关性的问题,基本上都是推给用户自己处理,而用户应该无法控制具体计算硬件设备,最后能有好效果就扯淡了。

kun坤 2020-06-09 22:08:58 0 浏览量 回答数 0

回答

MQTT协议 MQTT(Message Queuing Telemetry Transport,消息队列遥测传输)最早是IBM开发的一个即时通讯协议,MQTT协议是为大量计算能力有限且工作在低带宽、不可靠网络的远程传感器和控制设备通讯而设计的一种协议。 MQTT协议的优势是可以支持所有平台,它几乎可以把所有的联网物品和互联网连接起来。 它具有以下主要的几项特性:1、使用发布/订阅消息模式,提供一对多的消息发布和应用程序之间的解耦;2、消息传输不需要知道负载内容;3、使用 TCP/IP 提供网络连接;4、有三种消息发布的服务质量:QoS 0:“最多一次”,消息发布完全依赖底层 TCP/IP 网络。分发的消息可能丢失或重复。例如,这个等级可用于环境传感器数据,单次的数据丢失没关系,因为不久后还会有第二次发送。QoS 1:“至少一次”,确保消息可以到达,但消息可能会重复。QoS 2:“只有一次”,确保消息只到达一次。例如,这个等级可用在一个计费系统中,这里如果消息重复或丢失会导致不正确的收费。5、小型传输,开销很小(固定长度的头部是 2 字节),协议交换最小化,以降低网络流量;6、使用 Last Will 和 Testament 特性通知有关各方客户端异常中断的机制;在MQTT协议中,一个MQTT数据包由:固定头(Fixed header)、 可变头(Variable header)、 消息体(payload)三部分构成。MQTT的传输格式非常精小,最小的数据包只有2个bit,且无应用消息头。下图是MQTT为可靠传递消息的三种消息发布服务质量 发布/订阅模型允许MQTT客户端以一对一、一对多和多对一方式进行通讯。 下图是MQTT的发布/订阅消息模式 CoAP协议 CoAP是受限制的应用协议(Constrained Application Protocol)的代名词。由于目前物联网中的很多设备都是资源受限型的,所以只有少量的内存空间和有限的计算能力,传统的HTTP协议在物联网应用中就会显得过于庞大而不适用。因此,IETF的CoRE工作组提出了一种基于REST架构、传输层为UDP、网络层为6LowPAN(面向低功耗无线局域网的IPv6)的CoAP协议。 CoAP采用与HTTP协议相同的请求响应工作模式。CoAP协议共有4中不同的消息类型。CON——需要被确认的请求,如果CON请求被发送,那么对方必须做出响应。NON——不需要被确认的请求,如果NON请求被发送,那么对方不必做出回应。ACK——应答消息,接受到CON消息的响应。RST——复位消息,当接收者接受到的消息包含一个错误,接受者解析消息或者不再关心发送者发送的内容,那么复位消息将会被发送。 CoAP消息格式使用简单的二进制格式,最小为4个字节。 一个消息=固定长度的头部header + 可选个数的option + 负载payload。Payload的长度根据数据报长度来计算。 主要是一对一的协议 举个例子: 比如某个设备需要从服务器端查询当前温度信息。 请求消息(CON): GET /temperature , 请求内容会被包在CON消息里面响应消息 (ACK): 2.05 Content “22.5 C” ,响应内容会被放在ACK消息里面 CoAP与MQTT的区别 MQTT和CoAP都是行之有效的物联网协议,但两者还是有很大区别的,比如MQTT协议是基于TCP,而CoAP协议是基于UDP。从应用方向来分析,主要区别有以下几点: 1、MQTT协议不支持带有类型或者其它帮助Clients理解的标签信息,也就是说所有MQTT Clients必须要知道消息格式。而CoAP协议则相反,因为CoAP内置发现支持和内容协商,这样便能允许设备相互窥测以找到数据交换的方式。 2、MQTT是长连接而CoAP是无连接。MQTT Clients与Broker之间保持TCP长连接,这种情形在NAT环境中也不会产生问题。如果在NAT环境下使用CoAP的话,那就需要采取一些NAT穿透性手段。 3、MQTT是多个客户端通过中央代理进行消息传递的多对多协议。它主要通过让客户端发布消息、代理决定消息路由和复制来解耦消费者和生产者。MQTT就是相当于消息传递的实时通讯总线。CoAP基本上就是一个在Server和Client之间传递状态信息的单对单协议。 HTTP协议http的全称是HyperText Transfer Protocol,超文本传输协议,这个协议的提出就是为了提供和接收HTML界面,通过这个协议在互联网上面传出web的界面信息。 HTTP协议的两个过程,Request和Response,两个都有各自的语言格式,我们看下是什么。请求报文格式:(注意这里有个换行) 响应报文格式:(注意这里有个换行) 方法method:       这个很重要,比如说GET和POST方法,这两个是很常用的,GET就是获取什么内容,而POST就是向服务器发送什么数据。当然还有其他的,比如HTTP 1.1中还有:DELETE、PUT、CONNECT、HEAD、OPTIONS、TRACE等一共8个方法(HTTP Method历史:HTTP 0.9 只有GET方法;HTTP 1.0 有GET、POST、HEAD三个方法)。请求URL:       这里填写的URL是不包含IP地址或者域名的,是主机本地文件对应的目录地址,所以我们一般看到的就是“/”。版本version:       格式是HTTP/.这样的格式,比如说HTTP/1.1.这个版本代表的就是我们使用的HTTP协议的版本,现在使用的一般是HTTP/1.1状态码status:       状态码是三个数字,代表的是请求过程中所发生的情况,比如说200代表的是成功,404代表的是找不到文件。原因短语reason-phrase:       是状态码的可读版本,状态码就是一个数字,如果你事先不知道这个数字什么意思,可以先查看一下原因短语。首部header:       注意这里的header我们不是叫做头,而是叫做首部。可能有零个首部也可能有多个首部,每个首部包含一个名字后面跟着一个冒号,然后是一个可选的空格,接着是一个值,然后换行。实体的主体部分entity-body:       实体的主体部分包含一个任意数据组成的数据块,并不是所有的报文都包含实体的主体部分,有时候只是一个空行加换行就结束了。 下面我们举个简单的例子: 请求报文:GET /index.html HTTP/1.1    Accept: text/*Host: www.myweb.com 响应报文:HTTP/1.1 200 OKContent-type: text/plainContent-length: 3  HTTP与CoAP的区别 CoAP是6LowPAN协议栈中的应用层协议,基于REST(表述性状态传递)架构风格,支持与REST进行交互。通常用户可以像使用HTTP协议一样用CoAP协议来访问物联网设备。而且CoAP消息格式使用简单的二进制格式,最小为4个字节。HTTP使用报文格式对于嵌入式设备来说需要传输数据太多,太重,不够灵活。 XMPP协议 XMPP(可扩展通讯和表示协议)是一种基于可扩展标记语言(XML)的协议, 它继承了在XML环境中灵活的发展性。可用于服务类实时通讯、表示和需求响应服务中的XML数据元流式传输。XMPP以Jabber协议为基础,而Jabber是即时通讯中常用的开放式协议。   基本网络结构 XMPP中定义了三个角色,客户端,服务器,网关。通信能够在这三者的任意两个之间双向发生。 服务器同时承担了客户端信息记录,连接管理和信息的路由功能。网关承担着与异构即时通信系统 的互联互通,异构系统可以包括SMS(短信),MSN,ICQ等。基本的网络形式是单客户端通过 TCP/IP连接到单服务器,然后在之上传输XML。 功能 传输的是与即时通讯相关的指令。在以前这些命令要么用2进制的形式发送(比如QQ),要么用纯文本指令加空格加参数加换行符的方式发送(比如MSN)。而XMPP传输的即时通讯指令的逻辑与以往相仿,只是协议的形式变成了XML格式的纯文本。举个例子看看所谓的XML(标准通用标记语言的子集)流是什么样子的?客户端:123456<?xmlversion='1.0'?>to='example_com'xmlns='jabber:client'xmlns:stream='http_etherx_jabber_org/streams'version='1.0'>服务器:1234567<?xmlversion='1.0'?>from='example_com'id='someid'xmlns='jabber:client'xmlns:stream='http_etherx_jabber_org/streams'version='1.0'>工作原理XMPP核心协议通信的基本模式就是先建立一个stream,然后协商一堆安全之类的东西, 中间通信过程就是客户端发送XML Stanza,一个接一个的。服务器根据客户端发送的信息 以及程序的逻辑,发送XML Stanza给客户端。但是这个过程并不是一问一答的,任何时候 都有可能从一方发信给另外一方。通信的最后阶段是关闭流,关闭TCP/IP连接。  网络通信过程中数据冗余率非常高,网络流量中70% 都消耗在 XMPP 协议层了。对于物联网来说,大量计算能力有限且工作在低带宽、不可靠网络的远程传感器和控制设备,省电、省流量是所有底层服务的一个关键技术指标,XMPP协议看起来已经落后了。 SoAP协议 SoAP(简单对象访问协议)是交换数据的一种协议规范,是一种轻量的、简单的、 基于可扩展标记语言(XML)的协议,它被设计成在WEB上交换结构化的和固化的信息。  SOAP 可以和现存的许多因特网协议和格式结合使用,包括超文本传输协议(HTTP), 简单邮件传输协议(SMTP),多用途网际邮件扩充协议(MIME)。它还支持从消息系统到 远程过程调用(RPC)等大量的应用程序。SOAP使用基于XML的数据结构和超文本传输协议 (HTTP)的组合定义了一个标准的方法来使用Internet上各种不同操作环境中的分布式对象。 总结: 从当前物联网应用发展趋势来分析,MQTT协议具有一定的优势。因为目前国内外主要的云计算服务商,比如阿里云、AWS、百度云、Azure以及腾讯云都一概支持MQTT协议。还有一个原因就是MQTT协议比CoAP成熟的要早,所以MQTT具有一定的先发优势。但随着物联网的智能化和多变化的发展,后续物联网应用平台肯定会兼容更多的物联网应用层协议。 作者:HFK_Frank 来源:CSDN 原文:https://blog.csdn.net/acongge2010/article/details/79142380 版权声明:本文为博主原创文章,转载请附上博文链接!

auto_answer 2019-12-02 01:55:21 0 浏览量 回答数 0

阿里云试用中心,为您提供0门槛上云实践机会!

0元试用32+款产品,最高免费12个月!拨打95187-1,咨询专业上云建议!

问题

为什么要分库分表(设计高并发系统的时候,数据库层面该如何设计)?【Java问答】41期

剑曼红尘 2020-06-19 13:47:21 0 浏览量 回答数 0

问题

Netty实现原理浅析 1、总体结构 2、网络模型 3、 buffer 4、Ch?400报错

爱吃鱼的程序员 2020-06-04 11:53:36 3 浏览量 回答数 1

问题

【精品问答】python技术1000问(1)

问问小秘 2019-12-01 21:57:48 454222 浏览量 回答数 19

问题

【精品问答】python技术1000问(2)

问问小秘 2019-12-01 22:03:02 68 浏览量 回答数 0

回答

希望对你有帮助。 一、为何要学编程。 每个人的动机不一样。大致有: 1、为了找个好工作;或为了有更好的机会和更好的发展。 2、看到别人超厉害,所以也想学。 3、实际工作中很多场合需要。 4、从小就立志做个程序员,做软件工程师。 5、振兴中国的软件事业。 。。。。。。 ================================================ 二、如何学编程。 1、多看好书。 差书误人子弟,不但浪费时间和精力,而且打击人的信心,差书使人很久都不会,让会让人怀疑自已的学习能力。 现在的书很多,但好书很少,特别是被大家公认很有价值的好书,更是少之又少。历经多年时间考验和市场风雨不残酷洗礼而仅存的巨著,更是极其稀少。中国历史上文学小说类书本多如牛毛,但仅存的巨著,也只不过<<红楼梦>>等四本名著而已,编程方面也是如此。 2、多动手。 这一点很重要。而且特别重要。“纸上得来终觉浅,绝知此事要躬行。”陆游的千古名句说的就是这个道理,并且同样适合于编程方面。 ================================================ 三、用什么语言最好。 这主要取决于应用领域,每种语言都有自已的长处和不足。 1、汇编语言和C语言在单片机及工控领域用较多。另外C语言也是一种通用语言,是学C++/c#的起点。 2、C++系统编程等多个方面,最常用的编译器是VC。 3、C#/java网络编程方面新兴的。 4、VB通用。 5、还有Delphi等。。。。。。 个人建议:从未编过程的,就从学vb开始。有基础的可直接学c++/VC。 =================================================== 四、有什么好书。 几年前,台湾著名技术作家侯捷先生曾经写过一篇影响很大的书评文章,叫做《MFC四大天王》。文章的意思是说在MFC的浩瀚书海中,只要认真研读和学习其中四本,就可以“五岳归来不看山”。侯先生虽以MFC为例,但是这个道理却同样适合于MFC之外的很多具体技术领域,这不能不说是一个有趣的统计现象。 通常在某一个具体细分的技术领域,会自然而然地出现3-5本顶级著作,它们彼此互相配合,形成一个完整的体系。对于学习者来说,只需要认真研读这几本书,就足以升堂入室。我乐于将这种现称为“四书五经现象”。对于读者来说,如果能够找到该领域中的“四书五经”,则无论在时间上还是金钱上都是最经济的选择。好书几本,胜过烂书几捆,这个体会想必大家都有。在此,帮助大家遴选各个技术领域里的“四书五经”。 编程的书可谓汗牛充栋,其中经典也是不泛其数,但绝大多数的过来人,都一致认为,要想很快的入门并尽快的投入到编程实践中,只要其中的四到五本也就够了,即只看经典中的经典,圣经级的书就可以了。 所谓活到老学到老,程序员是个终身学习的职业,要不断的看书,直到放弃编程的那一天。所以,您要读的好书也绝非以下推荐的这些书哟,呵呵。 一句话,由于我们的时间、精力、金钱都是有限的,如何以最小的代价换得最大的收获。 ================================================================ 五、经典好书分类热销榜 1、java java编程语言(第三版)---java四大名著----James Gosling(java之父) java编程思想(第2版)----java四大名著----Bruce Eckel java编程思想(第3版)----java四大名著----------------Bruce Eckel java 2核心技术 卷I:基础知识(原书第7版)---java四大名著-----Cay Horstmann java 2核心技术 卷II:高级特性(原书第7版)----java四大名著-----Cay Horstmann Effective java中文版------java四大名著--------Joshua Bloch 精通Struts:基于MVC的java Web设计与开发---孙卫琴 精通Hibernate:java对象持久化技术详解---孙卫琴 Tomcat与java Web开发技术详解------------孙卫琴 java与模式------------------------------阎宏 2、c# C#程序设计-------Charles Petzold“windows编程泰山北斗”---C#语言“倚天屠龙双剑” C# Primer中文版--------Stanley B.Lippman---C#语言“倚天屠龙双剑” .NET框架程序设计(修订版)--------Jeffrey Richter“windows编程泰山北斗”---.NET平台四大天王 C# Windows程序设计----------Charles Petzold“windows编程泰山北斗”------.NET平台四大天王 .NET程序设计技术内幕-------------Jeff Prosise---.NET平台四大天王 .NET本质论--第1卷:公共语言运行库(中文版)--------Chris Sells---.NET平台四大天王 3、C++ C++程序设计语言(特别版)---c++八大金刚----Bjarne Stroustrup“C++之父” C++ Primer (第3版)中文版----c++八大金刚---Stanley B.Lippman C++ Primer (第4版)中文版----c++八大金刚---Stanley B.Lippman C++标准程序库—自修教程与参考手册--c++八大金刚--Nicolai M.Josuttis C++语言的设计和演化-----c++八大金刚----Bjarne Stroustrup“C++之父” 深度探索C++对象模型---c++八大金刚----Stanley B.Lippman Essential C++中文版---c++八大金刚---Stanley B.Lippman Effective C++中文版 2nd Edition-----c++八大金刚------Scott Meyers More Effective C++中文版----c++八大金刚------Scott Meyers C++编程思想(第2版) 第1卷:标准C++导引--------Bruce Eckel C++编程思想(第2版)第2卷:实用编程技术 --------Bruce Eckel C++程序设计--------------------------谭浩强 C++ 程序设计教程(第2版)--------------钱能 C++ Primer Plus(第五版)中文版---Stephen Prata 广博如四库全书The c++ programming language、c++ Primer 深奥如山重水复Inside the c++ object model 程序库大全The c++ standard libray 工程经验之积累Effective c++、More Effective c++、Exceptional c++ c++八大金刚: 1、Essentital c++---lippman---C++之父,旁枝暂略,主攻核心,轻薄短小,初学者 2、The c++ programming language----C++之父,技术权威,用词深峻,思想深远,c++百科全书代表,圣经。 3、c++ Primer----lippman---纵横书市十数年,c++最佳教本,c++百科全书代表。 4、Inside the c++ object model-----lippman----揭示c++底层,非常好,非常难。 5、Effective c++-----通过50个编程实例,展示专家经验,行文有趣,深处浅出。 6、More Effective c++----通过35个编程实例,展示专家经验,行文有趣,深处浅出。 7、The c++ standard libray---c++标准库的百科全书。 8、设计模式:可复用面向对象软件的基础------good! 4、c C程序设计语言(第2版·新版)---C语言“倚天屠龙双剑”---Brian W.Kernighan“C语言之父” C Primer Plus中文版(第五版)--------C语言“倚天屠龙双剑”---Stephen Prata C程序设计(第三版)---------------------------谭浩强 C语言大全(第四版)---------------------------HERBERT SCHILDT C语言接口与实现:创建可重用软件的技术-------------DAVID R.HANSON C语言参考手册(原书第5版)--------------------------Samuel P.Harbison C程序设计教程---------------------------------H.M.Deitel/P.J.Deitel C陷阱与缺陷-----------------------------------Andrew Koenig 5、VB Visual Basic .NET技术内幕-----VB编程三剑客-----------Francesco Balena“vb首席大师” Windows程序设计-Visual Basic.NET语言描述--VB编程三剑客-----Charles Petzold“windows编程泰山北斗”--- .NET框架程序设计:Visual Basic.NET语言描述--VB编程三剑客--Jeffrey Richter“windows编程泰山北斗”--- Visual Basic 6编程技术大全------------------------Francesco Balena“vb首席大师” Visual Basic.NET 从入门到精通-------------------------Petroutsos,E. 高级VISUAL BASIC编程-----------------------------------MATTHEW CURLAND 6、Delphi Inside VCL(深入核心——VCL架构剖析)----------李维 Delphi 7高效数据库程序设计--------------李维 面向对象开发实践之路(Delphi版)----------李维 7、VC Windows 程序设计(第5版)-----Charles Petzold“windows编程泰山北斗”--- Windows核心编程----------Jeffrey Richter“windows编程泰山北斗”--- Windows高级编程指南---------Jeffrey Richter“windows编程泰山北斗”--- 深入浅出MFC(第二版)-----“MFC四大天王”-------侯捷 MFC Windows程序设计(第2版)---MFC四大天王”---------Jeff Prosise Visual C++ 技术内幕(第4版)--MFC四大天王”--------David Kruglinski 深入解析MFC-------------MFC四大天王”-----------George Shepherd Visual C++.NET 技术内幕(第6版)-MFC四大天王”------------David Kruglinski 8、vf Visual Foxpro程序设计参考手册-------------------张洪举 专家门诊——Visual FoxPro开发答疑160问-------------------张洪举 Visual FoxPro 6.0/9.0解决方案与范例大全-------------------张洪举 Visual FoxPro软件开发模式与应用案例-------------------张洪举 9、黑客 应用密码学(协议算法与C源程序-----------Bruce Schneier 网络信息安全的真相-----------Bruce Schneier 黑客大曝光:网络安全机密与解决方案(第5版)--------STUART MCCLURE 软件加密技术内幕------------看雪学院 加密与解密——软件保护技术与完全解决方案------------看雪学院 加密与解密(第二版)--------段钢 10、汇编 Intel微处理器结构、编程与接口(第六版)---------Barry B. Brey 80*86、奔腾机汇编语言程序设计---------Barry B. Brey Windows环境下32位汇编语言程序设计(第2版)-----------罗云彬 IBM-PC汇编语言程序设计(第2版) 本书是国内优秀教材--------沈美明 温冬婵 IBM PC汇编语言程序设计(第五版) 这本书籍是国外优秀教材-------PETER ABEL著,沈美明 温冬蝉译 11、驱动开发 Windows WDM设备驱动程序开发指南------------------------------------ Chris Cant Windows 2000/XP WDM设备驱动程序开发(第2版)--------------------------武安河 WINDOWS 2000/XP WDM设备驱动程序开发-------------------------------- 武安河 12、网络 计算机网络第四版中文版----网络编程三剑客--------------Andrew S.Tanenbaum TCP/IP详解3卷本--------------------Richard Stevens----网络编程三剑客 UNIX网络编程2卷本--------------------Richard Stevens----网络编程三剑客 用TCP/IP进行网际互联-----------Douglas E. Comer 高级TCP/IP编程-------------------Jon C. Snader C++网络编程-----------------------Douglas Schmidt UNIX环境高级编程(第2版)--------------------Richard Stevens 13、算法 计算机程序设计艺术-------Donald.E.Knuth----------算法“倚天屠龙”双剑 算法导论-----------------Thomas H. Cormen--------算法“倚天屠龙”双剑 离散数学及其应用----------Kenneth H.Rosen 具体数学—计算机科学基础--------Donald.E.Knuth 14、图形编程 Windows 图形编程----------------FENG YUAN --图形编程界的Charles Petzold之书 15、数据结构 数据结构 C++语言描述》58.00(Data Structures C++) William Ford,William Topp 刘卫东 沈官林 数据结构算法与应用-C++语言描述》49.00Sartej Sahni 汪诗林 孙晓东等机械工业出版社 16、软件工程 设计模式--可复用面向对象软件的基础 重构—改善既有代码的设计 17、操作系统 深入理解计算机系统(修订版)-------RANDAL E.BRYANT 18、Unix UNIX 网络编程 卷I 套接字联网API(英文版 第三版 UNIX 编程艺术 UNIX环境高级编程(英文影印第2版-----UNIX编程“圣经 UNIX环境高级编程(英文影印版)(第2版) UNIX环境高级编程(第2版) UNIX环境高级编程(第2版)---UNIX编程“圣经 UNIX网络编程 第1卷:套接口API(第3版) UNIX网络编程卷2:进程间通信(第2版)(英文影印版) UNIX 网络编程(第二版)第2卷:进程间通信 UNIX编程环境 UNIX 网络编程 卷I 套接字联网API(英文版 第三版 UNIX系统编程 UNIX环境高级编程 UNIX 网络编程 卷I 套接字联网API(英文版 第三版) UNIX网络编程 第1卷:套接口API(第3版) UNIX 网络编程(第二版)第2卷:进程间通信 UNIX网络编程卷2:进程间通信(第2版)(英文影印版) UNIX 网络编程(第2版)第1卷:套接口API和X/Open 传输接口API UNIX网络编程(卷1):连网的APLS:套接字与XTI(第二版)(英文影印版) UNIX环境高级编程 Unix技术手册 19、Linux Linux内核设计与实现 Linux内核完全注释 LINUX内核分析及编程 GNU/Linux 编程指南(第二版) Linux设备驱动程序(第三版) 嵌入式设计及Linux驱动开发指南——基于ARM 9处理器 Linux设备驱动程序 第三版(英文影印版) Linux内核设计与实现(第2版) Linux内核设计与实现(英文影印版)(第2版) linux技术手册 20、游戏编程 Windows游戏编程大师技巧(第二版 游戏之旅--我的编程感悟 OpenGL超级宝典:第三版 OpenGL编程指南(第四版) java 游戏高级编程 J2ME手机游戏编程入门 游戏之旅——我的编程感悟 游戏开发中的人工智能(英文影印版) 3D游戏:卷2 动画与高级实时渲染技术 面向对象的游戏开发 java 游戏高级编程 3D游戏编程大师技巧 游戏编程精粹 面向对象的游戏开发 3D游戏 卷1:实时渲染与软件技术 3D游戏:卷2 动画与高级实时渲染技… J2ME手机游戏编程入门 Direct3D游戏编程入门教程(第二版… 21、移动开发 Windows Mobile手机应用开发 SYMBIAN OS C++手机应用开发 Windows Mobile手机应用开发--傅曦 齐宇 徐骏 SYMBIAN OS C++手机应用开发 (第2卷)------------------RICHARD HARRISON著,周良忠 王伯欣译 SYMBIAN OS C++手机应用开发---------------RICHARD HARRISON著,周良忠译 Windows CE.net内核定制及应用程序开发---------周毓林 宁杨 陆贵强 付林林 嵌入式系统Windows CE 开发技巧与实例--傅曦 Palm OS编程实践---绝版 22、单片机 单片机轻松入门----------------------------------周坚(平凡老师) 单片机典型模块设计实例导航-----------------------求是科技 例说8051----------------------------------------张义和 陈敌北 KEIL CX51 V7.0单片机高级语言编程与ΜVISION2应用实践-----徐爱钧 单片机应用程序设计技术(修订版)--------------------周航慈 8051单片机实践与应用-------------------------------吴金戎 MCS-51系列单片机实用接口技术---------------------李华 23、串并口通讯 Visual C++/Turbo C串口通信编程实践------------------龚建伟 VISUAL BASIC与RS-232串行通信控制(最新版)----------范逸之 24、电子 无线电识图与电路故障分析轻松入门(第二版) -------------------胡斌 无线电元器件检测与修理技术轻松入门(第二版) -------------------胡斌 图表细说电子技术识图-------------------胡斌 图表细说电子元器件-------------------胡斌 图表细说元器件及实用电路-------------------胡斌 ================================================================ 六、怎样成为一名程序员 通过以下4个阶段的训练, 没有任何编程基础人就可以成为一名普通的程序员。 第一阶段:掌握一种编程语言 学习内容:学习任意一种主流的编程语言。例如C++语言。 学习目标:熟练掌握一种语言的语法和基本的编程技巧。 学习时间:3个月左右 注意事项:编程语言和编程工具是两回事情,编程语言是指C++、Basic、Object Pascal等程序设计语言,它们是像汉语、英语一样的抽象的语法规则,编程工具是指Visual C++ 6.0、Visual Basic 6.0、Delphi 7.0等包括了源代码编辑器、程序编译器在内的集成化、可视化的软件开发工具。C++源程序可以在Visual C++ 6.0里编写,也可以在记事本里编写,而同一个C++源程序可以用Visual C++ 6.0编译、执行,也可以用C++ Builder 5.0 编译、执行,所以: C++ 不等于 Visual C++ 6.0 第二阶段:掌握一种编程工具 学习内容:学习任意一种主流的编程工具。注意编程工具要和第一阶段学习的编程语言一致,例如你学习的编程语言是C++,那么编程工具要选Visual C++ 6.0或者C++ Builder 5.0。 学习目标:熟练掌握这种编程工具基本用法,例如:菜单、组件、程序跟踪调试、编写Windows程序等。 学习时间:3个月左右 注意事项:这个阶段侧重编程工具的使用,同时进一步熟习编程语言,最后达到能熟练编写各种基本的Windows程序。 第三阶段:掌握“算法与数据结构”这门课程 学习内容:算法与数据结构,推荐许卓群的《数据结构》,高等教育出版社出版。 学习目标:熟练掌握各种常用的算法与数据结构 学习时间:4个月左右 注意事项:这是一门不可或缺的软件开发课程,曾经有一本经典计算机专业书籍叫做《数据结构+算法=程序》,这说明了数据结构和算法的重要性。它能帮我们建立良好的程序分析与设计能力。 第四阶段:实现一个模拟的小型软件项目 学习内容:软件项目的开发过程 学习目标:掌握软件项目的基本开发过程和方法 学习时间:4个月左右 注意事项:自己完成一个模拟的小型软件项目,强烈推荐做一个MIS(管理信息系统)软件,参考用书推荐“中小型信息管理系统开发实例系列丛书”,人民邮电出版社,它的例子详实有效,以它为基础再加以扩展,就可以做出实用的MIS软件来。此丛书包括多种开发工具,大家可以选择适合自己的:《VISUAL FOXPRO6.0 数据库系统开发实例导航》 《java数据库系统开发实例导航》 《VISUAL BASIC数据库系统开发实例导航》《VISUAL C++6.0数据库系统开发实例导航》 《ASP.NET数据库管理系统开发实例导航》 《DELPHI数据库系统开发实例导航》《POWERBUILDER 8.0数据库系统开发实例导航》。 最后将完成的模拟软件刻成光盘,作为自己的作品去面试,以此踏上自己光辉的职业程序员之路。

青衫无名 2019-12-02 01:20:33 0 浏览量 回答数 0

问题

【云能量沙龙深圳站】陆晶丹:阿里云开放存储服务API与Web应用案例分享

sleepbird 2019-12-01 20:27:09 18770 浏览量 回答数 23

回答

Layout Go工程项目的整体组织 首先我们看一下整个 Go 工程是怎么组织起来的。 很多同事都在用 GitLab 的,GitLab 的一个 group 里面可以创建很多 project。如果我们进行微服务化改造,以前很多巨石架构的应用可能就拆成了很多个独立的小应用。那么这么多小应用,你是要建 N 个 project 去维护,还是说按照部门或者组来组织这些项目呢?在 B 站的话,我们之前因为是 Monorepo,现在是按照部门去组织管理代码,就是说在单个 GitLab 的 project 里面是有多个 app 的,每一个 app 就表示一个独立的微服务,它可以独立去交付部署。所以说我们看到下面这张图里面,app 的目录里面是有好多个子目录的,比方说我们的评论服务,会员服务。跟 app 同级的目录有一个叫 pkg,可以存放业务有关的公共库。这是我们的一个组织方式。当然,还有一种方式,你可以按照 GitLab 的 project 去组织,但我觉得这样的话可能相对要创建的 project 会非常多。 如果你按部门组织的话,部门里面有很多 app,app 目录怎么去组织?我们实际上会给每一个 app 取一个全局唯一名称,可以理解为有点像 DNS 那个名称。我们对业务的命名也是一样的,我们基本上是三段式的命名,比如账号业务,它是一个账号业务、服务、子服务的三段命名。三段命名以后,在这个 app 目录里面,你也可以按照这三层来组织。比如我们刚刚说的账号目录,我可能就是 account 目录,然后 VIP,在 VIP 目录下可能会放各种各样的不同角色的微服务,比方说可能有一些是做 job,做定时任务或者流式处理的一些任务,有可能是做对外暴露的 API 的一些服务,这个就是我们关于整个大的 app 的组织的一种形式。 微服务中的 app 服务分类 微服务中单个 app 的服务里又分为几类不同的角色。我们基本上会把 app 分为 interface(BFF)、service、job(补充:还有一个 task,偏向定时执行,job 偏向流式) 和 admin。 Interface 是对外的业务网关服务,因为我们最终是面向终端用户的 API,面向 app,面向 PC 场景的,我们把这个叫成业务网关。因为我们不是统一的网关,我们可能是按照大的业务线去独立分拆的一些子网关,这个的话可以作为一个对外暴露的 HTTP 接口的一个目录去组织它的代码,当然也可能是 gRPC 的(参考 B 站对外的 gRPC Moss 分享)。 Service 这个角色主要是面向对内通信的微服务,它不直接对外。也就是说,业务网关的请求会转发或者是会 call 我们的内部的 service,它们之间的通讯可能是使用自己的 RPC,在 b 站我们主要是使用 gRPC。使用 gRPC 通讯以后,service 它因为不直接对外,service 之间可能也可以相互去 call。 Admin 区别于 service,很多应用除了有面向用户的一些接口,实际上还有面向企业内部的一些运营侧的需求,通常数据权限更高,从安全设计角度需要代码物理层面隔离,避免意外。 第四个是 ecode。我们当时也在内部争论了很久,我们的错误码定义到底是放在哪里?我们目前的做法是,一个应用里面,假设你有多种角色,它们可能会复用一些错误码。所以说我们会把我们的 ecode 给单独抽出来,在这一个应用里面是可以复用的。注意,它只在这一个应用里面复用,它不会去跨服跨目录应用,它是针对业务场景的一个业务错误码的组织。 App 目录组织 我们除了一个应用里面多种角色的这种情况,现在展开讲一下具体到一个 service 里面,它到底是怎么组织的。我们的 app 目录下大概会有 api、cmd、configs、 internal 目录,目录里一般还会放置 README、CHANGELOG、OWNERS。 API 是放置 api 定义以及对应的生成的 client 代码,包含基于 pb 定义(我们使用 PB 作为 DSL 描述 API) 生成的 swagger.json。 而 cmd,就是放 main 函数的。Configs 目录主要是放一些服务所需的配置文件,比方说说我们可能会使用 TOML 或者是使用 YAML 文件。 Internal 的话,它里面有四个子目录,分别是 model、dao、service 和 server。Model 的定位职责就是对我们底层存储的持久化层或者存储层的数据的映射,它是具体的 Go 的一个 struct。我们再看 dao,你实际就是要操作 MySQL 或者 Redis,最终返回的就是这些 model(存储映射)。Service 组织起来比较简单,就是我们通过 dao 里面的各个方法来完成一个完整的业务逻辑。我们还看到有个 server,因为我一个微服务有可能企业内部不一定所有 RPC 都统一,那我们处于过渡阶段,所以 server 里面会有两个小目录,一个是 HTTP 目录,暴露的是 HTTP 接口,还有一个是 gRPC 目录,我们会暴露 gRPC 的协议。所以在 server 里面,两个不同的启动的 server,就是说一个服务和启动两个端口,然后去暴露不同的协议,HTTP 接 RPC,它实际上会先 call 到 service,service 再 call 到 dao,dao 实际上会使用 model 的一些数据定义 struct。但这里面有一个非常重要的就是,因为这个结构体不能够直接返回给我们的 api 做外对外暴露来使用,为什么?因为可能从数据库里面取的敏感字段,当我们实际要返回到 api 的时候,可能要隐藏掉一些字段,在 Java 里面,会抽象的一个叫 DTO 的对象,它只是用来传输用的,同理,在我们 Go 里面,实际也会把这些 model 的一些结构体映射成 api 里面的结构体(基于 PB Message 生成代码后的 struct)。 Rob Pike 当时说过的一句话,a little copying is better than a little dependency,我们就遵循了这个理念。在我们这个目录结构里面,有 internal 目录,我们知道 Go 的目录只允许这个目录里面的人去 import 到它,跨目录的人实际是不能直接引用到它的。所以说,我们看到 service 有一个 model,那我的 job 代码,我做一些定时任务的代码或者是我的网关代码有可能会映射同一个 model,那是不是要把这个 model 放到上一级目录让大家共享?对于这个问题,其实我们当时内部也争论过很久。我们认为,每一个微服务应该只对自己的 model 负责,所以我们宁愿去做一小部分的代码 copy,也不会去为了几个服务之间要共享这一点点代码,去把这个 model 提到和 app 目录级别去共用,因为你一改全错,当然了,你如果是拷贝的话,就是每个地方都要去改,那我们觉得,依赖的问题可能会比拷贝代码相对来说还是要更复杂的。 这个是一个标准的 PB 文件,就是我们内部的一个 demo 的 service。最上面的 package 是 PB 的包名,demo.service.v1,这个包使用的是三段式命名,全局唯一的名称。那这个名称为什么不是用 ID?我见过有些公司对内部做的 CMDB 或者做服务树去管理企业内部微服务的时候,是用了一些名称加上 ID 来搞定唯一性,但是我们知道后面那一串 ID 数字是不容易被传播或者是不容易被记住的,这也是 DNS 出来的一个意义,所以我们用绝对唯一的一个名称来表示这个包的名字,在后面带上这一个 PB 文件的版本号 V1。 我们看第二段定义,它有个 Service Demo 代码,其实就表示了我们这个服务要启动的服务的一个名称,我们看到这个服务名称里面有很多个 RPC 的方法,表示最终这一个应用或者这个 service 要对外暴露这几个 RPC 的方法。这里面有个小细节,我们看一下 SayHello 这个方法,实际它有 option 的一个选项。通过这一个 PB 文件,你既可以描述出你要暴露的是 gRPC 协议,又暴露出 HTTP 的一个接口,这个好处是你只需要一个 PB 文件描述你暴露的所有 api。我们回想一下,我们刚刚目录里面有个 api 目录,实际这里面就是放这一个 PB 文件,描述这一个工程到底返回的接口是什么。不管是 gRPC 还是 HTTP 都是这一个文件。还有一个好处是什么?实际上我们可以在 PB 文件里面加上很多的注释。用 PB 文件的好处是你不需要额外地再去写文档,因为写文档和写服务的定义,它本质上是两个步骤,特别容易不一致,接口改了,文档不同步。我们如果基于这一个 PB 文件,它生成的 service 代码或者调用代码或者是文档都是唯一的。 依赖顺序与 api 维护 就像我刚刚讲到的,model 是一个存储层的结构体的一一映射,dao 处理一些数据读写包,比方说数据库缓存,server 的话就是启动了一些 gRPC 或者 HTTP Server,所以它整个依赖顺序如下:main 函数启动 server,server 会依赖 api 定义好的 PB 文件,定义好这些方法或者是服务名之后,实际上生成代码的时候,比方说 protocbuf 生成代码的时候,它会把抽象 interface 生成好。然后我们看一下 service,它实际上是弱依赖的 api,就是说我的 server 启动以后,要注册一个具体的业务代码的逻辑,映射方法,映射名字,实际上是弱依赖的 api 生成的 interface 的代码,你就可以很方便地启动你的 server,把你具体的 service 的业务逻辑给注入到这个 server,和方法进行一一绑定。最后,dao 和 service 实际上都会依赖这个 model。 因为我们在 PB 里面定义了一些 message,这些 message 生成的 Go 的 struct 和刚刚 model 的 struct 是两个不同的对象,所以说你要去手动 copy 它,把它最终返回。但是为了快捷,你不可能每次手动去写这些代码,因为它要做 mapping,所以我们又把 K8s 里类似 DeepCopy 的两个结构体相互拷贝的工具给抠出来了,方便我们内部 model 和 api 的 message 两个代码相互拷贝的时候,可以少写一些代码,减少一些工作量。 上面讲的就是我们关于工程的一些 layout 实践。简单回溯一下,大概分为几块,第一就是 app 是怎么组织的,app 里面有多种角色的服务是怎么组织的,第三就是一个 app 里面的目录是怎么组织的,最后我重点讲了一下 api 是怎么维护的。 Unittest 测试方法论 现在回顾一下单元测试。我们先看这张图,这张图是我从《Google 软件测试之道》这本书里面抠出来的,它想表达的意思就是最小型的测试不能给我们的最终项目的质量带来最大的信心,它比较容易带来一些优秀的代码质量,良好的异常处理等等。但是对于一个面向用户场景的服务,你只有做大型测试,比方做接口测试,在 App 上验收功能的这种测试,你应用交付的信心可能会更足。这个其实要表达的就是一个“721 原则”。我们就是 70% 写小型测试,可以理解为单元测试,因为它相对来说好写,针对方法级别。20% 是做一些中型测试,可能你要连调几个项目去完成你的 api。剩下 10% 是大型测试,因为它是最终面向用户场景的,你要去使用我们的 App,或者用一些测试 App 去测试它。这个就是测试的一些简单的方法论。 单元测试原则 我们怎么去对待 Go 里面的单元测试?在《Google 软件测试之道》这本书里面,它强调的是对于一个小型测试,一个单元测试,它要有几个特质。它不能依赖外部的一些环境,比如我们公司有测试环境,有持续集成环境,有功能测试环境,你不能依赖这些环境构建自己的单元测试,因为测试环境容易被破坏,它容易有数据的变更,数据容易不一致,你之前构建的案例重跑的话可能就会失败。 我觉得单元测试主要有四点要求。第一,快速,你不能说你跑个单元测试要几分钟。第二,要环境一致,也就是说你跑测试前和跑测试后,它的环境是一致的。第三,你写的所有单元测试的方法可以以任意顺序执行,不应该有先后的依赖,如果有依赖,也是在你测试的这个方法里面,自己去 setup 和 teardown,不应该有 Test Stub 函数存在顺序依赖。第四,基于第三点,你可以做并行的单元测试,假设我写了一百个单元测试,一个个跑肯定特别慢。 doker-compose 最近一段时间,我们演进到基于 docker-compose 实现跨平台跨语言环境的容器依赖管理方案,以解决运行 unittest 场景下的容器依赖问题。 首先,你要跑单元测试,你不应该用 VPN 连到公司的环境,好比我在星巴克点杯咖啡也可以写单元测试,也可以跑成功。基于这一点,Docker 实际上是非常好的解决方式。我们也有同学说,其他语言有一些 in-process 的 mock,是不是可以启动 MySQL 的 mock ,然后在 in-process 上跑?可以,但是有一个问题,你每一个语言都要写一个这样的 mock ,而且要写非常多种,因为我们中间件越来越多,MySQL,HBase,Kafka,什么都有,你很难覆盖所有的组件 Mock。这种 mock 或者 in-process 的实现不能完整地代表线上的情况,比方说,你可能 mock 了一个 MySQL,检测到 query 或者 insert ,没问题,但是你实际要跑一个 transaction,要验证一些功能就未必能做得非常完善了。所以基于这个原因,我们当时选择了 docker-compose,可以很好地解决这个问题。 我们对开发人员的要求就是,你本地需要装 Docker,我们开发人员大部分都是用 Mac,相对来说也比较简单,Windows 也能搞定,如果是 Linux 的话就更简单了。本地安装 Docker,本质上的理解就是无侵入式的环境初始化,因为你在容器里面,你拉起一个 MySQL,你自己来初始化数据。在这个容器被销毁以后,它的环境实际上就满足了我们刚刚提的环境一致的问题,因为它相当于被重置了,也可以很方便地快速重置环境,也可以随时随地运行,你不需要依赖任何外部服务,这个外部服务指的是像 MySQL 这种外部服务。当然,如果你的单元测试依赖另外一个 RPC 的 service 的话,PB 的定义会生成一个 interface,你可以把那个 interface 代码给 mock 掉,所以这个也是能做掉的。对于小型测试来说,你不依赖任何外部环境,你也能够快速完成。 另外,docker-compose 是声明式的 API,你可以声明你要用 MySQL,Redis,这个其实就是一个配置文件,非常简单。这个就是我们在单元测试上的一些实践。 我们现在看一下,service 目录里面多了一个 test 目录,我们会在这个里面放 docker-compose 的 YAML 文件来表示这次单元化测试需要初始化哪些资源,你要构建自己的一些测试的数据集。因为是这样的,你是写 dao 层的单元测试的话,可能就需要 database.sql 做一些数据的初始化,如果你是做 service 的单元测试的话,实际你可以把整个 dao 给 mock 掉,我觉得反而还相对简单,所以我们主要针对场景就是在 dao 里面偏持久层的,利用 docker-compose 来解决。 容器的拉起,容器的销毁,这些工作到底谁来做?是开发同学自己去拉起和销毁,还是说你能够把它做成一个 Library,让我们的同学写单元测试的时候比较方便?我倾向的是后者。所以在我们最终写单元测试的时候,你可以很方便地 setup 一个依赖文件,去 setup 你的容器的一些信息,或者把它销毁掉。所以说,你把环境准备好以后,最终可以跑测试代码也非常方便。当然我们也提供了一些命令函,就是 binary 的一些工具,它可以针对各个语言方便地拉起容器和销毁容器,然后再去执行代码,所以我们也提供了一些快捷的方式。 刚刚我也提到了,就是我们对于 service 也好,API 也好,因为依赖下层的 dao 或者依赖下层的 service,你都很方便 mock 掉,这个写单元测试相对简单,这个我不展开讲,你可以使用 GoMock 或者 GoMonkey 实现这个功能。 Toolchain 我们利用多个 docker-compose 来解决 dao 层的单元测试,那对于我刚刚提到的项目的一些规范,单元测试的一些模板,甚至是我写了一些 dao 的一些占位符,或者写了一些 service 代码的一些占位符,你有没有考虑过这种约束有没有人会去遵循?所以我这里要强调一点,工具一定要大于约束和文档,你写了约束,写了文档,那么你最终要通过工具把它落实。所以在我们内部会有一个类似 go tool 的脚手架,叫 Kratos Tool,把我们刚刚说的约定规范都通过这个工具一键初始化。 对于我们内部的工具集,我们大概会分为几块。第一块就是 API 的,就是你写一个 PB 文件,你可以基于这个 PB 文件生成 gRPC,HTTP 的框架代码,你也可以基于这个 PB 文件生成 swagger 的一些 JSON 文件或者是 Markdown 文件。当然了,我们还会生成一些 API,用于 debug 的 client 方便去调试,因为我们知道,gRPC 调试起来相对麻烦一些,你要去写代码。 还有一些工具是针对 project 的,一键生成整个应用的 layout,非常方便。我们还提了 model,就是方便 model 和 DTO,DTO 就是 API 里面定义的 message 的 struct 做 DeepCopy,这个也是一个工具。 对于 cache 的话,我们操作 memcache,操作 Redis 经常会要做什么逻辑?假如我们有一个 cache aside 场景,你读了一个 cache,cache miss 要回原 DB,你要把这个缓存回塞回去,甚至你可能这个回塞缓存想异步化,甚至是你要去读这个 DB 的时候要做归并回源(singleflight),我们把这些东西做成一些工具,让它整个回源到 DB 的逻辑更加简单,就是把这些场景描述出来,然后你通过工具可以一键生成这些代码,所以也是会比较方便。 我们再看最后一个,就是 test 的一些工具。我们会基于项目里面,比方说 dao 或者是 service 定义的 interface 去帮你写好 mock 的代码,我直接在里面填,只要填代码逻辑就行了,所以也会加速我们的生产。 上图是 Kratos 的一个 demo,基本就是支持了一些 command。这里就是一个 kratos new kratos-demo 的一个工程,-d YourPath 把它导到某一个路径去,--proto 顺便把 API 里面的 proto 代码也生成了,所以非常简单,一行就可以很快速启动一个 HTTP 或者 gRPC 服务。 我们知道,一个微服务的框架实际非常重,有很多初始化的方式等等,非常麻烦。所以说,你通过脚手架的方式就会非常方便,工具大于约定和文档这个这个理念就是这么来的。 Configuration 讲完工具以后,最后讲一下配置文件。我为什么单独提一下配置文件?实际它也是工程化的一部分。我们一个线上的业务服务包含三大块,第一,应用程序,第二,配置文件,第三,数据集。配置文件最容易导致线上出 bug,因为你改一行配置,整个行为可能跟 App 想要的行为完全不一样。而且我们的代码的开发交付需要经过哪些流程?需要 commit 代码,需要 review,需要单元测试,需要 CD,需要交付到线上,需要灰度,它的整个流程是非常长的。在一步步的环境里面,你的 bug 需要前置解决,越前置解决,成本越低。因为你的代码的开发流程是这么一个 pipeline,所以 bug 最终流到线上的概率很低,但是配置文件没有经过这么复杂的流程,可能大家发现线上有个问题,决定要改个线上配置,就去配置中心或者配置文件改,然后 push 上线,接着就问题了,这个其实很常见。 从 SRE 的角度来说,导致线上故障的主因就是来自配置变更,所以 SRE 很大的工作是控制变更管理,如果能把变更管理做好,实际上很多问题都不会出现。配置既然在整个应用里面这么重要,那在我们整个框架或者在 Go 的工程化实践里面,我们应该对配置文件做一些什么事情? 我觉得是几个。第一,我们的目标是什么?配置文件不应该太复杂,我见过很多框架,或者是业务的一些框架,它实际功能非常强大,但是它的配置文件超级多。我就发现有个习惯,只要有一个同事写错了这个配置,当我新起一个项目的时候,一定会有人把这个错误的配置拷贝到另外一个系统里面去。然后当发现这个应用出问题的时候,我们一般都会内部说一下,你看看其他同事有没有也配错的,实际这个配错概率非常高。因为你的配置选项越多,复杂性越高,它越容易出错。所以第一个要素就是说,尽量避免复杂的配置文件。配得越多,越容易出错。 第二,实际我们的配置方式也非常多,有些用 JSON,有些用 YAML,有些用 Properties,有些用 INI。那能不能收敛成通用的一种方式呢?无论它是用 Python 的脚本也好,或者是用 JSON 也好,你只要有一种唯一的约定,不需要太多样的配置方式,对我们的运维,对我们的 SRE 同时来说,他跨项目的变更成本会变低。 第三,一定要往简单化去努力。这句话其实包含了几个方面的含义。首先,我们很多配置它到底是必须的还是可选的,如果是可选,配置文件是不是就可以把它踢掉,甚至不要出现?我曾经有一次看到我们 Java 同事的配置 retry 有一个重试默认是零,内部重试是 80 次,直接把 Redis cluster 打故障了,为什么?其实这种事故很低级,所以简单化努力的另外一层含义是指,我们在框架层面,尤其是提供 SDK 或者是提供 framework 的这些同事尽量要做一些防御编程,让这种错配漏配也处于一个可控的范围,比方重试 80 次,你觉得哪个 SDK 会这么做?所以这个是我们要考虑的。但是还有一点要强调的是,我们对于业务开发的同事,我们的配置应该足够的简单,这个简单还包含,如果你的日志基本上都是写在这个目录,你就不要提供这个配置给他,反而不容易出错。但是对于我们内部的一些 infrastructure,它可能需要非常复杂的配置来优化,根据我的场景去做优化,所以它是两种场景,一种是业务场景,足够简单,一种是我要针对我的通用的 infrastructure 去做场景的优化,需要很复杂的配置,所以它是两种场景,所以我们要想清楚你的业务到底是哪一种形态。 还有一个问题就是我们配置文件一定要做好权限的变更和跟踪,因为我们知道上线出问题的时候,我们的第一想法不是查 bug,是先止损,止损先找最近有没有变更。如果发现有变更,一般是先回滚,回滚的时候,我们通常只回滚了应用程序,而忘记回滚了配置。每个公司可能内部的配置中心,或者是配置场景,或者跟我们的二进制的交付上线都不一样,那么这里的理念就是你的应用程序和配置文件一定是同一个版本,或者是某种意义上让他们产生一个版本的映射,比方说你的应用程序 1.0,你的配置文件 2.0,它们之间存在一个强绑定关系,我们在回滚的时候应该是一起回滚的。我们曾经也因为类似的一些不兼容的配置的变更,二进制程序上线,但配置文件忘记回滚,出现过事故,所以这个是要强调的。 另外,配置的变更也要经过 review,如果没问题,应该也是按照 App 发布一样,先灰度,再放量,再全量等等类似的一种方式去推,演进式的这种发布,我们也叫滚动发布,我觉得配置文件也是一样的思路。 加入阿里云钉钉群享福利:每周技术直播,定期群内有奖活动、大咖问答 原文链接

有只黑白猫 2020-01-09 17:29:54 0 浏览量 回答数 0

回答

在校生要找到好工作,主要靠几个光环,学校光环、竞赛光环、项目光环、实习光环。其中项目经验尤为重要。有些同学就有疑问了: “我校招没offer,没有项目经验,是不是要报个培训班?” “我转行计算机,是不是应该报个班?” “我也想自学,可怎么学啊,选哪个方向啊?” 对于有些同学,当我还在想办法劝他自学时,给我贴出了培训班的广告词,真可谓,人有多大胆,口号就有多不要脸: “0基础入学,三个月包就业” “毕业月入不过万,不收学费” “从前是你找工作,接下来是工作找你” 当我推荐某些同学去培训时,又给咔咔咔亮出了几个帖子,说培训出来的受歧视啊、有些同学培训出来还是找不到工作啊,等等。 其实,选择自学还是培训是看自身情况而定,无论选择自学还是培训,都只是入门的一种手段,各有优劣势,本文就详细说说自学/培训怎么选,选择以后怎么办,记得帮我点赞哦。   目录: 自学还是培训,怎么选? 自学怎么学? 培训班到底在培训什么? 有些企业歧视培训班学员,培训班的问题到底出在哪? 一些建议 一、自学还是培训,怎么选? 无论你是什么学历、有没有计算机基础,这些都不是决定你适合自学的条件,具备如下三个条件的人都可以选择自学: (1)、时间充足 如果说从零基础靠自学达到找工作的水平,需要多久呢?我觉得至少一年,有的人可能需要两年。所以,如果你是大一、大二、大三的学生,你还有时间,可以选择自学。如果你是已经工作的,想转行计算机,可以边工作边学习,这个过程会比较辛苦,但也不是绝对不可行。 对于大四的同学,以就业为导向,建议你去培训。不可否认,培训是最快入门的方式,对于时间不足的同学而言,培训是最优解。同样地,如果你是已工作的,不存在财务压力,我同样建议你去培训,工作后的时间很珍贵,比不上在校期间有大把时间可以浪费,如果做好了必转的决心,以最快速度转行才是最优解。 (2)、自控力强 能管得住自己,自己定的目标能想尽一切办法实现的同学,真不多,能占人群中1/4已经不错了。 有些人学了半小时就会累,休息一会,就成这样: 我见过太多的半途而废的同学,也见过太多自己安慰自己式的学习方式,但就业就是一个试金石,你这段时间的努力有没有回报,去找工作的时候,就水落石出。 如果在自律这方面不太行的话,可以看下这篇文章,《启舰:你是怎么变自律的?》,找到自已的驱动器,完成自己的梦想。 (3)、具备高中以上学历 计算机本身是数学家发明的,或多或少会用到一些基本的数学知识、经常用到的很多算法都是数学知识的延伸,没有基本的数学功底,自学确实很难。 至于英语阅读能力还好说,只要会用有道词典,不会的去搜去看,总会读懂的,而且入门级的文献和视频中文版的资料已足够你入门,英语应该不是太大的问题。 如果你这三点都满足,恭喜你,你具有了自学的基础,可以选择自学。 二、自学怎么学? 1、选定一个方向 首先,我们选择方向的目的是什么?不就是为了找份工作吗?那直接到招聘类网站去搜下相关的岗位数量及要求不就好了,哪个数量多,自己也喜欢,那就选这个即可。 其次,如果是大三、大四即将毕业的同学,想知道最近哪个岗位好找工作的话。还可以看看很多培训机构的培训内容,现在很多培训机构都声称保就业,真的以为,培训几个月能培训出朵花来吗?不可能的,编程是个需要长期训练的活,几个月的培训,仅是入门而已,入门的水平能保证找份工作,就靠的是这个岗位门槛低,需求大,好找工作。 如果实在不知道选什么,我帮你找几个方向:python、java后端、Html5就业岗位都挺多,就业门槛低,相对好就业,如果也有其它方向推荐,大家可以留言。 2、找到几套视频教材 在入门时强烈不建议跟着书学 第一,不一定能看得懂 第二,书本的知识不成体系,入门有入门的书,进阶有进阶的书,实战有实战的书,需要自己去选择,本身就不是一件易事。 第三,视频可以看到老师的操作,而书本全靠自己摸 现在某某培训班的入门、进阶、实战的系列视频不要太好找,找到这么两套视频,对比着看,或者跟着一套视频深入看,来得更容易。人家培训班安排好的路线跟着学,不懂的自己搜,就已经排除了自已给自己安排路线的难点,况且人家本身就是面向就业的,培训出来的同学能保就业,只要你能跟着学通学会,自然找到工作也不是问题。 我精心整理了计算机各个方向的从入门、进阶、实战的视频课程和电子书,都是技术学习路上必备的经验,跟着视频学习是进步最快的,而且所有课程都有源码,直接跟着去学!!! 只要关注微信公众号【启舰杂谈】后回复你所需方向的关键字即可,比如『Android』、『java』、『ReactNative』、『H5』、『javaweb』、『面试』、『机器学习』、『web前端』、『设计模式』等关键字获取对应资料。(所有资料免费送,转发宣传靠大家自愿) 视频内容非常多,总共2184G、一千六百多册电子书,九百多套视频教程,涉及43个方向。我整理了很长时间,有些资料是靠买的,希望大家能最快的提升自己。帮我点个赞吧。 启舰:全网2184G计算机各方向视频教程/电子书汇总(持续更新中)​   3、自学,除了知识,你还能学到什么? 自学的缺点很明显: 第一:速度慢,所有进度完全靠自己把控,没有氛围 第二:遇到问题需要自己解决,无人请教 那优点恰恰是从这些缺点中磨练出来的,进度靠自己把握,完全磨练了你的意志力。而所有问题靠自己解决,恰恰培养了你的解决问题的能力。 而这些能力都是培训班教不出来的、无法速成的。而这些能力却是真正的开发高手所必备的 问题定义、分析与设计阶段,这是最需要智商、创造力和经验的阶段,真正的开发高手,就是在这一阶段体现出远超普通人的水平,而在这一阶段所需要的能力,对不起,培训班教不出来,也无法速成,只能靠人自己的努力,慢慢地培养和增强。 4、自学建议 (1)、多做笔记、多复习 刚开始学习时,很难,真的很难。很多东西听不懂,很多东西需要自己搜,自己定的进度很可能完不成。 没关系,坚持下去,都是这么过来的。我刚开始自学的时候,也是无数次想死的冲动…… 学会做笔记,把自己学到的东西及时记下来,形成目录,在后面用到的时候,根据笔记再去看一遍,刚开始经常会出现,听得懂,跟着学会,自己弄就不会的现象。这都是正常的,技术本就是个熟能生巧的过程。 多动手,多总结,就慢慢熟练了。 (2)、多写代码!听得懂、看得懂,并没什么用 入门级知识,本就是语法和框架的熟悉过程,说到底就是工具的使用方法熟悉的过程。既然是工具,那就必然要多用。熟能生巧,指的是用的熟。很多同学看的懂,听的会,自己一下手就问题百出,就是练的少! (3)、听不懂,搜一下,再不懂就放过 刚学的时候很多概念听不懂,没关系,自己搜一下,能理解了就理解,理解不了就算。听一遍就行,学到后面的时候,你就懂些了回头,再看看那些知识,基本上你都懂了。 (4)、多写注释 刚开始的时候,很多逻辑弄不懂,没关系,自己把代码拆解,并对其加以注释,这样,你在反过来再看这些代码时,能很快弄懂它的逻辑。你要知道,你后面学习时还是会碰到这些知识的,而在只看一遍的情况下是不可能记得住的,到时候,你还是会返回来复习这些知识的。 增加注释,看起来浪费时间,其实是整理代码逻辑的过程。浑浑噩噩敲出来的代码,自己都不明白什么意思的话,其实相当于没有真正学会。 三、培训班到底在培训什么? 去培训的主要原因,说到底还是因为自己啥都不会。但不会与不会间是有区别的。 对于科班出身的,上学又好好学了的同学,虽然他们没有系统的编程知识,没有项目经验,但他们有计算机基础,他懂得操作系统原理、数据结构与算法等原理性知识。 而对于跨专业和在玩了四年的同学而言,那才是真正的零基础。 而对于培训机构而言,它的责任就是让你实现从0到1的入门过程,而有经验的老鸟都知道,编程入门仅仅是知识的堆积,并没有什么技巧性可言。所有的语法和框架运用,简单来说,就是学会编程套路,学习工具使用。 而培训机构的责任,就是把这些套路教给你。只要你不太笨,经过几个月的强化训练,大部分人都能学得会。 所以,培训班教你的就是工具的使用,目的,就是以最快的速度塞给你,助你找到工作。 四、有些企业歧视培训班学员,培训班的问题到底出在哪? 培训机构有着熟练的授课体系,老师手把手答疑,让你在学习路上没有一丁点的思考时间,为的就是以最快的速度让你达标,好结课,开始下一波培训。 1、问题就出在速度上。 认知科学的研究成果表明,知识的消化与吸收,职业技能的学习与精通,本质上是在大脑神经元之间建立连接,重塑大脑结构的过程,这个过程的时间可以缩短,但不能无限地缩短。另外,不同的人,拥有不同的背景和基础,在学习与掌握相同的知识与职业技能时,所花的时间是不一样的。 而培训机构才不管这些,他的目的就是挣钱,以最快的速度挣钱,能在三天内把所有内容塞给你绝不用四天,只要最终能糊弄住面试官,让学员找到一份工作就可以了。 所以,必然会出现下面的现象: 对于原来有一些基础的,学习能力较强的同学,在学习之前已经有较扎实的基础,所以在培训期间能够自己构建成技术体系,知识吸收相对较好: 而另一些学员,则会出现消化不良的情况: 2、培训后遗症 对于软件开发而言,所有的软件开发都大致分为两个阶段: 1、分析、定义、设计阶段。这个阶段是需要有解决问题、分析问题的能力。而这个能力培训班培训不出来,只能是慢慢增强。 2、语法、工具的使用,将设计的内容实现出来。这一块就比较机械了,工具嘛,学一学都能会,培训班在这一块的效率是很高效的,它们多半能在较短的时间内,教会学员特定编程语言(比如Python)特定工具(比如Git)与特定技术的使用(比如Spring MVC),并且传授给他们一些开发的“套路”(比如分层架构与设计模式),从而将学员成功地培养成为一个能够“搬砖”的软件工人,即初级程序员。 培训班一般都会选择门槛低、就业岗位多的方向进行培训,对于这类岗位,人才缺口大,只要能直接上手写代码的初级程序员,都很容易找到一份工作。这也就是为什么培训班多半会收学生五位数的学费,而学生也愿意支付的根本原因。 (1)、解决问题能力差,动不动就得人教 经过几个月饭来张口、衣来伸手的填鸭式集训,有些人在工作后,却依然认为,当他遇到问题时,从来不想着自己搜搜资料解决,而是依赖同事帮他答疑! 自学能力差、解决问题能力差,是很多人找到了工作,过不了试用期的根本原因。 (2)、培训效果立竿见影,却又很快遗忘 任何的知识都是一样,短时间内填鸭式学到的知识,在一段时间不用后,就会遗忘。这就是有些同学刚从培训班出来时,能找到份工作,当学到的东西在工作中几个月用不到时,就很快忘记,总觉得自己还是啥都不会的原因。 永远要记住:学历不行靠实力,实力不行靠态度!!! 当我们初入职场,尽心尽责地把自己的工作做完做好的同时,千万不要忘记像海绵一样,以最快的速度给自己充水。 像培训完的同学,在校期间已经做了很多的笔记,工作之余,多复习,重新练,利用时间将它理解,真正内化为自己的本领。 对于自学的同学,多找进阶性书籍和视频去看,以最快的速度提升自己。 文末我整理了计算机各个方向的从入门、进阶、实战的视频课程和电子书,都是技术学习路上必备的经验,跟着视频学习是进步最快的,而且所有课程都有源码,直接跟着去学!!! 五、一些建议 1、非科班同学建议 对于非科班转行计算机的同学,有太多的知识需要补足,如果你靠的是自学,需要强有力的自律能力,只要时间还够,是可以靠自学的,在跟着视频学的时候,哪里听不懂及时去搜相关的资料去补足。 刚开始自学时,即便是科班出身也是有想死的冲动的,大家都一样。我也是靠自学过来的,很多的东西不会,很多的东西听不懂。没关系,多做笔试,多搜资料,把不会的弄会,你会发现,学习起来越来越容易。 所有的困难只不过是纸老虎,坚持过去就成功了。 如果你是通过培训找到了一份工作,你需要比别人更努力补充计算机知识,基础知识的缺乏,会使你很难在这条路上走很远,所有的大神,都是自学能力很强的人,你想,你也可以。 2、所有开发方向都必须从C++开始? 经常会有要校生问我:我要做H5开发,是不是要先学C++? 其实,各个语言之间是没有任何关联的,完全都是有各自的语法体系和开发工具的,简单来讲,他们都是不同类型的工具。 你学会一种工具,只会对另一种类似的工具更容易上手,而不是完全不用学。所以,想学哪个方向,直接去学就行了,没必须先从C++入手迂回一下,纯属浪费时间。 但,如果你还在上学,现在正在学C++,那我还是建议你好好学,必须C语言语法更接近低层编译器原理,学会了它,对理解低层分配、释放、编译机制都是很有用的,但就以工作为导向而言,如果你不从事C++相关工作,是没必要学的。 3、培训出来人人工资过万? 有个男生非常沮丧的找我,自己是专科毕业,培训完,小公司不想进,大点的公司进不去,给的工资也不高,问我怎么办? 上面我们已经讲到,对于不同程度的同学,在培训出来的结果是不一样的,你要分清,你培训完的情况是属于这种: 还是这种? 对于没有名校光环的同学,建议以先就业为主。 别看培训班招你的时候给你洗脑,培训完人人过万,但能不能过万,最终靠的是自己,而不是培训班。 认请自己的情况,可以先就业,再优化自己履历,而进步步高升。 4、建议不要暴露自己的培训经历 你百度、知乎搜一下,遍地的培训歧视,很多公司根本不要培训出来的同学. 业界对培训有偏见,因为写代码是一个逐渐学习、熟练的过程,经过几个月集中的培训,虽然看起来什么都接触到了,但真正能内化为自己知识的部分其实不多。在工作中并不能熟练运用,仅是入门水平而已。 而且大家普遍认为参加培训的主要原因是因为,大学中没好好学,临近毕业了,催熟一把。不然,谁会花这几万块钱呢?对普通家庭而言,其实也并不是个小数目了。 有一个外包公司的朋友,技术总监,招人时培训公司出来都不要,原因就是干活能力不行。当然这仅代表个例,但大家需要注意的是,业界并不认为培训是一件光彩的事,千万不要搞错了!!! 5、培训班防骗三十六计 现在太多的培训机构,一个个把自己吹的天花乱坠,我也建议过小伙伴去培训,但小孩子交完钱培训一个月就退费了,深感自己好心做了坏事,这里建议大家培训市场,鱼龙混杂,一定要提前做好防骗准备。 谎言之所以真实是因为年青的心太不甘寂寞,太急于求成! 从网上找了,培训班防骗三十六计,供大家参考: “借刀杀人”:培训班间竞争激烈,彼此勾心斗角,正好为我所用。去培训班甲问乙如何,到培训班乙打听甲。Ha.Ha..,狗咬狗开始了,一时间内幕迭报:乙设备不全,很多实验不能做;甲的那个号称CCIE的老师只过了笔试,没过实验室,假的! “声东击西”:与甲约好星期六考察学校,结果星期X跑去(1=< X <= 5)。   “你怎么来了?”   “我星期六有事,所以提前来看看……” “抛砖引玉”:有时候,拿不定注意或者培训班在外地,实地考察有难度,何不到论坛发个帖子征求意见,要是能得到已经培训过的前辈的释疑,那你绝对是不虚此帖了! “假痴不癫”:有时候你可能偶然拥有一些内幕消息,不如试试他们的诚实度。   “听说你们的教师是CCIE!”   “那当然,技术首屈一指,……”   此时此刻,看着乙那得意样样的小样,不知是好笑,还是可气。不过记住:一个没有诚信的公司是什么都干的出来的! “反间计”:一个卑鄙的培训班后面一般都有一个卑鄙的流氓大亨,他不仅千方百计的从学员那里榨取钱财,对自己的手下也不会心慈手软,本着人们内部矛盾的原则发展一个或多个间谍。 “走为上计”:经过一番打探,知道他们都不是东西,还犹豫什么?宁缺毋滥,走人! 最后,如论怎么选,自终也只是入门阶段,为了找到一份工作。对于初入职场的你们,给一条最终建议:学校不行靠实力,实力不行靠态度。记得帮我点赞哦。 ———————————————— 版权声明:本文为CSDN博主「启舰」的原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接及本声明。 原文链接:https://blog.csdn.net/harvic880925/article/details/103413853

问问小秘 2020-01-07 10:55:15 0 浏览量 回答数 0
阿里云大学 云服务器ECS com域名 网站域名whois查询 开发者平台 小程序定制 小程序开发 国内短信套餐包 开发者技术与产品 云数据库 图像识别 开发者问答 阿里云建站 阿里云备案 云市场 万网 阿里云帮助文档 免费套餐 开发者工具 企业信息查询 小程序开发制作 视频内容分析 企业网站制作 视频集锦 代理记账服务 2020阿里巴巴研发效能峰会 企业建站模板 云效成长地图 高端建站