一种残膜回收机防缠绕挑膜装置的制 一种秧草收获机用电力驱动行走机构

分析微服务架构下函数调用关系的方法及装置与流程

2022-11-16 10:44:26 来源:中国专利 TAG:


1.本公开涉及计算机技术领域,尤其涉及静态程序分析领域。


背景技术:

2.静态程序分析(static program analysis)是指在不实际执行程序的条件下,对代码的语义和行为进行分析的方法。随着近些年go语言的快速发展,静态程序分析技术在go函数调用关系和编码规范检查等方面也应用非常广泛。
3.但当前已有静态程序分析工具通常仅支持以主函数作为指针分析起点,对于一些依赖动态调用处理请求的程序(例如http server),以主函数为指针分析起点的静态分析由于动态调用边的不可达问题,会损失大量函数调用关系分析结果。


技术实现要素:

4.本公开提供了一种分析微服务架构下函数调用关系的方法及装置。
5.根据本公开的一方面,提供了一种分析微服务架构下函数调用关系的方法,包括:获取多个函数作为静态指针分析起点;根据所述静态指针分析起点对目标代码库进行静态程序分析,并根据分析结果生成函数调用图,所述函数调用图中包括基于所述静态指针分析起点确定的多个调用边,所述调用边用于表征以静态指针分析起点作为调用者节点进行函数调用的函数调用关系;遍历所述函数调用图中包括的多个调用边,得到存储至图数据库中的目标调用边。
6.根据本公开的另一方面,提供了一种分析微服务架构下函数调用关系的装置,包括:获取模块,用于获取多个函数作为静态指针分析起点;分析模块,用于根据所述静态指针分析起点对目标代码库进行静态程序分析,并根据分析结果生成函数调用图,所述函数调用图中包括基于所述静态指针分析起点确定的多个调用边,所述调用边用于表征以静态指针分析起点作为调用者节点进行函数调用的函数调用关系;处理模块,用于遍历所述函数调用图中包括的多个调用边,得到存储至图数据库中的目标调用边。
7.根据本公开的另一方面,提供一种电子设备,包括:至少一个处理器;以及与所述至少一个处理器通信连接的存储器;其中,所述存储器存储有可被所述至少一个处理器执行的指令,所述指令被所述至少一个处理器执行,以使所述至少一个处理器能够执行上述的方法。
8.根据本公开的另一方面,提供一种存储有计算机指令的非瞬时计算机可读存储介质,其中,所述计算机指令用于使所述计算机执行上述的方法。
9.根据本公开的另一方面,提供一种计算机程序产品,包括计算机程序,所述计算机程序在被处理器执行时实现上述的方法。
10.本公开提供的分析微服务架构下函数调用关系的方法,可以获取更全面的函数调用关系,生成更全面的函数调用图,基于函数调用图得到的分析结果也相应更加准确。
11.应当理解,本部分所描述的内容并非旨在标识本公开的实施例的关键或重要特
征,也不用于限制本公开的范围。本公开的其它特征将通过以下的说明书而变得容易理解。
附图说明
12.附图用于更好地理解本方案,不构成对本公开的限定。其中:
13.图1是根据本公开实施例提供的一种分析微服务架构下函数调用关系的方法流程图;
14.图2是根据本公开实施例提供的另一种分析微服务架构下函数调用关系的方法流程图;
15.图3是根据本公开实施例提供的又一种分析微服务架构下函数调用关系的方法流程图;
16.图4是根据本公开实施例提供的又一种分析微服务架构下函数调用关系的方法流程图;
17.图5是根据本公开实施例提供的一种分析微服务架构下函数调用关系的装置的框图;
18.图6是用来实现本公开实施例的分析微服务架构下函数调用关系的方法的电子设备的框图。
具体实施方式
19.以下结合附图对本公开的示范性实施例做出说明,其中包括本公开实施例的各种细节以助于理解,应当将它们认为仅仅是示范性的。因此,本领域普通技术人员应当认识到,可以对这里描述的实施例做出各种改变和修改,而不会背离本公开的范围和精神。同样,为了清楚和简明,以下的描述中省略了对公知功能和结构的描述。
20.静态程序分析(static program analysis)是指在不实际执行程序的条件下,对代码的语义和行为进行分析的方法。随着近些年go语言的快速反正,静态程序分析技术在go函数调用关系和编码规范检查等方面也应用非常广泛。但当前已有静态程序分析工具通常仅支持以func main()函数作为指针分析起点,对于一些依赖动态调用处理请求的程序(例如http server),以func main()函数为指针分析起点的静态分析由于动态调用边的不可达问题,从而会损失大量函数调用关系分析结果。另一方面,当前已有的静态程序分析工具也无法解析基于http server的微服务架构中的跨服务调用关系,造成部分函数调用关系结果不准确。
21.例如,go官方的module golang.org/x/tools实现了andersen's指针分析算法,提供了基本的函数调用图生成能力。然而go官方库只支持以package main中的func init()和func main()作为指针分析起点,对于存在web server这种依赖动态调用处理请求的程序是致命的,因为这意味着静态程序分析不可达,必然会损失大量分析结果。
22.就一个具体的例子而言,为了避免router配置过度膨胀,go语言的web server经常会使用reflect建立动态路由,对静态程序分析来说,如果只能指定func main()为起点,controller下的函数是不可达的。
23.基于此,本公开实施例提供了一种分析微服务架构下函数调用关系的方法,采取多个函数作为静态指针分析起点对目标代码库进行静态程序分析,能够实现获取更加全面
的函数调用关系生成更全面的函数调用图,从而基于函数调用图得到全面的函数调用关系的分析结果。
24.图1是根据本公开一示例性实施方式中示出的一种分析微服务架构下函数调用关系的方法流程图,该方法包括以下步骤:
25.在步骤s101中,获取多个函数作为静态指针分析起点。
26.其中,静态指针分析起点用于在对代码库进行静态程序分析时,以静态指针分析起点出发,分析代码库中的函数调用关系。
27.可选的,用户可以自定义配置多个函数作为静态指针分析起点,通过对官方库进行改造,将多个函数传入到官方库中,在分析程序初始化时,从官方库中读取用户自定义的配置,得到各个代码库的静态指针分析起点。
28.具体的,pointer.config模块用于管理各个代码库的分析起点,当没有对官方库进行改造之前,pointer.config模块默认传入ssa.package类型的main包,从main包中获取func main()和func init()并转换为cgnode后,开始执行静态程序分析。
29.而本公开实施例通过对官方库进行改造,在pointer.config模块中新增字段,可以传入自定义的non-main函数作为起点,自定义的non-main函数可以为任意有名函数。在需要进行静态程序分析时,读取自定义的non-main函数配置,将自定义的non-main函数和对应pacakge的init函数转换为cgnode,作为静态指针分析起点。
30.在步骤s102中,根据静态指针分析起点对目标代码库进行静态程序分析,并根据分析结果生成函数调用图。
31.其中,函数调用关系图中的节点是程序中所有函数的集合,图中的边也被称为调用边,表示函数之间的调用关系。如果函数间存在调用关系,那么节点间会通过有向弧相连接,这个有向弧从调用者节点指向被调用者节点。如果调用关系图中存在环,说明程序中存在递归调用。
32.在本公开实施例中,函数调用图中包括基于静态指针分析起点确定的多个调用边,调用边用于表征以静态指针分析起点作为调用者节点进行函数调用的函数调用关系。
33.示例性的,目标代码库的静态指针分析起点为3个,分别为main函数、c函数、f函数,经静态程序分析得到目标代码库的函数调用关系为main-》a-》b,c-》d,f-》i,则main-》a-》b表示以main函数作为静态指针分析起点确定的调用边,main函数为调用者节点(caller),b函数为被调用者节点(callee),同理,c-》d,f-》i分别表示以c函数和f函数作为静态指针分析起点确定的调用边,c函数和f函数为调用者节点,d函数和i函数为被调用者节点。
34.在步骤s103中,遍历函数调用图中包括的多个调用边,得到存储至图数据库中的目标调用边。
35.可选的,先将多个调用边中的每个调用边的caller节点和callee节点转换为利于操作和存储的规格化数据,再对多个调用边进行遍历,以减短遍历时间。
36.本公开实施例通过获取多个函数作为静态指针分析起点,基于静态指针分析起点对目标代码库进行静态程序分析生成的函数调用图可以更加全面的体现目标代码库中的函数调用关系,进而基于函数调用图存储至图数据库中的目标调用边更加全面而准确。
37.图2是根据本公开实施例中遍历函数调用图中包括的多个调用边,得到存储至图
数据库中的目标调用边方法的流程示意图,参照图2,该方法包括以下步骤。
38.在步骤s201中,遍历函数调用图中包括的多个调用边,并确定多个调用边中每一调用边的调用类型。
39.其中,调用类型包括服务内调用或服务间调用。
40.可选的,服务内调用表示调用者节点和被调用者节点属于同一个模块中的函数,也即调用者节点和被调用者节点所在的服务名相同。服务间调用表示调用者节点和被调用者节点属于不同模块中的函数,也即调用者节点和被调用者节点所在的服务名不同。
41.示例性的,用户信息和用户昵称存储在user模块,用户权限存储在perm模块,当我们需要获取用户信息时,首先需要获取用户昵称,根据用户昵称去寻找对应的用户信息,此时调用关系为user模块-》user模块,属于同一模块,也即服务内调用。当我们需要获取用户权限时,需要先获取用户昵称,根据用户昵称去寻找对应的用户权限,此时调用关系为perm模块-》user模块,属于不同模块,也即服务间调用。
42.可选的,在遍历函数调用图中包括的多个调用边时,基于用户自定义的函数规则确定每一调用边的调用类型。
43.在步骤s202中,确定调用类型为服务内调用的第一调用边。
44.在步骤s203中,基于第一调用边确定目标调用边,并将目标调用边存储至图数据库。
45.可选的,在将目标调用边写入图数据库时,会根据图数据库中已经存储的数据对目标调用边进行自动去重,若图数据库中已经存在该目标调用边,则不再将目标调用边存储至图数据库。
46.在本公开实施例中,基于函数调用图对函数调用图中的每一个调用边进行分析,可以分析出调用边属于服务内调用还是服务间调用,相较于现有技术中无法分析调用边的类型,本公开实施例可以准确分析出调用边的类型,且由于函数调用图覆盖更全面,基于函数调用图分析出属于服务内调用的调用边更加准确而全面,从而使图数据库中存储的数据更加全面,在后续查询图数据库时,获取的查询结果更加准确。
47.进一步的,在第一调用边中筛选符合预设要求的第一调用边,作为目标调用边。若第一调用边不符合预设要求,则将不符合要求的第一调用边丢弃。
48.在本公开实施例中,通过对第一调用边进行筛选,将不符合要求的调用边丢弃,使存储至图数据库中的调用边更加准确。
49.图3是根据本公开的另一种遍历函数调用图中包括的多个调用边,得到存储至图数据库中的目标调用边方法的流程示意图,参照图3,该方法包括以下步骤。
50.在步骤s301中,遍历函数调用图中包括的多个调用边,并确定多个调用边中每一调用边的调用类型。
51.在步骤s302中,确定调用类型为服务间调用的第二调用边,以及第二调用边所对应的被调用者节点。
52.可选的,在确定第二调用边的调用类型为服务间调用后,从函数调用图中将第二调用边剥离出来,并将第二调用边序列化并按照行顺序存储至全局临时文件。
53.其中,每条序列化数据都包含了第二调用边中调用者节点和被调用者节点的基本信息,如service_name、package_name、receiver_name、function_name。
54.在步骤s303中,若被调用者节点为预设节点,则将第二调用边存储至图数据库中。
55.在本公开实施例中,通过确定调用类型为服务间调用的第二调用边,并判断第二调用边的被调用者节点是否为预设节点,若为预设节点,则表示第二调用边可以调用到实际需要的函数,因此直接存储到图数据库中,使图数据库中存储的调用边都是准确而符合功能要求的调用边。
56.一些实施例中,假设有两个独立的服务user和perm,分别对应module hello/world/perm和module hello/world/user,perm服务中的函数通过服务间调用调用user中的函数。静态程序分析直接得到的调用边是:[perm][demo][][getuserinfo]-》[perm][demo][][remotecall];而实际期望的调用边是:[perm][demo][][getuserinfo]-》[user][][][getusername]。虽然静态程序分析得到的结果符合go语言语义,但是不符合对功能的期望,因此我们需要处理这种特殊情况,解析得到实际期望的结果。下面将对这种特殊情况进行说明,如图4所示,包括以下步骤。
[0057]
在步骤s401中,遍历函数调用图中包括的多个调用边,并确定多个调用边中每一调用边的调用类型。
[0058]
在步骤s402中,确定调用类型为服务间调用的第二调用边,以及第二调用边所对应的被调用者节点。
[0059]
在步骤s403中,若被调用者节点不是预设节点,则提取第二调用边的实参。
[0060]
其中,实参包括服务名称service_name和功能名称function_name。
[0061]
具体的,若第二调用边被存储在全局临时文件中,先将全局临时文件中的文本行反序列化,获取被调用者节点的函数信息,从被调用者节点所在文件的ast中找到被调用者节点对应的函数,从固定参数位置提取实参,获取service_name和function_name。
[0062]
可选的,ast会在函数调用图生成之后,根据各个源代码文件生成并存储在全局变量中。
[0063]
值得说明的是,本公开实施例中被提取的实参都是通过string字面量传递的。
[0064]
在步骤s404中,查询图数据库中是否存在匹配实参的调用边,并基于查询结果确定对第二调用边的处理方式。
[0065]
其中,处理方式包括丢弃或者存储至图数据库。
[0066]
在本公开实施例中,通过提取第二调用边的实参判断图数据库中是否存在匹配的调用边,并基于不同的查询结果对第二调用边做不同的处理方式,从而使最终存储至图数据库的调用边都是符合预期且准确的调用边。
[0067]
作为一种可能的实现方式,若查询结果为未查询到存在匹配所。实参的调用边,则确定对第二调用边的处理方式为丢弃。
[0068]
作为另一种可能的实现方式,若查询结果为查询到存在匹配实参的调用边,且调用边为单一的调用边,则基于匹配实参的调用边和第二调用边,生成目标调用边,并存储至图数据库中。
[0069]
可选的,基于匹配实参的调用边将第二调用边的callee节点的package和receiver字段补全,生成目标调用边。
[0070]
作为又一种可能的实现方式,若查询结果为查询到存在匹配实参的调用边,且调用边的数量两个或两个以上,则确定对第二调用边的处理方式为丢弃。
[0071]
在本公开实施例中,根据不同的查询结果确定对第二调用边不同的处理方式,当查询结果为查询到存在匹配实参的调用边,且调用边为单一的调用边,则将第二调用边的callee节点的字段补全,从而生成目标调用边,也即功能符合预期要求的调用边,并将其存储至图数据库中,后续在查找图数据库时,查找结果更准确。
[0072]
在一些实施例中,由于在函数调用图中可能存在一种以第二调用边的callee节点为起点的第三调用边,在遍历第三调用边时,由于第三调用边的callee节点与第二调用边的callee节点属于同一类型的函数,因此会将第三调用边确定为服务内调用,由于遍历的最终结果是分析代码库的调用关系,而不是服务间调用内部的调用关系,因此为了减少后续查询图数据库时干扰结果,需要将以第二调用边的被调用者节点为起点的调用边全部剔除。
[0073]
作为一种可能的实现方式,在遍历完函数调用图中包括的全部调用边之后,在图数据库中剔除以第二调用边的被调用者节点为起点的子树。
[0074]
作为另一种可能的实现方式,在遍历完函数调用图中包括的全部调用边之后,在图数据库中切断以第二调用边的被调用者节点为起点的第三调用边,从而使第三调用边的内部调用不可达。
[0075]
作为又一种可能的实现方式,在确定第二调用边之后,立即在函数调用图中剔除以第二调用边为起点的子树。
[0076]
在本公开实施例中,为了减少后续查询图数据库时干扰结果,将以第二调用边的被调用者节点为起点的调用边全部剔除,使后续查询图数据库时获取的查询结果更加准确。
[0077]
基于上述任一实施例,作为静态指针分析起点的多个函数包括主函数和/或非主函数,每一个静态指针分析起点均对应一个主函数或非主函数。
[0078]
本公开实施例通过将非主函数也设置为静态指针分析起点,相较于仅以主函数作为静态分析起点生成的函数调用图更加全面,提升被分析程序的分析覆盖度。
[0079]
基于相同的构思,本公开实施例还提供一种分析微服务架构下函数调用关系的装置。
[0080]
可以理解的是,本公开实施例提供的分析微服务架构下函数调用关系的装置为了实现上述功能,其包含了执行各个功能相应的硬件结构和/或软件模块。结合本公开实施例中所公开的各示例的单元及算法步骤,本公开实施例能够以硬件或硬件和计算机软件的结合形式来实现。某个功能究竟以硬件还是计算机软件驱动硬件的方式来执行,取决于技术方案的特定应用和设计约束条件。本领域技术人员可以对每个特定的应用来使用不同的方法来实现所描述的功能,但是这种实现不应认为超出本公开实施例的技术方案的范围。
[0081]
作为一示例性实施方式,图5是根据本公开一示例性实施方式中示出的一种分析微服务架构下函数调用关系的装置的框图。参阅图5所示,该装置500包括获取模块501、分析模块502以及处理模块503。
[0082]
获取模块501,用于获取多个函数作为静态指针分析起点;
[0083]
分析模块502,用于根据静态指针分析起点对目标代码库进行静态程序分析,并根据分析结果生成函数调用图,函数调用图中包括基于静态指针分析起点确定的多个调用边,调用边用于表征以静态指针分析起点作为调用者节点进行函数调用的函数调用关系;
[0084]
处理模块503,用于遍历函数调用图中包括的多个调用边,得到存储至图数据库中的目标调用边。
[0085]
在一种实施方式中,处理模块503,具体用于遍历函数调用图中包括的多个调用边,并确定多个调用边中每一调用边的调用类型,调用类型包括服务内调用或服务间调用;确定调用类型为服务内调用的第一调用边;基于第一调用边确定目标调用边,并将目标调用边存储至图数据库。
[0086]
在一种实施方式中,处理模块503,具体还用于在第一调用边中筛选符合预设要求的第一调用边,作为目标调用边。
[0087]
在一种实施方式中,处理模块503,还用于确定调用类型为服务间调用的第二调用边,以及第二调用边所对应的被调用者节点;若被调用者节点为预设节点,则将第二调用边存储至所述图数据库中。
[0088]
在一种实施方式中,装置还包括提取模块504和查询模块505,提取模块504,用于若被调用者节点不是预设节点,则提取第二调用边的实参,实参包括服务名称和功能名称;
[0089]
查询模块505,用于查询图数据库中是否存在匹配实参的调用边,并基于查询结果确定对第二调用边的处理方式,处理方式包括丢弃或者存储至图数据库。
[0090]
在一种实施方式中,查询模块505,用于若查询结果为未查询到存在匹配实参的调用边,则确定对第二调用边的处理方式为丢弃;若查询结果为查询到存在匹配实参的调用边,且调用边为单一的调用边,则基于匹配实参的调用边和第二调用边,生成目标调用边,并存储至图数据库中;若查询结果为查询到存在匹配实参的调用边,且调用边的数量两个或两个以上,则确定对第二调用边的处理方式为丢弃。
[0091]
在一种实施方式中,处理模块503,还用于在图数据库中剔除以第二调用边的被调用者节点为起点的子树;或者在图数据库中切断以第二调用边的被调用者节点为起点的第三调用边;或者在函数调用图中剔除以第二调用边为起点的子树。
[0092]
在一种实施方式中,多个函数包括主函数和/或非主函数。
[0093]
关于本公开上述涉及的装置,其中各个模块执行操作的具体方式已经在有关该方法的实施例中进行了详细描述,此处将不做详细阐述说明。
[0094]
本公开的技术方案中,所涉及的用户个人信息的获取,存储和应用等,均符合相关法律法规的规定,且不违背公序良俗。
[0095]
根据本公开的实施例,本公开还提供了一种电子设备、一种可读存储介质和一种计算机程序产品。
[0096]
图6示出了可以用来实施本公开的实施例的示例电子设备600的示意性框图。电子设备旨在表示各种形式的数字计算机,诸如,膝上型计算机、台式计算机、工作台、个人数字助理、服务器、刀片式服务器、大型计算机、和其它适合的计算机。电子设备还可以表示各种形式的移动装置,诸如,个人数字处理、蜂窝电话、智能电话、可穿戴设备和其它类似的计算装置。本文所示的部件、它们的连接和关系、以及它们的功能仅仅作为示例,并且不意在限制本文中描述的和/或者要求的本公开的实现。
[0097]
如图6所示,设备600包括计算单元601,其可以根据存储在只读存储器(rom)602中的计算机程序或者从存储单元608加载到随机访问存储器(ram)603中的计算机程序,来执行各种适当的动作和处理。在ram603中,还可存储设备600操作所需的各种程序和数据。计
算单元601、rom602以及ram 603通过总线604彼此相连。输入/输出(i/o)接口605也连接至总线604。
[0098]
设备600中的多个部件连接至i/o接口605,包括:输入单元606,例如键盘、鼠标等;输出单元607,例如各种类型的显示器、扬声器等;存储单元608,例如磁盘、光盘等;以及通信单元609,例如网卡、调制解调器、无线通信收发机等。通信单元609允许设备600通过诸如因特网的计算机网络和/或各种电信网络与其他设备交换信息/数据。
[0099]
计算单元601可以是各种具有处理和计算能力的通用和/或专用处理组件。计算单元601的一些示例包括但不限于中央处理单元(cpu)、图形处理单元(gpu)、各种专用的人工智能(ai)计算芯片、各种运行机器学习模型算法的计算单元、数字信号处理器(dsp)、以及任何适当的处理器、控制器、微控制器等。计算单元601执行上文所描述的各个方法和处理,例如分析微服务架构下函数调用关系的方法。例如,在一些实施例中,分析微服务架构下函数调用关系的方法可被实现为计算机软件程序,其被有形地包含于机器可读介质,例如存储单元608。在一些实施例中,计算机程序的部分或者全部可以经由rom 602和/或通信单元609而被载入和/或安装到设备600上。当计算机程序加载到ram 603并由计算单元601执行时,可以执行上文描述的分析微服务架构下函数调用关系的方法的一个或多个步骤。备选地,在其他实施例中,计算单元601可以通过其他任何适当的方式(例如,借助于固件)而被配置为执行分析微服务架构下函数调用关系的方法。
[0100]
本文中以上描述的系统和技术的各种实施方式可以在数字电子电路系统、集成电路系统、场可编程门阵列(fpga)、专用集成电路(asic)、专用标准产品(assp)、芯片上系统的系统(soc)、负载可编程逻辑设备(cpld)、计算机硬件、固件、软件、和/或它们的组合中实现。这些各种实施方式可以包括:实施在一个或者多个计算机程序中,该一个或者多个计算机程序可在包括至少一个可编程处理器的可编程系统上执行和/或解释,该可编程处理器可以是专用或者通用可编程处理器,可以从存储系统、至少一个输入装置、和至少一个输出装置接收数据和指令,并且将数据和指令传输至该存储系统、该至少一个输入装置、和该至少一个输出装置。
[0101]
用于实施本公开的方法的程序代码可以采用一个或多个编程语言的任何组合来编写。这些程序代码可以提供给通用计算机、专用计算机或其他可编程数据处理装置的处理器或控制器,使得程序代码当由处理器或控制器执行时使流程图和/或框图中所规定的功能/操作被实施。程序代码可以完全在机器上执行、部分地在机器上执行,作为独立软件包部分地在机器上执行且部分地在远程机器上执行或完全在远程机器或服务器上执行。
[0102]
在本公开的上下文中,机器可读介质可以是有形的介质,其可以包含或存储以供指令执行系统、装置或设备使用或与指令执行系统、装置或设备结合地使用的程序。机器可读介质可以是机器可读信号介质或机器可读储存介质。机器可读介质可以包括但不限于电子的、磁性的、光学的、电磁的、红外的、或半导体系统、装置或设备,或者上述内容的任何合适组合。机器可读存储介质的更具体示例会包括基于一个或多个线的电气连接、便携式计算机盘、硬盘、随机存取存储器(ram)、只读存储器(rom)、可擦除可编程只读存储器(eprom或快闪存储器)、光纤、便捷式紧凑盘只读存储器(cd-rom)、光学储存设备、磁储存设备、或上述内容的任何合适组合。
[0103]
为了提供与用户的交互,可以在计算机上实施此处描述的系统和技术,该计算机
具有:用于向用户显示信息的显示装置(例如,crt(阴极射线管)或者lcd(液晶显示器)监视器);以及键盘和指向装置(例如,鼠标或者轨迹球),用户可以通过该键盘和该指向装置来将输入提供给计算机。其它种类的装置还可以用于提供与用户的交互;例如,提供给用户的反馈可以是任何形式的传感反馈(例如,视觉反馈、听觉反馈、或者触觉反馈);并且可以用任何形式(包括声输入、语音输入或者、触觉输入)来接收来自用户的输入。
[0104]
可以将此处描述的系统和技术实施在包括后台部件的计算系统(例如,作为数据服务器)、或者包括中间件部件的计算系统(例如,应用服务器)、或者包括前端部件的计算系统(例如,具有图形用户界面或者网络浏览器的用户计算机,用户可以通过该图形用户界面或者该网络浏览器来与此处描述的系统和技术的实施方式交互)、或者包括这种后台部件、中间件部件、或者前端部件的任何组合的计算系统中。可以通过任何形式或者介质的数字数据通信(例如,通信网络)来将系统的部件相互连接。通信网络的示例包括:局域网(lan)、广域网(wan)和互联网。
[0105]
计算机系统可以包括客户端和服务器。客户端和服务器一般远离彼此并且通常通过通信网络进行交互。通过在相应的计算机上运行并且彼此具有客户端-服务器关系的计算机程序来产生客户端和服务器的关系。服务器可以是云服务器,也可以为分布式系统的服务器,或者是结合了区块链的服务器。
[0106]
应该理解,可以使用上面所示的各种形式的流程,重新排序、增加或删除步骤。例如,本发公开中记载的各步骤可以并行地执行也可以顺序地执行也可以不同的次序执行,只要能够实现本公开公开的技术方案所期望的结果,本文在此不进行限制。
[0107]
上述具体实施方式,并不构成对本公开保护范围的限制。本领域技术人员应该明白的是,根据设计要求和其他因素,可以进行各种修改、组合、子组合和替代。任何在本公开的精神和原则之内所作的修改、等同替换和改进等,均应包含在本公开保护范围之内。
再多了解一些

本文用于创业者技术爱好者查询,仅供学习研究,如用于商业用途,请联系技术所有人。

发表评论 共有条评论
用户名: 密码:
验证码: 匿名发表

相关文献