为了账号安全,请及时绑定邮箱和手机立即绑定
3.1 微信小程序 API

uni-app 的 API 与微信小程序 API 基本一致。掌握微信小程序 API 对后面的开发很有帮助。微信小程序 API 文档:https://developers.weixin.qq.com/miniprogram/dev/api/

3.1 打包为微信小程序

注册微信小程序账号,获取到 AppID,我们后面配置的时候会用到。在 HBuilderX 工具栏,点击发行,选择小程序-微信。输入小程序名称和 AppID,单击发行就可以了。这样我们就会获得一个微信小程序的打包文件,接下来我们来发布微信小程序项目,打开微信小程序开发者工具,导入刚刚生成的微信小程序项目的打包文件,在微信小程序开发者工具中先测试一下,项目运行是否正常,项目测试没有问题后,点击右上角>>按钮,上传代码就可以发布微信小程序了,最后等待微信团队审核通过,别人就可以在线上访问到你的项目了。

2.1 微框架

Flask 是一个 Python 实现的 Web 开发微框架,但是这个“微”并不代表着 Flask 功能比较简陋、有所欠缺。微框架中的 “微” 意味着:Flask 旨在保持核心简单而易于扩展;Flask 不会替用户做出太多决策,比如使用何种数据库;Flask 的选项(比如使用何种模板引擎) 通常有多个,用户很容易替换。默认情况下,Flask 不包含数据库抽象层、模板引擎、身份认证或其它任何已有多种库可以胜任的功能,如下图所示。然而,Flask 支持用扩展来给应用添加这些功能,应用程序可以很方便的集成这些扩展。众多的扩展提供了数据库集成、表单验证、上传处理、各种各样的开放认证技术等功能。

2.1 微前端

微前端 尚处在发展时期,其核心概念和 微服务 相似。现阶段较为常用的微前端框架为 single-spa 和 qiankun,后者是基于前者实现的。该技术能做到 技术栈无关,即一个应用,能由多个不同技术的子应用构成,同时做到子应用的相互隔离,这里的隔离就可以选择采用 Web Components 实现。

2. 代理配置

go mod 虽然可以直接帮我们下载好我们需要的包,但是因为 Go 语言很多包都是在国外的服务器上,国内下载具有一定的困难。但是不用担心,go mod 提供了代理服务,同时很多国内的云服务器产商都提供了自己的代理服务:阿里云: https://mirrors.aliyun.com/goproxy 微软: https://goproxy.io 七牛云: https://goproxy.cn GoCenter: https://gocenter.io

3. 国际化

国际化的功能离不开错误码的支持,客户端指定语言到服务端去请求,当出错了服务端会根据错误码和语言找到对应的国际化提示语。从上面图中我们发现,错误码不仅仅是客户端与服务端的交互,后台各个服务间的交互也需要约定的一套错误码。一般一个系统的错误码 code 都是唯一确定的。msg 不同场景下可能不一样,提供给用户的肯定是需要友好且不能暴露底层细节,给开发人员看的就要详细专业的错误内容。网关服务上面维护着多套不同语言的错误码提示语,响应的时候会根据客户端带的 Lang 信息进行国际化转译。模块模块编码错误编码底层描述中文提示语英文提示语库存10001商品规格表关联有误商品不存在goods don’t exist一般国际化的系统中会有多份 xxx_lang.properties文件,每一份代表一种语言的消息提示语。中文一般会转为 Unicode 编码进行存储(这个过程一般开发工具可以设置自动转),这样的处理可以规避不同开发环境下不同编码导致中文乱码。

新浪微博

咱们打开新浪微博,然后随便找个带皇冠的,按下F12键(Mac用户按command+option+i)然后选中控制台的箭头,再点击皇冠:再点开这个图片可以发现:可以看到那些大 V 图标皇冠图标以及各种微博认证等图标,都是放在了一张雪碧图里(即使再牛的大 V,身份标志也是放在雪碧图中的)。

2. 国际化

上述例子发现输出的结果是英文的,显然是不适合在国内环境使用,moment.js 提供了国际化支持,在现有的库中,moment 支持的语言可以说是相对完备了。通过引入对应的国际化资源(语言文件),来切换语言。<script src="https://cdn.bootcdn.net/ajax/libs/moment.js/2.27.0/moment.min.js"></script><script src="https://cdn.bootcdn.net/ajax/libs/moment.js/2.27.0/locale/zh-cn.min.js"></script><script> var now = moment().calendar(); console.log(now);// 输出当前日历时间 moment().startOf('hour').fromNow(); // 相对这个小时过去了多少分钟 var timestamp = 1593933593236; // 2020年7曰5日下午15点20分38秒 moment(timestamp).fromNow(); // 相对时间戳多久前</script>有关国际化的更多内容可以参考文档。

2.1 管理代码

试想一下,当我们在公司做某个项目,代码写到一半,回到家以后想用自己的电脑,继续写剩下的代码,那怎么办呢?当然你可以把代码拷贝下来,然后安装到自己的电脑上面,或者借助 QQ、微信、网盘等文件传送方式传送到你自己的电脑上(这里只是举例子,实际工作中一定要遵守公司规定,不要把公司重要代码随意上传或者打包带走)。这样做未免有些繁琐,因为你每次上传都需要传全部的代码,而有些项目的代码还有各种各样的依赖包,实际所占内存会很大,传送也浪费时间。通过 GitHub 我们就能完美解决这个问题,只需要将代码上传到 GitHub 仓库,回家后再拉去一下代码就好了。具体是什么原理,我们后面会讲到。

3.1 关于微服务监控平台

技巧 1如果我们的微服务监控平台没有任何数据,或者说,在打开微服务平台之后,各参数一直处于 loading 状态,这个时候,我们只需要在服务端调用任意一个服务接口即可,这样在微服务监控平台,我们就能看到被监控实例的参数了。技巧 2如果我们在访问 /actuator/hystrix.stream 路径时,系统找不到对应的路径,即报 404 异常,那么我们需要在对应项目的启动类中添加一个 Bean :@Beanpublic ServletRegistrationBean hystrixMetricsStreamServlet() { ServletRegistrationBean registration = new ServletRegistrationBean(new HystrixMetricsStreamServlet()); registration.addUrlMappings("/hystrix.stream"); return registration;}这样我们就能正常访问 /actuator/hystrix.stream 下的路径了。

4.2 微信

1. 独立的页面维护了全局 错误码错误码由5位整数构成2. 每个接口一个独立的 参数说明页面正常情况下出参只返回业务实体异常情况才有 errCode errMsg每个接口下也可能有自己的业务错误码

4. 模板方法模式

模板方法模式是定义一个操作中的算法的骨架,从而将一些步骤延迟到子类中。模板方法使得子类可以不改变一个算法的结构即可重定义该算法的某些特定步骤。通常对于一些重要的复杂方法和多个子类共有的方法且逻辑相同的情况下会使用模板方法模式。比如用户第三方用户认证的时候就比较适合使用模板方法。我们来看一个例子:假设我们现在需要用到微信、微博的第三方用户授权来获取用户的信息。//使用模板方法模式描述获取第三方用户信息的过程 public abstract class Authentication{ public void checkUserAuthentication(){ checkIdentity(); fetchInfo(); } ​ protected abstract void checkIdentity(); protected abstract void fetchInfo(); } ​ //微信用户 public class WechatAuthenication extends Authentication{ @Override protected void checkIdentity() { System.out.println("获得微信用户授权"); } ​ @Override protected void fetchInfo() { System.out.println("获取微信用信息"); } } ​ //微信用户 public class WeiboAuthenication extends Authentication{ @Override protected void checkIdentity() { System.out.println("获得微博用户授权"); } ​ @Override protected void fetchInfo() { System.out.println("获取微博用信息"); } } ​ //调用模板方法 public class Demo{ public static void main(String...s){ Authentication auth = new WechatAuthenication(); auth.checkUserAuthentication(); auth = new WeiboAuthenication(); auth.checkUserAuthentication(); } }输出结果:获得微信用户授权 获取微信用信信息 获得微博用户授权 获取微博用信信息现在我们使用 Lambda 表达式换个角度来思考模板方法模式。如果我们用函数式接口来组织模板方法中的调用过程,相比使用继承来构建要显得灵活的多。//定义一个处理接口,用来处理一项事务,如授权或者获取信息。 public interface Processer{ public void process(); } ​ //封装调用过程 public class Authentication{ private final Processer identity; private final Processer userinfo; public Authentication(Criteria identity,Criteria userinfo){ this.identity = identity; this.userinfo = userinfo; } ​ public void checkUserAuthentication(){ identity.process(); userinfo.process(); } } ​ //使用模板方法 public class Demo{ Authentication auth = new Authentication(()->System.out.println("获得微信用户授权"), ()->System.out.println("获取微信用户信息")); auth.checkUserAuthentication(); auth = new Authentication(()->System.out.println("获得微博用户授权"), ()->System.out.println("获取微博用户信息")); auth.checkUserAuthentication(); }输出结果:获得微信用户授权 获取微信用信信息 获得微博用户授权 获取微博用信信息此时,我们的模板方法得到了大幅的简化,同时通过函数接口让模板方法获得了极大的灵活性。

1. 前言

在上一章中,我们对 Hystrix 中的所有的微服务治理特性都做了学习和了解,同时我也通过 demo 样例的形式,来对每一个特性都做了代码实现,可是这些代码并不是我们真实业务场景下的代码,只能用来学习特性所用。为了将我们所学习和了解到的微服务治理特性应用于真实项目中,于是规划了 4 节在实际业务场景下 Hystrix 微服务治理特性的应用内容,希望可以通过这 4 节的介绍,大家可以了解到如何在实际项目中去应用这些特性。在本节中,我将为大家介绍真实业务场景下,服务容错与降级的应用方法,及代码实现。本节主要内容:服务容错与降级真实业务场景描述;业务场景实现思路分析与实操。

微前端

single-spaqiankunmicro-appwujie

3.3 近于实时的补偿性

我们都知道,什么事情都不可能是十全十美的。抛开 RabbitMQ 不说,在互联网行业中的其他工具,也不能百分百保证每时每刻都在正常工作,更何况是涉及到消息通信的工具。RabbitMQ 在传递消息时,由于一些客观原因或者是其本身的原因,可能会出现,在有大批量消息传递时,所有的消息不能百分百传递到目的地的问题。RabbitMQ 在设计之初就考虑到了这个问题的出现,所以,RabbitMQ 提供了内置的消息补偿机制,这里我们简单做一下介绍。当存在大批量的消息都需要经过 RabbitMQ 来投递时,RabbitMQ 会将这些消息划分成若干组,然后通过为组设置顺序的方式,来依次投递这些消息。如果在任意一组中,出现了消息未能投递到目的地的现象,那么, RabbitMQ 会将该条消息进行短暂的存储,待其他消息都到达目的地后,RabbitMQ 会重新将该条消息进行投递,然而,这个过程执行的时间是微乎其微的,几乎近于实时。

3. CDN

可以通过 CDN 引入 ECharts 文件:<!-- bootstrap 服务 --><!-- bootstrap 提供的免费CDN服务,亲测非常稳定 --><script src="//cdn.bootcss.com/echarts/4.5.0/echarts.common.js"></script><!-- 七牛云存储服务 --><!-- 国内速度稳定,开放性强 --><script src="//cdn.staticfile.org/echarts/4.5.0/echarts.common.js"></script><!-- jsdeliver 服务 --><!-- 微软的CDN服务,虽然国内访问速度比不上国内CDN,但速度不至于太慢,有国际化需求的可以试试 --><script src="//cdn.jsdelivr.net/npm/echarts@4.5.0/echarts.common.js"></script><!-- cdnjs 服务 --><!-- 一个非常全的CDN服务,存储了大多数主流的js、css、图片库 --><script src="//cdnjs.cloudflare.com/ajax/libs/echarts/4.5.0/echarts.common.js"></script>

5.1 编辑代码

编辑 pages/index/index.vue 文件,在 data 中编辑。实例:data() { return { // #ifdef H5 text:"欢迎登录H5平台", // #endif // #ifdef MP-WEIXIN text:"欢迎登录微信小程序", // #endif isShow:true };},

2. 实际业务场景描述

业务场景描述有这样一个真实的业务场景:在某大厂某销售业务项目中,由于某大厂销售业务板块业务的持续增加,导致之前原本设计好的项目架构出现了问题,不足以支撑持续增长的业务需要,于是,某大厂程序员对项目架构做了拆分,并最终形成了以 Spring Cloud 为基础架构的微服务分布式项目架构。在拆分了项目架构之后,虽然可以支撑持续增长的业务需要,但是,在拆分后的项目架构中,Hystrix 无法对所有项目进行监控,即 Hystrix 服务监控平台只能监控一个分散的项目,无法对项目整体进行监控。问题原因分析在解决问题之前,我们首先来分析一下这种问题产生的原因。上述场景场景中,项目的架构方式是微服务的分布式架构,而一般来说的 Hystrix 微服务监控平台默认只对一个项目实例起作用,所以,也就导致了一个微服务平台只对一个微服务实例起作用。

3.3 <code>MutableList&lt;*&gt;</code> 实际上一个 out 协变投影

MutableList<*> 实际上是投影成 MutableList<out Any?> 类型:我们来分析下为什么会这样投影,我们知道 MutableList<*> 只包含某种特定类型的集合,可能是 String、Int 或者其他类型中的一种,可想而知对于该集合操作需要禁止写操作,不能往该集合中写入数据,无法确定该集合的特定类型,写操作很可能引入一个不匹配类型到集合中,这是一件很危险的事。但是反过来想下,如果该集合存在只读操作,读出数据元素类型虽然不知道,但是始终是安全的。只存在读操作那么说明是协变,协变就会存在保留子类型化关系,也就是读出数据元素类型是不确定类型子类型,那么可想而知它只替换 Any? 类型的超类型,因为 Any? 是所有类型的超类型,那么保留型化关系,所以 MutableList<*> 实际上就是 MutableList<out Any?> 的子类型了。

3.1 星投影的定义

星投影是一种特殊的星号投影,它一般用来表示不知道关于泛型实参的任何信息,换句话说就是它表示一种特定的类型,但是只是这个类型不知道或者不能被确定而已。

3. 代理模式的基本要求

委托对象 (或者被代理对象) 与代理对象需要实现相同的接口;代理对象中保有实际的委托对象引用,外部调用的操作或行为都是代理对象在内部交于实际的委托对象去实现;为了内部隐藏性,外部调用者直接和两者共同的接口通信。

4 手势处理示例

本节通过GestureDetector完成一个类似微信聊天中的大图缩放功能,即通过双指往外或者向内的手势来控制图片的放大、缩小。

3. 使用代理

在 Scrapy 项目中使用代理是非常简单的一件事情,我们只需要在发送的 Request 请求中添加 meta 参数即可实现代理功能:yield Request(url, callback=回调方法, errback=错误回调, meta={"proxy": proxy, "download_timeout": 10})上面生成的 Request 请求带上了 meta 参数,该参数中又设置了代理服务器的地址以及相应的超时时间。我们可以简单来看看代理服务器的使用:首先我们来自己搭建一个 Nginx 服务,具体的搭建过程可以参考这个教程: Nginx入门手册;接着我们使用9999这个端口做为代理转发端口,相关的配置如下:# nginx.confserver { resolver 114.114.114.114; resolver_timeout 5s; listen 9999; location / { proxy_pass $scheme://$host$request_uri; proxy_set_header Host $http_host; proxy_buffers 256 8k; proxy_max_temp_file_size 0; proxy_connect_timeout 30; proxy_cache_valid 200 302 10m; proxy_cache_valid 301 1h; proxy_cache_valid any 1m; }}启动 nginx 服务后,我们这个代理服务就搞定了。我们可以使用 requests 测试下这个代理服务,看看是不是生效了:import requestsproxies = { "http": "http://180.76.152.113:9999",}response = requests.get("http://www.china-pub.com/browse/", proxies=proxies)response.encoding = 'gbk'print(response.text)上述代码位于另一台云服务器,请求的是互动出版物的图书分类页面,这次我们会在 requests 请求中加上我们刚刚配置的代理,使用 nginx 代理转发请求,请看视频演示:99往往在 Scrapy 中,我们往往会采用这样的方式去使用代理服务:准备好一个 redis 和 web 服务。其中 web 服务往往会使用 django 或者 flask 等 web 框架开发,用于爬取免费的代理 ip,同时会对爬取到的 ip:port 进行校验。如果代理 ip 有效则将其缓存至 redis 服务中,形成有效的 ip 代理池;web 服务会定期检查 ip 代理池的所有数据,对于无效的 ip 及时清除。同时,也会定时爬取新的有效的代理 ip 并保存到 redis 中;web 服务会提供一个获取当前 ip 池内有效 HTTP 代理地址的接口,这样外部应用只需要请求这个接口就能获取一个有效的代理地址;此外,在 Scrapy 的项目中,我们往往会按照如下的思路进行代理爬取:限于篇幅,这里不再对整个流程做案例演示,有兴趣的读者可以下去后一步步完成从 ip 代理池服务的开发到最后对接 Scrapy 框架的整个过程,推荐测试的网站为新浪微博,这也是 github 上许多案例的测试靶场。

8. 自定义配置文件

有时候参数太多,都放到一个配置文件中太乱了,我们会希望将配置分到不同文件中,然后每个文件保存不同配置。例如上面微信公众号配置,我们单独建立一个 wxmp.properties 文件,内容如下:实例:# wxmp.properties配置文件# 公众号的appidwxmp.appid=111# 公众号的secretwxmp.secret=222WxMpParam 代码如下:实例:/*** 微信公众号参数*/@Component // 注册为组件@PropertySource(value = "classpath:wxmp.properties", encoding = "utf-8") // 指定配置文件及编码public class WxMpParam { @Value("${wxmp.appid}") private String appid; @Value("${wxmp.secret}") private String secret;}

4.1 编辑代码

将 pages/index/index.vue 文件中,我们给 Login 组件上面加的条件编译去掉。来编辑 components/login/login.vue 文件中的样式部分。实例:/*H5平台登录按钮显示红色,微信小程序登录按钮显示蓝色*/button { /* #ifdef H5 */ background:red; /* #endif */ /* #ifdef MP-WEIXIN */ background:blue; /* #endif */}

4.2 测试效果

点击工具栏–运行–运行到内置浏览器,测试H5平台。点击工具栏–运行–运行到小程序模拟器–微信开发者工具,测试微信小程序平台。

5.2 测试效果

点击工具栏–运行–运行到内置浏览器,测试H5平台。点击工具栏–运行–运行到小程序模拟器–微信开发者工具,测试微信小程序平台。

3.6 数据分析

数据分析是指对数据搜集、整理、分析,并依据数据做出评估和预测。现在是一个依靠数据竞争的时代,世界 500 强企业中,有 90% 以上都建立了数据分析部门。IBM、微软、Google 等知名公司都积极投资数据业务,建立数据部门,培养数据分析团队。Python 提供了和数据分析相关的模块,典型的包括:numpy,用于数学计算,如矩阵计算。pandas,基于 numpy 数据分析工具,提供了大量能使我们快速便捷地处理数据的函数和方法。matplotlib:用于数据结果的可视化,将数据展现为散点图、折线图、直方图、柱状图、饼图等直观的形式。

4. 各平台小程序组件存放目录

uni-app 还有一个非常牛的地方,就是支持在 App 和小程序中使用小程序自定义的组件,支持情况如下:平台支持情况小程序组件存放目录 H5 从 HBuilderX2.4.7 起,支持微信小程序组件 wxcomponentsApp(不含 nvue)支持微信小程序组件 wxcomponents 微信小程序支持微信小程序组件 wxcomponents 支付宝小程序支持支付宝小程序组件 mycomponents 百度小程序支持百度小程序组件 swancomponents 字节跳动小程序支持字节跳动小程序组件 ttcomponentsQQ 小程序支持 QQ 小程序组件 wxcomponents

3. 使用梯度带来进行自动微分

通过上面小节的例子,想必大家已经对使用 TensorFlow 进行梯度求解有了一个大体的了解。具体来说,我们大致需要经过几个步骤进行自动微分的操作:定义梯度带 tf.GradientTape () 的上下文;指定我们要跟踪梯度的数据,tape.watch();在梯度带上下文之中进行我们想要的操作(一般是让数据通过网络);通过得到的结果来使用梯度带求得各个参数的梯度;后续的操作,比如根据梯度进行优化等。那么让我们来看一个更加实际一些的例子,使用矩阵进行运算。import tensorflow as tfx = tf.ones((5, 5))with tf.GradientTape() as t: t.watch(x) y = tf.reduce_sum(x) y = tf.reduce_sum(y+x) z = tf.multiply(y, y)dz_dx = t.gradient(z, x)print(dz_dx)我们可以得到输出,值得注意的是,因为我们的输入都是矩阵,因此得到的梯度也是一个矩阵:tf.Tensor([[33800. 33800. 33800. 33800. 33800.] [33800. 33800. 33800. 33800. 33800.] [33800. 33800. 33800. 33800. 33800.] [33800. 33800. 33800. 33800. 33800.] [33800. 33800. 33800. 33800. 33800.]], shape=(5, 5), dtype=float32)如此,我们便求得了梯度,这是我们进行自定义网络的第一步,下一步,我们要将整个网络的计算放在梯度带的上下文之中进行计算。

首页上一页1234567下一页尾页
直播
查看课程详情
微信客服

购课补贴
联系客服咨询优惠详情

帮助反馈 APP下载

慕课网APP
您的移动学习伙伴

公众号

扫描二维码
关注慕课网微信公众号