用通俗的语言讲解RPC原理(万字长文)

丰富的线上&线下活动,深入探索云世界

做任务,得社区积分和周边

最真实的开发者用云体验

让每位学生受益于普惠算力

让创作激发创新

资深技术专家手把手带教

遇见技术追梦人

技术交流,直击现场

海量开发者使用工具、手册,免费下载

极速、全面、稳定、安全的开源镜像

开发手册、白皮书、案例集等实战精华

为开发者定制的Chrome浏览器插件

RPC(RemoteProcedureCall)即远程过程调用,我简单解释下字面的意思,远程肯定是指要跨机器而不是本机,所以需要用网络编程才能实现,但是不是说只通过网络通信访问到另外的一台主机的应用程序,就可以称为RPC调用了,显然还远远不够。

我的理解的RPC是帮助我们屏蔽网络编程的细节,实现调用远程方法就跟调用本地(同一个项目中的方法)是一样的,不需要因为这个方法是远程调用就需要编写很多业务无关的代码。

这就好比在修在小河的桥一样,它连着河的两岸,如果没有桥了,你只能通过划船,绕道等方式才能到达河对面。现在是有桥的,这跟路上走到河对面有啥区别呢?没得区别。所以总结我认为,RPC的作用就是两个方面:

屏蔽远程调用和本地调用的区别,让我们感觉调项目内的方法一样的

隐藏底层网络的复杂性,让我们更专注于业务逻辑

我们从定义提炼三个关键词

简单高效通用

但是想想互联网应用的量级越来越大,单台计算机的能力有限,那么需要借助可扩展的集群来完成,具体看下如何RPC在不同机器之间的完成调用。

咱们就开始了

典型的RPC架构可划成三部分:

1)服务提供者(RPCServer):运行在服务端,提供服务接口定义和服务实现类。

2)服务消费者(RPCClient):运行在客户端的,通过远程代理对象调用远程服务。

3)注册中心(Registry):也是运行在服务端,负责把本地服务发布成远程的服务,它也要去管理,提供给服务消费者来使用的。

通过上面的图可以看出,一次简单的RPC调用可以分为以下几个步骤:

(1)服务提供者启动后主动向注册中心注册机器ip、端口以及提供的服务列表;

(2)服务消费者在启动时到注册中心获取服务提供方地址列表,在本地缓存一份;

(3)服务消费者通过本地调用的方式调用服务,调用模块收到请求后通过负载均衡策略选取合适的远程服务地址;

(4)协议模块负责把方法、入参等信息进行序列化(编码)成能够进行网络传输的消息体,并将消息通过网络发送给服务端;

(5)服务端收到消息后进行解码(反序列化操作)。

(7)服务端将处理返回的结果进行序列化(编码),并将结果通过网络发送至服务消费者;

(8)服务消费者收到消息后进行解码最终得到结果;

敲黑板:在不同的RPC框架实现中步骤1、2、3的顺序可能有些不同。

RPC调用分以下两种:

同步调用客户方等待调用执行完成并返回结果。异步调用客户方调用后不用等待执行结果返回,但依然可以通过回调通知等方式获取返回结果。若客户方不关心调用返回结果,则变成单向异步调用,单向调用不用返回结果。异步和同步的区分在于是否等待服务端执行完成并返回结果。

RPC结构拆解如下图所示。

RPC组件职责上面我们进一步拆解了RPC实现结构的各个组件组成部分,下面我们详细说明下每个组件的职责划分。

RPC服务方通过RpcServer去导出(export)远程接口方法,而客户方通过RpcClient去引入(import)远程接口方法。客户方像调用本地方法一样去调用远程接口方法,RPC框架提供接口的代理实现,实际的调用将委托给代理RpcProxy。代理封装调用信息并将调用转交给RpcInvoker去实际执行。在客户端的RpcInvoker通过连接器RpcConnector去维持与服务端的通道RpcChannel,并使用RpcProtocol执行协议编码(encode)并将编码后的请求消息通过通道发送给服务方。

RPC服务端接收器RpcAcceptor接收客户端的调用请求,同样使用RpcProtocol执行协议解码(decode)。解码后的调用信息传递给RpcProcessor去控制处理调用过程,最后再委托调用给RpcInvoker去实际执行并返回调用结果。

一个完整的商用RPC框架有很多功能,最最核心的基本功能就是三个:服务寻址、数据编解码、网络传输。

如果是本地调用,被调用的方法在同一个进程内,操作系统或者是虚拟机可以去地址空间去找;但是在远程调用中,这是行不通的,因为两个进程的地址空间是完全不一样的,肯定也无法知道远端的进程在那。

如果要想实现远程调用,我们需要对服务消费者和服务提供者两者进行约束:

在远程过程调用中所有的函数都必须有一个ID,这个ID在整套系统中是唯一存在确定的。

服务消费者在做远程过程调用时,发送的消息体中必须要携带这个ID。

服务消费者和服务提供者分别维护一个函数和ID的对应表。

当服务消费者需要进行远程调用时,它就查一下这个表,找出对应的ID,然后把它传给服务端,服务端也通过查表,来确定客户端需要调用的函数,然后执行相应函数的代码就行。

上面说的可能比较抽象,通俗一点就是服务消费者如何寻找服务提供者,这就是服务寻址。

图片

服务寻址的实现方式有很多种,常见的是:服务注册中心。要调用服务,首先你需要一个服务注册中心去查询对方服务都有哪些实例,然后根据负载均衡策略择优选一。

像Dubbo框架的服务注册中心是可以配置的,官方推荐使用Zookeeper。

我私下用的nacos也行。

对计算机网络稍微有一点熟悉的同学都知道,数据在网络中传输都是二进制的:01010101010101010,类似这种,只有二进制数据才能在网络间传。

那一个客户端调用远程服务的一个方法,像方法入参这些必然需要转换成二进制才能进行传输,这种将对象转换成二进制流的过程就叫做序列化(编码),学过JavaIO流那部分你应该熟悉。

服务端接收到二进制流不能识别,势必要将二进制流转换成对象,这个逆过程就叫做反序列化,也可以叫解码。

常见的RPC序列化协议

XML(ExtensibleMarkupLanguage)是一种常用的序列化和反序列化协议,具有跨机器,跨语言等优点。狭义webservice就是基于SOAP消息传递协议(一个基于XML的可扩展消息信封格式)来进行数据交换的。

Hessian是一个动态类型,简洁的,可以移植到各个语言的二进制序列化对象协议。采用简单的结构化标记、采用定长的字节记录值、采用引用取代重复遇到的对象。

JSON(JavascriptObjectNotation)起源于弱类型语言Javascript,是采用"Attribute-value"的方式来描述对象协议。与XML相比,其协议比较简单,解析速度比较快。

ProtocolBuffers是google提供的一个开源序列化框架,是一种轻便高效的结构化数据存储格式,可以用于结构化数据串行化,或者说序列化。它很适合做数据存储或RPC数据交换格式。可用于通讯协议、数据存储等领域的语言无关、平台无关、可扩展的序列化结构数据格式。同XML相比,Protobuf的主要优点在于性能高。它以高效的二进制方式存储,比XML小3到10倍,快20到100倍。

Thrift既是rpc框架,同时也具有自己内部定义的传输协议规范(TProtocol)和传输数据标准(TTransports),通过IDL脚本对传输数据的数据结构(struct)和传输数据的业务逻辑(service)根据不同的运行环境快速的构建相应的代码,并且通过自己内部的序列化机制对传输的数据进行简化和压缩提高高并发、大型系统中数据交互的成本。

提起网络传输大家脑海里肯定马上就能想到TCP/IP四层模型、OSI七层模型,那通常RPC会选择那一层作为传输协议呢?

在回答这个问题前

先来看下RPC需要网络传输实现什么样的功能。

客户端的数据经过序列化+编码后,就需要通过网络传输到服务端。网络传输层需要把前面说的函数ID和序列化后的参数字节流传给服务端,服务端处理完然后再把序列化后的调用结果传回客户端。

原则上只要能实现上面这个功能的都可以作为传输层来使用,具体协议没有限制。

我们先来看下TCP协议,TCP连接可以是按需连接,需要调用的时候就先建立连接,调用结束后就立马断掉,也可以是长连接,客户端和服务器建立起连接之后保持长期持有,不管此时有无数据包的发送,可以配合心跳检测机制定期检测建立的连接是否存活有效。

由此可见TCP的性能确实很好,因此市面上大部分RPC框架都使用TCP协议,但也有少部分框架使用其他协议,比如gRPC用的是HTTP2来实现。

敲黑板:

数据编解码和网络传输可以有多种组合方式,比如常见的有:HTTP+JSON,Dubbo协议+TCP等。

最近刚升为apache顶级项目的dubbo可以说是java语言中RPC架构最流行的框架。同时Dubbo的文档也是开源软件中写的最详细的文档之一,细看dubbo官方文档。下图是dubbo的整体设计:

上面的dubbo展示了一个完整的带服务治理功能的RPC框架的分层架构。下面我们写一个简易的RPC框架,我把dubbo中的一些非核心层省略掉。具体细节见demo。

省略掉config层,直接通过单例模式获取服务。保留proxy服务代理层,客户端采用简单的反射机制实现服务接口的动态代理,demo中对应ServiceProxyClient类;服务端初始化的时候,按一定规则写进Map映射中,这样直接获取服务实例对象即可,类似RMI的skeleton模块,demo中对应ServiceProcessor类。省略registry注册中心层,demo服务只有一个实例机器提供,故直接写死ip和端口,在ClientRemoter类中getDataRemote方法中直接写死。省略cluster路由层,只有当服务实例有多个时才需要通过算法决定哪个服务实例“接待”请求。省略monitor监控层,这个是服务治理需要的,不影响核心流程调用。保留protocol远程调用层以下四层,统称为remote层。负责请求双方调用协议的约定,序列化、传输。client端的remote层对应demo中ClientRemoter类,将请求服务接口转化成二进制通过socket发送给服务端;服务端的remote层对应demo中的ServerRemoter类,负责客户端的二进制按照协议转化成本地的方法调用,然后又将返回结果通过按照协议翻译成二进制通过socket送给客户端。

敲黑板:首先强调一下轮子的目的不是为了放在生产上面去用,肯定会有很多缺陷是不得行,而是造轮子以实战经验来促进你高效来学习,让你掌握零散的知识点连成一条线。

这次我会深入研究带大家从零开始撸一个RPC框架,如果在编写过程中如果呈现问题,欢迎小伙伴们到github(id:Datalong)提交你的issue,会及时修正。

[过程]这个词估计你学C的时候听说过,也不知道最开始谁翻译的,个人觉得程序,服务,方法,这几个都比[过程]要好。

为了后面能够好理解,我们统一一下术语,干脆叫,远程服务调用,服务包括是指程序接口,方法等一类资源。

RPC是一种进程间通信的模式,程序分布在不同的地址空间里。如果在同一主机里,RPC可以通过不同的虚拟地址空间(即便使用相同的物理地址)进行通讯,而在不同的主机间,则通过不同的物理地址进行交互。许多技术(通常是不兼容)都是基于这种概念而实现的。

听懂了些,好像又没完全懂,那说人话吧。比如说两台服务器:A和B,一个应用部署在A服务器上,想要调用B服务器上某个应用提供的函数/方法。

由于跨应用服务器,你不能直接调用,需要通过网络来表达调用的语意和传达调用的数据,这种调用的方式就是RPC,如下图所示。

RPC服务方通过RpcServer去导出远程接口方法,而客户端通过RpcClient去引入远程接口方法。那客户端像调用本地方法一样去调用远程接口方法,RPC框架提供接口的代理实现,实际的调用将委托给代理RpcProxy。代理封装调用信息并将调用转交给RpcInvoker去实际执行。在客户端的RpcInvoker通过连接器RpcConnector去维持与服务端的通道RpcChannel,并使用RpcProtocol执行协议编码(encode)并将编码后的请求消息通过通道发送给服务方。

既然存在RPC这种远程过程调用,必然会有与之对应的本地过程调用了。本地过程调用在不同的操作系统中,叫法不同,使用方式也不太一样。在Windows编程中,称为LPC;在linux编程中,更习惯称之为IPC,即进程间通信,这不就绕回来了。

但是,不管如何,其本质上就是本地机器上的不同进程之间通信协作的调用方式。

RPC家族中,RMI是Java制定的远程通信协议。而后,基本上RPC框架都或多或少有RMI的影子(当然,其实主要是RPC本身的实现方式就是这样子的)。RMI既然是Java的标准RPC组件,那必然其他编程语言就无法使用了但是,作为服务化的组件,如果没有服务治理来完成大规模应用集群中服务调用管理工作,则运维工作则是非常繁重的,因此类似dubbo这种包含服务治理的RPC组件出现。

也就是RPC本身的实现方式。在JDK1.2的时候,引入到Java体系的。当应用比较小,性能要求不高的情况下,使用RMI还是挺方便快捷的。下面先看看RMI的调用流程。

目前大规模使用的RPC框架有:

作为Java自带的官方RPC组件,单独介绍;然后我们来看看通用RPC实现结构。

全称是RemoteMethodInvocation,也就是远程方法调用。在JDK1.2的时候,引入到Java体系的。当应用比较小,性能要求不高的情况下,使用RMI还是比较快捷的。

从零开始,手写一个RPC,跟随这篇前提知识做铺垫以及数个迭代版本的代码,由简陋到逐渐完备,目的让所有人都能看懂并且写出一个RPC框架。

本文档与代码都是本人第一次手写RPC的心路历程,会有理解的偏差与代码上的不完善,但更是由于这样,有着与新手对同样问题的疑惑,也许会使新手更容易理解这样做的缘故是啥。

另外期待与你的合作:代码,帮助文档甚至rpc框架功能的完备

一定要实际上手敲代码

每一版本都有着对应独立的代码与文档,结合来看

每一个版本都有着要解决的问题与此版本的最大痛点,带着问题去写代码,并且与上个版本的代码进行比较差异

如果你认真去学下去,可以掌握下面的技术:

basic

hard

还有就是底层的网络是基于netty,学完后netty入门没有问题;

有没有一点心动呢?!

上面简单解答了为啥咱们要学rpc轮子,那铁子们就问为什么需要RPC?一项新技术肯定是为了改善技术工具或者重新设计解决具体的业务及架构方面的问题。

不得不说单体架构,这种就是把应用程序的所有功能都打成一个部署包。从上面的架构图总结一下单体架构的特点:

如果网站流量很小时,只需一个应用,把所有功能部署在一起,来减少部署结点和运维成本。如果流量稍微大一点可以通过部署应用集群和数据库集群来提高系统的性能。

这种肯定逐渐淘汰,业务逐渐复杂,应用的外部流量压力骤增,团队成员会越来越多,这时的抗压能力会逐渐暴露。

具体聊下不足

缺点一:高耦合

某个模块出现死循环,导致内存溢出,上下应用都会挂掉。

缺点二:扩展性很差

系统的扩容只能针对应用进行扩容,不能做到对某个功能模块进行扩容,扩容后必然带来资源浪费的问题

缺点三:持续交付周期拉长

网站应用的规模不断扩大,传统的垂直应用架构早已经没法满足了,分布式服务架构以及流动计算架构也在行业应用很广泛,但是在这背景就需要个治理系统确保架构有条不紊的继续演进。

当网站流量很小,它只需一个应用,将所有功能如下单,支付等都部署在一起,减少了部署节点和成本。

垂直应用架构解决了单一应用架构所面临的扩容问题,流量能够分散到各个子系统当中,且系统的体积可控,一定程度上降低了开发人员之间协同以及维护的成本,提升了开发效率。

当垂直应用越来越多,应用之间交互不可避免,将核心业务抽取出来,作为独立的服务,逐渐形成稳定的服务中心

它也叫服务治理结构,随着服务化的进一步发展,服务越来越多,服务之间的调用和依赖关系也越来越复杂,诞生了面向服务的架构体系(SOA),也因此衍生出了一系列相应的技术,如对服务提供、服务调用、连接处理、通信协议、序列化方式、服务发现、服务路由、日志输出等行为进行封装的服务框架

在RPC框架中主要有三个角色:Provider、Consumer和Registry。如下图所示:节点角色说明:

此RPC的最大痛点:只能调用服务端Service唯一确定的方法,如果有两个方法需要调用呢(Reuest需要抽象)返回值只支持User对象,如果需要传一个字符串或者一个Dog,String对象呢(Response需要抽象)客户端不够通用,host,port,与调用的方法都特定(需要抽象)

是通过在客户端和服务器之间建立TCP连接,远程过程调用的所有交换的数据都在这个连接里传输。连接可以是按需连接的,调用结束后就断掉了呗,也可以是长连接,多个远程过程调用共享同一个连接。

A服务器上的应用怎么告诉底层的RPC框架,如何连接到B服务器(如主机或IP地址)以及特定的端口,方法的名称名称是什么,这样才能完成调用。比如基于Web服务协议栈的RPC,就要提供一个endpointURI,或者是从UDDI服务上查找。如果是RMI调用的话,还需要一个RMIRegistry来注册服务的地址。

当A服务器上的应用发起远程过程调用时,方法的参数需要通过底层的网络协议如TCP传递到B服务器,由于网络协议是基于二进制的,内存中的参数的值要序列化成二进制的形式,也就是序列化(Serialize)或编组(marshal),通过寻址和传输将序列化的二进制发送给B服务器。同理,B服务器接收参数要将参数反序列化。B服务器应用调用自己的方法处理后返回的结果也要序列化给A服务器,A服务器接收也要经过反序列化的过程。

THE END
1.12个学习网站,不看绝对后悔招财锦鲤附体 在得物App发布了一条热门动态!快来围观,就等你啦!https://m.dewu.com/note/trend/details?id=258086093
2.ASP.NETCore适用于.NET的开源Web框架使用Microsoft Azure 可免费获取 10 个 ASP.NET Core 网站。 还可以部署到任何主要云平台、自己的 Linux 或 Windows 服务器,或多个托管提供程序其中之一。 使用Microsoft Azure 免费托管 你可能还对这些免费电子书感兴趣 Blazor e-book 这本免费电子书向 ASP.NET Web Forms开发人员介绍了 Blazor。它与 ASP.NET https://asp.net/
3.学习中用到的一些网站无心流泪学习中用到的一些网站 http://tortoisesvn.net/downloads.html SVN客户端的下载网站 http://subclipse.tigris.org/servlets/ProjectProcess?pageID=p4wYuA 用于获取eclipse中SVN插件的地址https://www.cnblogs.com/wuxinliulei/p/3973075.html
4.搜索技巧所以今天小编想给大家安利一些?基础但好用的搜索小技巧(老司机就不用看了),帮助大家提高使用搜索引擎的效率。 怎么搜到你想要的学习资源|电子书&教材&课程资源查找|学就完事儿了 既然要终身学习,怎么能连资料都不会找?先给大家说一下我最常用也是最广泛的搜索学习资源的途径。 我的搜索能力曾经强到搜出了http://www.sowang.com/seek.htm
5.网络安全教育主题班会心得体会范文(通用14篇)你的个人电脑会不会被攻击?你注册的会员网站会不会泄露你的信息呢?等等!所有这些,都可视为网络信息安全的一部分。 经过学习我才更加的认识到网络安全的重要性,因为我们每个人都基本在使用电脑,个人电脑有没有被攻击,病毒侵害呢?每个人的个人电脑都会存储好多个人信息和重要文本文件,那么我们为了保障这些文本信息的https://m.ruiwen.com/xindetihui/4401432.html
6.关于剧情涉及到的一些心理学相关背景:解离性障碍和心理创伤症候群(关于剧情涉及到的心理学知识背景,阅读感可能长且枯燥,且有很多很多剧透,慎入!)这个剧是一个关于解离性障碍患者的患病感受,体验,其病因等和心理创伤相关的心理悬疑剧(偏解析,非惊悚)。它不是表现破案推理调查技术类型的悬疑剧,不是穿越剧,不是平行世界科幻剧,更不是职场剧。全剧用视听语言解析呈现女主林晨曦因心理https://movie.douban.com/review/14733238/
7.商战数据挖掘:你需要了解的数据科学与分析思维这是数据科学最重要的基本原则之一,本书将用整整两章(第 7 章和第 11 章)来讨论。我们究竟想做什么?如何做?应用场景的哪些部分可能包含数据挖掘模型?在详细讨论上述问题时,本书会先采用一个简化的应用场景。但随着学习的深入,本书会折回来,根据实际业务需求不断调整应用场景。本书还会介绍一些概念性工具来辅助https://www.ituring.com.cn/book/tupubarticle/28952
8.一些自己用到的学习网站经常会用到的学习资料有哪些一些自己用到的学习网站 http://www.w3school.com.cn/https://blog.csdn.net/dennycking/article/details/62897831
9.第四届科研论文获奖论文集内容如在八上第四单元第二课《A Brave Dog》中,我对短文教学主要采用分段学习的方法,第一段我采用了听课文来回答简单问题的方式让每一位学生练习听力,同时对文章内容有初步的了解,第二段比较长,我采用听短文填空的方式来训练听力,主要照顾部分学习上困难的学生,然后,我又让学生看着问题和答案以及填空的内容,两人一组https://school.bsedu.org.cn/ypsyxx/app/info/doc/index.php/2888
10.强化学习详细解读DQN(更新完成)51CTO博客深度学习的成功让直接从原始数据中提取特征成为可能,所以DQN尝试进行DL+RL。 强化学习中应用深度学习有以下一些挑战: ① 深度学习(监督学习)需要大量的有标签的训练数据,应用到强化学习中去时,只能使用Reward来作为标签,但是reward通常来说是稀疏的、带有噪音并且是延时性的信号(通常是进行很多episode之后才给出reward)https://blog.51cto.com/u_15302822/5946222
11.太棒了!学习Python的21个常用资源网站,get了从小白到入门再到大神Python作为现在很热门的一门编程语言,要想学好它,除了掌握好的学习方法还得有一些学习资料和书籍作为补充,为了帮助大家更好的学习Python,我为大家搜寻了一些学习python的常用资源,通过分析、整理,为不同阶段的Python学习者都进行了概括,希望对大家有用。 https://www.jianshu.com/p/fc9aa49a453c
12.手残党也能成为艺术家!4个热门AI绘画平台的创作经验总结这里放一些大佬用这个工具创作的优秀作品,太好看了。 下面分享下快速使用的教程 1. 用 Google 浏览器,打开 Midjourney 官网,加入演示版 2. 进入到 discord,随便选择一个新加入用户的分组。你应该能看到很多人在群组里不断生成新的 AI 图片,此时你其实已经可以在这里开始你自己的 AI 作画了。 https://www.uisdc.com/4-ai-draw-platform
13.动效教程!充满科技感的飞线图动效,设计加代码一起教给你!这次还是和设计教程一样,我打算只绘制3根线条。学会了制作一根的方法,你就可以无限复制,活学活用了。 步骤二:尝试学习一下原理(但是没学会) 用代码绘制这种贝塞尔曲线看起来很难,它的基础知识你可以看看维基百科。 在维基百科里面,都是这种复杂的数学公式,打开这个页面看了不到3秒钟我就差点晕倒了。咱们设计师必须https://uiiiuiii.com/other/1212414982.html
14.超星尔雅《信息素养:效率提升与终身学习的新引擎》最新章节测验5【判断题】大学里学到的东西,工作后很多用不上,而工作中用到的很多东西,大学里并没有学。这说明大学教育没有必要。错 6【判断题】终身学习能力的培养是大学教育的重要培养目标之一。对 案例:5?=( )R 1【判断题】信息素养指的是基于信息解决问题的综合能力和基本素质。()是 https://www.zhi12.cn/content/95560938
15.面试常见问题在学习和工作中,我们很多时候都不得不用到试题,借助试题可以更好地考查参试者所掌握的知识和技能。你知道什么样的试题才是规范的吗?以下是小编为大家收集的面试常见问题,仅供参考,大家一起来看看吧。 面试常见问题1 一、问:“如果我录用你,你认为你在这份工作上会待多久呢?”(分析:考官是想了解应聘者是否属于稳https://www.yjbys.com/qiuzhizhinan/show-596114.html
16.实习期工作总结(精选17篇)始终把学习作为获得新知、掌握方法、提高能力、解决问题的一条重要途径和方法,切实做到用理论武装头脑、指导实践、推动工作。思想上积极进取,积极的把自己现有的知识用于社会实践中,在实践中也才能检验知识的有用性。所以在这一个月的实习工作中给我最大的感触就是我们在学校学到了很多的理论知识,但很少用于社会实践中https://www.oh100.com/a/202305/6766182.html
17.教师数字素养心得体会(通用37篇)学习的意义和重要性在于学习过程本身学习的意义和学习除了能掌握相关理论知识外,更重要的是我们在学习过程中我们的思考和得到的启示。 理论验证性实验的内容中应设置问题让学生思考。鼓励学生通过重新编写MATLAB程序验证个人答案。对于设计性实验,课程讲完之后要求学生根据课堂内容,编写相应的设计程序,当然对于用到的主要https://mip.jy135.com/xindetihui/1166479.html
18.国培计划信息技术2.0培训心得体会范文(精选15篇)通过学习,我们发现,他们课前准备充分,课上善于运用新媒体技术,使用一些让学生感兴趣的内容来教学,这样就会收到意想不到的教学效果。在以后的'教学中,我们一定好好学习并运用这些教学方法,使我们的课堂更富有魅力。 四、明确了未来努力的方向。 我们积极学习新的教育教学理念,用以指导实际的教学工作,向新课改的目标https://www.fwsir.com/xinde/html/xinde_20220923090014_1989708.html
19.自我成长分析报告范文(精选10篇)一切生活的重担及教育子女的责任全部落到了母亲的肩上,面对着繁重的工作和生活的双重压力,母亲始终保持着乐观的态度,用她高度的责任感以及刚毅、勤劳、宽容、豁达的品质影响着我们姐弟五人,并且对我们提出很严格的要求:言行要一致、学习要优秀。这样的家庭教育的熏陶和家庭环境的影响,培养了我乐观、刚毅的品质和追求https://www.yuwenmi.com/fanwen/baogao/346373.html
20.头条文章可以学习一些中国特色的表达,看看如何用英语描述中国社会经济等问题。 12. 金融时报中文网 2018年5月CATTI真题出题方向,考的是外刊回译。 更多可以看: 看CATTI题源,推荐28个CATTI备考网站(必须收藏) 09 CATTI实务 英译汉备考练习网站 一般取自纽约时报、卫报、经济学人等外刊,所以需要看这些资料。 https://m.weibo.cn/ttarticle/p/show?id=2309634722060495815195
21.硬件知识:DP接口和HDMI接口对比,看完你就懂了!大家好,又见面了,我是你们的朋友全栈君。 电脑显示器高清传输通过会用到两个接口,就是DP接口和HDMI接口,今天电脑学习小编带大家对比一下这两个接口。 一、DP接口 DisplayPort缩写DP,是一个由PC及芯片制造商联盟开发,视频电子标准协会(VESA)标准化的数字式视频接口标准。该接口免认证免授权,主要用于视频源与显示器https://cloud.tencent.com/developer/article/2108607