穿越代码迷雾:解密Tracing技术的神奇力量

thbcm阅读(193)

在软件开发和性能优化领域,追踪(Tracing)技术是一种重要的工具,用于收集和分析程序的执行过程和性能数据。本文将深入讲解Tracing的原理、工作方式以及在不同领域的应用场景,帮助读者更好地理解和利用这一强大的技术。

什么是Tracing?

Tracing是一种记录程序执行过程的技术,通过在关键点插入记录代码,可以收集关于函数调用、事件触发、资源利用以及时间消耗等方面的详细信息。它提供了全局的视图,能够展示程序的整体执行路径和性能瓶颈,帮助开发者深入理解和优化程序行为。

Tracing的原理与工作方式

Tracing的核心思想是在程序执行过程中插入记录代码,通常使用钩子函数、代理或注入机制来实现。当程序运行时,记录代码会捕获关键事件并将其记录到追踪系统中。这些记录可以包括函数调用、参数、返回值、时间戳等信息,以及与性能相关的数据,如CPU利用率、内存占用等。

应用领域

  • 性能优化:Tracing是性能优化的重要工具,可以帮助开发者找出性能瓶颈和潜在的优化点。通过分析追踪数据,可以确定哪些函数或代码路径消耗了大量的时间和资源,从而有针对性地进行优化。
  • 调试与故障排查:Tracing可以提供程序的详细执行路径和状态信息,有助于调试复杂的问题和排查故障。开发者可以追踪代码中的特定区域,查看数据流动、函数调用顺序以及异常情况,加快故障定位和修复过程。
  • 分布式系统:在分布式系统中,Tracing可以追踪请求的流经路径,从而提供端到端的可视化和诊断能力。通过记录请求的各个节点和服务之间的调用关系,可以分析系统的整体性能和瓶颈,并进行优化和扩展。

Tracing工具和框架

有许多开源和商业的Tracing工具和框架可供选择。例如,Dapper、Zipkin、Jaeger等是一些流行的分布式追踪系统;Chrome开发者工具中的Performance面板可以用于前端性能追踪;Node.js中的Async Hooks和Performance Hooks提供了追踪API等。

总结

Tracing技术是一种强大的工具,可以帮助开发者在性能优化、调试和分布式系统等方面取得突破。通过深入理解Tracing的原理和应用,开发者可以更好地利用这一技术来提升软件的质量和性能。同时,不同领域和场景下的Tracing工具和框架也提供了丰富的选择,开发者可以根据需求选择适合的工具来进行追踪和分析。

Spring Cloud Gateway:构建高效微服务网关的利器

thbcm阅读(177)

在微服务架构中,网关扮演着重要的角色,用于处理请求路由、负载均衡、安全认证等任务。Spring Cloud Gateway作为Spring Cloud生态系统的一部分,提供了一个灵活且高性能的网关解决方案。本文将深入探讨Spring Cloud Gateway的特性、工作原理以及如何利用它构建强大的微服务网关。

什么是Spring Cloud Gateway?

Spring Cloud Gateway是一个基于Spring Framework 5、Spring Boot 2和Project Reactor的反应式API网关。它提供了一种简单、轻量级的方式来处理请求路由、加载均衡、认证授权、限流等网关功能,以帮助构建弹性和高性能的微服务架构。

Spring Cloud Gateway的特性

  • 动态路由:Spring Cloud Gateway支持动态路由配置,可以根据业务需求轻松添加、删除或修改路由规则,实现灵活的服务转发和负载均衡。
  • 过滤器链:通过内置的过滤器和自定义过滤器,可以在请求进入和响应返回时执行各种处理逻辑,比如认证、鉴权、请求转换等。
  • 断路器支持:集成了断路器模式,可以防止服务雪崩效应,提高系统的容错性和稳定性。
  • 集成Spring生态系统:Spring Cloud Gateway与Spring生态系统紧密集成,可以无缝使用其他Spring Cloud组件,如Eureka、Config Server等。

Spring Cloud Gateway的工作原理

Spring Cloud Gateway基于异步、非阻塞的Reactor模型,通过使用Netty服务器来提供高性能的请求处理。它采用了基于HTTP请求和响应的编程模型,可以通过定义路由规则将请求转发到不同的微服务实例,并在转发过程中应用过滤器。

使用案例

  • 请求路由和负载均衡:Spring Cloud Gateway可以根据请求的路径、主机、请求头等信息进行动态路由,将请求转发到相应的微服务实例,并支持负载均衡策略。
  • 安全认证和授权:通过自定义过滤器,可以在网关层面进行统一的安全认证和授权处理,避免每个微服务都实现一遍认证逻辑。
  • 请求转换和重写:通过过滤器,可以对请求和响应进行转换和重写,例如添加请求头、修改请求路径等,以适应各个微服务的要求。

总结

Spring Cloud Gateway是构建微服务架构中强大网关的理想选择。它以其灵活性、高性能和可扩展性而受到广泛关注。通过深入理解Spring Cloud Gateway的特性和工作原理,开发者可以更好地利用它构建高效、安全且可靠的微服务网关,为复杂的微服务架构提供稳定的请求路由和处理能力。

Promises: JavaScript异步编程的救星

thbcm阅读(193)

Promises(承诺)是JavaScript中处理异步操作的一种机制,它提供了一种更优雅和可读性更高的方式来处理异步代码。Promises的实现原理基于一种称为”Promise/A+”规范的约定,该规范定义了Promises的行为和接口。

Promises的实现原理是什么?

Promises的实现原理可以通过以下4步概括:

  1. Promise有3种状态:pending、fulfilled和rejected。初始状态为pending。
  2. Promise实例包含一个then方法,then方法接受两个参数:onFulfilled和onRejected,分别为promise成功或失败的回调。
  3. Promise有一个内部属性[[PromiseState]],初始值为pending。内部又有一个属性[[PromiseResult]],初始值为undefined。
  4. Promise的状态只能从pending到fulfilled或rejected,状态一旦改变就不能再变。 fulfilled和rejected状态都会触发then里的回调。

当我们new一个Promise时,会传入一个执行器executor,执行器会立即执行。在执行器中我们可以处理异步任务,比如发送ajax请求,一旦异步任务执行结束,就可以决定是resolve(成功)还是reject(失败)这个promise。

如果执行resolve,那么将[[PromiseState]]设为fulfilled,[[PromiseResult]]设为传入的值。执行onFulfilled回调。

如果执行reject,那么将[[PromiseState]]设为rejected,[[PromiseResult]]设为传入的reason。执行onRejected回调。

这样通过状态和结果的改变,来触发then里不同的回调,从而实现异步流程的控制。

Promise就是通过状态改变来触发回调的,这也是它实现异步编程的基石。

如果在Promise的执行器函数(executor)中不调用resolve或reject, 会怎么样?

如果在Promise的执行器函数(executor)中不调用resolve或reject,通常会导致两个结果:

  • Promise对象的状态永远保持pending

Promise对象代表一个异步操作,它的最终状态应该在某个时刻确定下来(fulfilled或rejected)。如果executor函数中不调用resolve或reject,Promise的状态就无法得以确定,会永远处于pending状态。

  • then方法指定的回调函数不会被调用

then方法注册的回调函只有在Promise状态确定后才会被调用,如果状态一直是pending,那么then方法的回调函数就永远不会被执行。

所以,如果在executor函数中不调用resolve或reject,就是一个错误的实现,违反了Promise/A+规范。

正确的做法是,在executor函数中,无论异步任务是否成功,都需要在最后调用resolve或者reject,将Promise的状态确定下来,以便触发then方法注册的回调。通常like这样:


  
   
    new Promise((resolve, reject) => { // ...做一些异步操作 if(成功) { resolve(value); } else { reject(error); } })
   
  

所以,不调用resolve/reject,将导致Promise永远pending,然后注册的回调函数也就不会执行。这违反Promise的设计初衷,应该避免这样使用。

微前端是如何实现作用域隔离的?

thbcm阅读(178)

一、前言

沙箱(Sandbox)是一种安全机制,目的是让程序运行在一个相对独立的隔离环境,使其不对外界的程序造成影响,保障系统的安全。作为开发人员,我们经常会同沙箱环境打交道,例如,服务器中使用 Docker 创建应用容器;使用 Codesandbox运行 Demo示例;在程序中创建沙箱执行动态脚本等。

二、使用场景

2.1 iPaaS 可视化 API 编排  

在流程编排的某些节点需要用到低代码模型转换(Transformer),用户可在转换器流程节点自定义 Groovy 脚本实现,服务端在执行自定义的 Groovy 脚本时,会放置在沙箱中,避免对整个流程逻辑造成影响。

2.2 微前端应用沙箱  

在微前端当中,有一些全局对象在所有的应用中需要共享,如 Window 对象。不同开发团队的子应用很难通过规范约束他们使用全局变量。为了保证应用的可靠性,需要技术手段去治理运行时的冲突问题;通过使用沙箱,每个前端应用都可以拥有自己的上下文环境、页面路由和状态管理,而不会相互干扰或冲突。

接下来的篇章我们将介绍大前端领域沙箱的实现以及我们如何基于JS沙箱落地应用的过程。

三、JS沙箱调研

3.1 eval和Function  

前端常见的动态执行代码的方式是使用 Eval 和 New Function 提供一个运行外部代码的环境:     

// 使用 eval 的糟糕代码:
function looseJsonParse(obj){
    return eval(`(${obj})`);
}
console.log(looseJsonParse(
   "{a:(4-1), b:function(){}, c:new Date()}"
))

// 使用 Function 的更好的代码:
function looseJsonParse(obj){
    return Function(`"use strict";return (${obj})`)();
}
console.log(looseJsonParse(
   "{a:(4-1), b:function(){}, c:new Date()}"
))

两种方式都可以正常执行,并且返回结果相同,但是用来创建沙箱环境还不够格,因为它们都能访问[全局变量],无法实现作用域隔离。

3.2 with + new Function + proxy实现  

3.2.1 with关键字  

JavaScript 在查找某个未使用命名空间的变量时,会通过作用于链来查找,而 with 关键字,可以使得查找时,先从该对象的属性开始查找,若该对象没有要查找的属性,顺着上一级作用域链查找,若不存在要查到的属性,则会返回 ReferenceError 异常。

不推荐使用 with,在 ECMAScript 5 严格模式中该标签已被禁止。推荐的替代方案是声明一个临时变量来承载你所需要的属性。

3.2.2 ES6 Proxy  

Proxy 是 ES6 提供的新语法,Proxy 对象用于创建一个对象的代理,从而实现基本操作的拦截和自定义(如属性查找、赋值、枚举、函数调用等)。示例如下:

const handler = {
  get: function (obj, prop) {
    return prop in obj ? obj[prop] : 'weimob';
  },
};

const p = new Proxy({}, handler);
p.a = 2023;
p.b = undefined;

console.log(p.a, p.b); // 2023 undefined
console.log('c' in p, p.c); // false, weimob    

3.2.3 Symbol.unScopables  

With 再加上 Proxy 几乎完美解决 JS 沙箱机制。但是如果对象的Symbol.unScopables设置为 true ,会无视 with 的作用域直接向上查找,造成沙箱逃逸,所以要另外处理 Symbol.unScopables。

3.2.4 沙箱实现   

function sandbox(code, context) {
  context = context || Object.create(null);
  const fn = new Function('context', `with(context){return (${code})}`);
  const proxy = new Proxy(context, {
    has(target, key) {
      if (["console", "setTimeout", "Date"].includes(key)) {
        return true
      }
      if (!target.hasOwnProperty(key)) {
        throw new Error(`Illegal operation for key ${key}`)
      }
      return target[key]
    },
    get(target, key, receiver) {
      if (key === Symbol.unscopables) {
        return undefined;
      }
      return Reflect.get(target, key, receiver);
    }
  })
  return fn.call(proxy, proxy);
}

sandbox('3+2') // 5
sandbox('console.log("智慧商业服务商")') // Cannot read property 'log' of undefined
sandbox('console.log("智慧商业服务商")', {console: window.console}) // 智慧商业服务商
       

上面的代码主要做了3件事,实现沙箱隔离:

  • 使用 with API,将对象添加到作用域链的顶部,变量访问会优先查找你传入的参数对象,之后再往上找;
  • 通过ES6提供的proxy,设置has函数,实现对象的访问拦截,同时处理Symbol.unscopables 的属性,控制可以被访问的变量 context,阻断沙箱内的对外访问;
  • 绑定 this 指向 proxy 对象,防止 this 访问 window;

3.3 基于iframe实现  

iframe 标签可以创造一个独立的浏览器原生级别的运行环境,这个环境由浏览器实现了与主环境的隔离。在 iframe 中运行的脚本程序访问到的全局对象均是当前 iframe 执行上下文提供的,不会影响其父页面的主体功能,因此使用 iframe 来实现一个沙箱是目前最方便、简单、安全的方法。

const parent = window;
const frame = document.createElement('iframe');
// 限制代码 iframe 代码执行能力
frame.sandbox = 'allow-same-origin';
document.body.appendChild(iframe);
const sandboxGlobal = iframe.contentWindow;

3.4 node运行时实现  

3.4.1 原生模块vm  

相较于浏览器环境,Node运行时就简单很多,使用其提供的原生vm模块,可以很方便的创建V8虚拟机,并在指定上下文编译和执行代码;

const vm = require('node:vm');

const x = 1;

const context = { x: 2 };
vm.createContext(context); // Contextify the object.

const code = 'x += 40; var y = 17;';
vm.runInContext(code, context);

console.log(context.x); // 42
console.log(context.y); // 17

console.log(x); // 1; y is not defined.

问题来了,使用 vm.runInContext 看似创建了沙箱隔离环境,但 vm 模块足够安全吗?引用 Node 官网的回答

node:vm 模块不是安全机制。不要用它来运行不受信任的代码。

3.4.2 不安全原因  

为什么不是安全机制,继续剖析;

const vm = require('vm');
vm.runInNewContext('this.constructor.constructor("return process")().exit()');
console.log('智慧商业服务商') // 永远不会执行

这就是 JS 语言的特性,以上示例中 runInNewContext 会默认创建上下文对象, this 指向默认创建的 ctx 对象 并通过原型链的方式拿到沙盒外的 Funtion,通过Function 访问全局变量,完成逃逸,并执行逃逸后的 JS 代码。

3.4.3 解决方案  

解决方案是绑定上下文对象,同时切断上下文对象的原型链,提供纯净的上下文对象,避免通过原型链逃逸。

const vm = require('vm');
let sandBox = Object.create(null);
sandBox.title = '智慧商业服务商'
sandBox.console = console
vm.runInNewContext('console.log(title)', sandBox);

Flutter 有什么优异特性和革命性创新之处?

thbcm阅读(176)

什么是 Flutter?

Flutter mobile app SDK是一种新的方式来构建漂亮的原生移动应用程序,摆脱过去常见的“千篇一律”的应用程序。用过Flutter的人都对它赞赏有加;

相比较其他新型系统,人们想知道是什么让它与众不同,换句话说,“Flutter的创新和令人兴奋的内容到底是什么?”,这是个好问题。本文将从技术角度回答这个问题。

首先,先来讲点历史。

移动应用程序开发的简史

移动应用程序开发是一个相对较新的领域。 第三方开发人员已经能够在不到十年的时间里构建移动应用程序,所以此类工具仍在不断发展的现象并不令人觉得奇怪。

平台软件开发工具(Platform SDK)

Apple iOS SDK于2008年发布,Google Android SDK于2009年发布。这两个SDK分别基于不同的语言:Objective-C和Java。

在这个模型中,你的app通过与平台(Platform)通信以创建小部件(Widgets)或访问相机等服务。 窗口小部件会呈现在屏幕画布上(Canvas),同时事件(Event)会被传递到窗口小部件。 虽然这是一个简单的架构,但你几乎要为每个平台创建单独的应用程序,因为在不同平台上的小部件也是不同的。这样的软件开发难度可想而知更不用说还要使用原生语言开发了。

网页视图(Web view)

Web View是史上第一个跨平台框架,它基于JavaScript和WebViews,其例子包括一系列相关框架 :PhoneGap,Apache Cordova,Ionic等。 在Apple发布iOS SDK之前,Apple建议第三方开发人员使用Webapp为iPhone编写程序。因此使用Web技术构建跨平台应用程序是具有代表性的一步。

在这个框架中,你的app会创建HTML并将其显示在平台上的WebView中。 请注意,像JavaScript这样的语言很难直接与本机代码(如服务)对话,因此它们会经历一个“桥”,在JavaScript领域和本机领域之间进行上下文切换。 由于平台服务通常不会经常被调用,因此这不会导致太多性能问题。

响应视图(Reactive Views)

当下,满大街都是像ReactJS(或是其他)这样的响应式网页编程框架,主要是因为它们借鉴了响应式编程的编程模式来简化Web视图。2015年,React Native的建立给手机app上的响应式开发提供了许多便利。

React Native非常受欢迎,但是如果它想从JavaScript域中访问处于平台域(Platform)中的平台部件(Widget),它就必须通过桥接器(Bridge)。 通常,小部件需要被频繁调用(在动画,转换期间或当用户用手指“刷”屏幕上的某些内容时,调用次数被限制在了每秒最多60次),这就可能会导致性能问题。就像one article about React Native所说:

这是理解React Native性能的主要关键之一。 每个领域本身都非常快。 当我们从一个领域转移到另一个领域时,通常会出现性能瓶颈。 为了构建高性能的React Native应用程序,我们必须将桥上的数据传递保持在一定限度之内。

Flutter

与React Native一样,Flutter也提供了响应式视图。 Flutter采用不同的方法来避免因使用编译的编程语言(即Dart)而需要JavaScript桥接从而导致的性能问题。Dart是“提前”(AOT)编译为多个平台的原生代码。 它能够与Flutter与平台进直接行通信,而无需通过执行上下文切换的JavaScript桥接器。 此外,编译为原生代码的应用程序还可以缩短程序的启动时间。

事实上,Flutter是唯一的,不需要Javascript桥接的手机SDK。这足以使得它变得很有趣并值得一试。不仅如此,Flutter还有一些更具革命性的东西,比如它实现小部件的方式。

Flutter的小部件 (Widget)

窗口小部件是影响和控制应用程序视图和界面的元素。 说小部件是移动应用程序最重要的部分之一并不夸张。 事实上,单独的一个小部件就足以创建或破坏一个应用程序。

  • 小部件的外观和感觉是至关重要的。 小部看起来好看,需要适配各种屏幕尺寸。同时,他们也需要感觉自然。
  • 小部件必须快速执行: 创建窗口小部件树,伸缩窗口小部件(实例化他们的子窗口),将它们放在屏幕上,渲染它们,或(尤其是)为它们设置动画。
  • 对于现代应用程序,窗口小部件应该是可扩展和可自定义的。开发人员希望能够添加令人愉快的新窗口小部件,并自定义与应用程序的品牌相适应的窗口小部件。

Flutter有一个新的架构,包括良好的外观,反应速度快,可定制和可扩展的小部件。 没错,Flutter不使用平台小部件(或DOM WebViews),它提供了自己的小部件。

Flutter将小部件和渲染器放到应用程序域中而不是传统的平台域中,这使小部件可以自定义和扩展。 Flutter要求平台提供画布(Canvas)(应用程序在其中呈现小部件以便它们可以出现在设备屏幕上)及访问事件(触摸,计时器等)和服务(位置,相机等)。

Dart程序(绿色)和本机平台代码(蓝色,iOS或Android)之间仍然有一个接口,可以进行数据编码和解码,但这比JavaScript桥接器快几个数量级。

事实上,将小部件和渲染器移动到应用程序中会影响应用程序的大小。 Android上Flutter应用程序的最小大小约为4.7MB,相当于使用其他工具构建的最小应用程序的大小。

本文的其余部分将讨论这些好处。

布局(Layout)

在Flutter中最大的提升之一是Layout(布局)。Layout(布局)基于一些规则(也叫约束)决定了widgets(小部件)的大小和位置。

传统上,布局使用大量能够被应用到(几乎)所有小部件的规则。这些规则被接入多种布局思路。我们以CSS布局为例,因为它很知名(尽管 安卓和iOS的布局基本上是相似的)。CSS具有的一些属性(规则)可应用于HTML元素(小部件)。CSS3定义了375个属性。

CSS包含许多布局模型,包括(多个)框模型、浮动元素、表、多列文本、分页媒体等等。后来又添加了其他的布局模型,比如flexbox和grid,因为开发人员和设计师需要对布局进行更多的控制,并使用表格和透明图像来获得他们想要的东西。在传统布局中,开发人员无法添加新的布局模型,因此必须将flexbox和grid添加到CSS中,并在所有浏览器上实现。

传统布局的另一个问题是,规则可以相互交互(甚至冲突),元素通常有许多规则应用于它们。这使得布局变慢。更糟糕的是,布局性能通常是N-的平方阶,因此随着元素数量的增加,布局会变得更慢。

Flutter最初是由谷歌的Chrome浏览器团队成员进行的一项实验。我们想看看如果我们忽略传统的布局模型,是否可以构建更快的渲染器。几周后,我们取得了显著的性能提升。我们发现:

  • 大多数布局相对简单,例如:滚动页面上的文本、大小和位置仅取决于显示大小的固定矩形,以及一些表格、浮动元素等。
  • 大多数布局是小部件子树的本地布局,该子树通常使用一个布局模型,因此这些小部件只需要支持少量规则。

我们意识到,如果我们把它反过来看,布局可以大大简化:

  • 每个小部件将指定自己的简单布局模型,而不是一大堆可以应用于任何小部件的布局规则。•因为每个小部件需要考虑的布局规则要少得多,所以可以对布局进行大量优化。
  • 为了进一步简化布局,我们几乎把所有东西都变成了一个小部件。

下面是Flutter代码,用于创建一个布局简单的小部件树:

new Center(child: new Column(children: [new Text(‘Hello, World!’)),new Icon(Icons.star, color: Colors.green)]))

这段代码足够语义化,您可以很容易地想象它将产生什么,但是结果显示如下:

在这段代码中,一切都是一个小部件,包括布局在内。中心(Center)小部件将它的子部件放在其父部件(例如屏幕)中。列布(Column)局小部件垂直地排列其子部件(小部件列表)。该列包含一个文本(Text)小部件和一个图标(Icon)小部件(图标小部件具有属性及其颜色)。

在Flutter中,置于中心和填充的是小部件。主题是小部件,适用于它们的子组件。甚至应用程序和导航都是小部件。

Flutter 包含许多用于布局的小部件,不仅包括列,还包括行、网格、列表等。此外,Flutter还有一个独特的布局模型,我们称之为“sliver layout model”,用于滚动。Flutter中的布局非常快,可以用来滚动页面。想一下。滚动必须是即时的和平滑的,当用户在物理屏幕上拖动屏幕图像时,用户感觉屏幕图像是附着在他们的手指上的。

通过使用布局来滚动,Flutter可以实现高级类型的滚动,如下所示。注意这些都是GIF动画图像,Flutter更平滑。你可以(也应该)自己运行这些应用程序;请参阅本文末尾的参考资料部分。

Flutter Gallery appPosse Gallery appPosse Gallery app

在大多数情况下,Flutter可以一次完成布局,这意味着在线性时间内完成布局,因此它可以处理大量小部件。Flutter还可以进行缓存和其他操作,因此它可以在可能的情况下完全避免布局。

自定义设计

因为小部件现在是应用程序的一部分,所以可以添加新的小部件,并定制现有的小部件,使其具有不同的外观或感觉,或与公司的品牌相匹配。移动设计的趋势已经不再是几年前常见的千篇一律的应用程序,而是转向取悦用户并赢得奖项的定制设计。

Flutter为Android、iOS材料设计提供了丰富的、可定制的小部件集(事实上,我们听说Flutter有着最精确的材料设计)。我们使用Flutter的可定制性来构建这些小部件集,以匹配多个平台上本机小部件的外观。应用程序开发人员可以使用相同的可定制性来进一步调整小部件以满足他们的需求。

再谈谈交互性视图

用于响应web视图的库引入了virtual DOM。DOM是HTML文档对象模型,是JavaScript用来操作HTML文档的API,表示为元素树。virtual DOM是使用编程语言(在本例中是JavaScript)中的对象创建的DOM的抽象版本。

在响应式web视图中(由诸如ReactJS等系统实现),virtual DOM是不可变的,每次发生变化都要从头开始重建。

将virtual DOM与实际DOM进行比较,以生成一组最小的更改,然后执行这些更改来更新实际DOM。

最后,平台重新呈现真实的DOM并将其绘制到画布中。

这听起来可能需要大量额外的工作,但这是非常值得的,因为操作HTML DOM非常代价非常高昂

React Native也做了类似的事情,不过是针对移动应用。它在移动平台上操作本地小部件,而不是DOM。它不是一个虚拟DOM,而是构建一个小部件的虚拟树,并将其与本机小部件进行比较,只更新那些已经更改的小部件。

请记住,React Native必须通过桥与本机小部件进行通信,因此虚拟小部件树有助于将桥上的传递保持在最低限度,同时仍然允许使用本机小部件。最后,一旦本地小部件被更新,平台就会将它们呈现给画布。

React Native是移动开发的一大胜利,也是Flutter的灵感来源,但Flutter更进一步。

回想一下,在Flutter中,小部件和渲染器已经从平台提升到用户的应用程序中。由于没有本地平台小部件可操作,所以原来的虚拟小部件树现在变成了小部件树。Flutter呈现小部件树并将其绘制到平台画布。这很好,很简单(而且很快)。此外,动画发生在用户空间中,因此应用程序(以及开发人员)对它有更多的控制。

Flutter渲染器本身很有趣:它使用几个内部树结构只渲染那些需要在屏幕上更新的小部件。例如,渲染器使用“使用合成的结构重绘”(“结构”的意思是通过小部件,这比通过屏幕上的矩形区域更有效)。未更改的小部件,即使是那些已经移动的小部件,也会从缓存中进行“位传输(bit blit)”,这非常快。这是使滚动在抖动中表现得如此出色的原因之一,即使是在高级滚动中(如上所述)。

Dart 编程语言

因为Flutter与其他使用响应视图的系统一样, 为每个新帧刷新视图树,它创建了许多仅存活一帧(六十分之一秒)的对象。并且,Dart使用对于这类系统非常有效的“分代垃圾收集技术”,因为这样做可以降低回收对象(特别是短命的对象)的消耗。此外,Dart仅使用单个指针的增减便能完成对象的分配,这种指针运作很快并且不需要锁定。这有助于避免UI丢帧和卡顿。

Dart还有一个“ tree shaking ”编译器,它只包含你的应用程序所需的代码。您可以放心地使用大型小部件库,即使您只会用到库中的一个或两个小部件。有关Dart的更多信息,请阅读“ 为什么Flutter使用Dart ”。

实时重载

Flutter最受欢迎的原因之一就是其快速且有状态显示的实时重新加载功能。您可以在一个Flutter应用程序运行时对其进行更改,它将重新加载已更改的应用程序代码,并让它从停止的地方继续运行,通常在不到一秒钟的时间内。如果您的应用程序遇到错误,您通常可以修复错误,然后继续,就像错误从未发生过一样。即使你必须做一个完全重新加载,它依旧是很快的。

开发者们告诉我们这让他们“画”出他们自己的应用程序,做出一个改动并几乎实时看到结果却不用重新启动应用程序。

兼容性

因为小部件(包括用于小部件的渲染器)是应用程序的一部分,而不是平台的一部分,所以无需“适配链接库(Compact libraries)”。 您的应用不仅能运行,而且能在最近的系统版本上正常运行(安卓4.1及IOS 8.0)。这大大减少了在旧操作系统版本上测试应用程序的需求。此外,您的应用程序很可能适用于未来的操作系统版本。

有一个潜在的问题是,因为Flutter不使用原生平台的小部件,所以当支持新小部件的新版iOS或安卓发布时,或是当老版本的小部件的外观和行为方式被改变时,Flutter小部件是否需要很长时间才能更新?

  • 首先,Google是Flutter的一个重要内部用户,因此我们有足够的热情来更新小部件集以使其保持最新状态并尽可能接近当前新平台的小部件。
  • 就算窗口小部件迟迟不更新,Flutter的小部件具有很强的可扩展和可定制能力,任何人都可以更新它们,即使是你。于是,人们甚至不必提交请求,您也不必等待Flutter本身更新。
  • 以上几点仅适用于当您希望在应用中使用新的小部件时。如果您不希望更改影响应用的外观或行为方式,同样也是可以的。窗口小部件是您应用的一部分,因此窗口小部件永远不会在您不知情的情况下更改并使您的应用看起来很糟糕(或者更糟糕的是,导致应用无法运行)。
  • 此外,您可以通过自行编写小部件,以便即使在较旧的OS版本上也可以使用新的小部件。

其他优点

Flutter的简单性使它变得更快,同时它具有普遍的可定制性和可扩展性,使其功能强大。

Dart有一个软件包存储库,因此您可以扩展应用程序的功能。例如,有许多软件包可以轻松访问Firebase,因此您可以构建“无服务器”应用程序。外部贡献者创建了一个包,允许您访问Redux数据存储。还有一些称为“ plugins(插件)”的软件包,可以以独立于操作系统的方式,更轻松地访问平台服务和硬件,例如 加速度计或摄像头。

当然,Flutter也是开源的,再加上Flutter渲染堆栈是你应用程序的一部分,这意味着你可以为个人应用程序自定义几乎任何你想要的东西。此图中的所有绿色都可以自定义:

所以,Flutter到底新在哪,为何如此吸引人

如果有人像这样问你,现在你知道该如何回答它们了:

  • 响应式视图的优点,不用JavaScript的桥接
  • 快速,流畅,可预测; 代码将AOT编译为本机(ARM)代码
  • 开发人员可以完全控制小部件和布局
  • 配有漂亮的可定制小部件
  • 出色的开发工具,具有惊人的实时重载功能
  • 性能更高,兼容性更强,更有趣

你注意到我遗漏了什么吗?其实那是人们在谈论Flutter时首先提到的东西,但对我而言,这是Flutter最无趣的事情之一。

事实上,Flutter可以从单个代码库为多个平台构建漂亮而快速的应用程序。当然,它本身就是为此而生的!它的可定制性和可扩展性,可以轻松地将Flutter定位到多个平台,而不会放弃性能或功耗。

革命性

我也从未完全解释为什么Flutter是“革命性的”。但这样解释起来很合适,因为外部开发人员使用Flutter构建的第一个主要应用程序之一是“ 汉密尔顿:美国音乐剧 ” 的官方应用程序,它发生在美国独立战争时期。汉密尔顿是有史以来最受欢迎的百老汇音乐剧之一。

项目经理Posse表示,他们选择了Flutter,因为他们需要“ 在短短的三个月内 ” 构建应用程序。他们称之为“为革命性的演出创建革命性的应用”,并称“Flutter是美丽,高性能,品牌驱动的移动体验的绝佳选择。” 他们还在 Google Developer Days会议上就他们构建Flutter的应用程序的体验发表了讲话。该应用程序可在AndroidiOS上使用,并获得好评如潮

一起投身变革吧

2018年12月4日,Flutter 1.0发布。2021年3月4日,Flutter 2.0 发布,Google 将继续为其添加更多功能,并且计划进行更多优化。Flutter的使用已经开始,全球有超过250,000名开发人员。Flutter目前在Github上活跃的软件存储库中排名前20位。

如果您对Flutter感兴趣,可以安装它并使用安装附带的一些示例应用程序。一定要查看有状态显示的实时重载。

如果您不是开发人员或只是想看一些应用程序,您可以安装使用Flutter构建的应用程序,并查看它们的外观和性能。我推荐Hamilton应用程序,但还有其他优秀的程序。或者您还可以观看来自Google I / O的视频

资源

网站:

视频:

应用:

进一步阅读:

限免!iOS系统抓包利器——Stream HTTP抓包工具限时免费,速收藏!

thbcm阅读(186)

一、前言

对于移动开发和测试人员来说,抓包是日常工作中必不可少的一个环节。只有抓取到客户端与服务器之间传输的数据,我们才能准确定位和解决各种网络请求方面的问题。今天给大家推荐一款功能强大,操作简单的iOS平台抓包工具——【Stream HTTP抓包工具】,目前限时免费,感兴趣的朋友千万不要错过!

二、主要功能

Stream是一款专为iOS平台开发的HTTP/HTTPS抓包工具,主要功能包括:

  1. 抓取 HTTP&HTTPS 请求,其中 HTTPS 请求需要配置 CA 证书。
  2. 访问抓包历史,预览请求体 (request body) 以及响应体 (response body),目前支持文本/JSON/文件/表单。
  3. 域名过滤: 只拦截您所需要的流量,不拦截其他流量,避免干扰其他应用。
  4. 请求重写: 支持重定向,支持替换请求或响应报文,也可以根据增则修改请求或或响应。
  5. 请求屏蔽: 支持根据URL屏蔽请求,不让请求发送到服务器。
  6. 脚本: 支持编写JavaScript脚本来处理请求或响应。
  7. 搜索:根据关键词响应类型多种条件搜索请求

三、准备工作

1. 首先点击下方网址下载并安装Stream 下载地址:https://apps.apple.com/cn/app/id6483685232

或扫描下方二维码进行下

2. 打开Stream,点击”启用HTTPS代理”,然后点击”下载根证书”,如下图

3. 在弹出的Safari页面会弹出下载一个描述文件,点击”允许”,如下图

4. 打开iOS系统设置,点击”已下载描述文件”,再点击”安装”,输入锁屏密码后确认安装,如下图

5. 安装完成后,回到系统设置,点击”通用”-“关于本机”,拉到最下面点击”证书信任设置”,如下图

6. 找到”Stream Generated Certificate”,将其启用,如下图,这一步是为了让iOS信任Stream的根证书,否则HTTPS抓包会失败。


7.重新回到Stream,打开“启用HPPS代理”开关

四、开始抓包

1. 完成准备工作后,回到Stream的主界面,点击”开始抓包”,如下图

2. 如果是第一次使用,会提示需要添加VPN配置,点击”允许”并验证,如下图

3. 开始抓包后,你可以访问任何网站或者打开任何App,Stream会自动记录所有的网络请求,如下图

4. 要停止抓包,点击右下角的红色方块即可,如下图

五、分析数据

  1. 停止抓包后,可以在Stream的请求列表中查看每一条网络请求的详细信息
  2. 点击请求,可以查看该请求的请求头、请求体、响应头、响应体等

六、请求重写

Stream提供了强大的请求重写功能,可以通过自定义规则来动态修改HTTP/HTTPS请求和响应的内容。目前Stream支持以下5种重写类型:

  1. 替换请求:完全替换原始请求,包括请求行、请求头、请求体
  2. 替换响应:完全替换原始响应,包括状态行、响应头、响应体
  3. 修改请求:对请求进行局部修改,如增删改请求参数、请求头等
  4. 修改响应:对响应进行局部修改,如修改响应头、响应体等
  5. 重定向:将请求重定向到另一个URL

1、创建规则

你可以通过以下两种方式来创建重写规则:

  1. 在Stream主界面,点击”设置”-“请求重写”,然后点击”+”按钮新建一个规则
  2. 在抓包详情页面,点击消息体右上角的重写图标,可以快速创建一个针对当前请求的重写规则

创建重写规则

2、替换响应

此重写行为表示整体替换响应数据,支持替换的部分:状态码方法、响应头、响应体。

3、修改请求

假设我们要修改如下URL中name参数的值,但要保留age参数不变:


  
   https:
   //example.com?name=123&age=32
  

可以创建一个修改请求的重写规则,将name参数的值替换为345:修改请求参数如果参数的key不确定,也可以用正则表达式来匹配和替换:正则替换请求参数你还可以通过修改请求的重写规则来实现删除、新增请求参数,以及修改请求头、请求体等。Stream支持为一个请求创建多个重写规则,并按照规则列表中的顺序依次执行。

七、写在最后

以上就是Stream HTTP抓包工具的基本使用流程,整个过程不需要越狱,也不需要USB连接电脑,非常便捷。Stream的功能远不止于此,它还支持请求重写、自定义脚本等高级功能,感兴趣的朋友可以在使用中继续探索。目前Stream限时免费,建议大家赶紧下载体验。
希望Stream能够成为你开发和调试工作中的好帮手!

零基础编程学python:如何从零开始学习并使用Python编程语言

thbcm阅读(183)

       Python是一种非常流行的编程语言,由于其简单的语法和强大的功能,使其成为初学者和专业开发者的首选。无论您是数据科学家、网络开发者还是自动化工程师,Python都能提供必要的工具来完成任务。这篇教程将详细介绍Python的基本概念、特点、优缺点以及如何在PyCharm中设置和管理Python项目。

1. Python的特性和优缺点

优点

  高开发效率:Python有一个非常直观和简洁的语法,可以快速地编写代码。

  多功能:Python是一种多范式的语言,支持命令式、面向对象和部分支持函数式编程。

  胶水语言:Python能够轻松地与其他语言如C、C++、Java等集成,这使得它可以用于各种复杂的应用场景。

 缺点

  运行速度慢:与编译型语言如C和C++相比,Python作为一种解释型语言,在运行速度上通常较慢。

  源代码不能加密:由于Python主要是解释执行的,源代码需要被发布和分发,这可能导致安全性问题。

2. 环境设置

在PyCharm中创建和管理Python项目

PyCharm是由JetBrains开发的一个强大的Python IDE。它提供了代码完成、错误高亮和即时的项目管理功能,使得Python开发更为高效和简便。

  1. 安装PyCharm:访问JetBrains官网下载并安装PyCharm。

  2. 创建新项目:启动PyCharm后,选择“Create New Project”,选择存放项目的位置以及Python解释器。

  3. 新建文件和目录:在项目视图中,右键点击并选择“New”,可以创建新的Python文件或目录。

3. Python基础

变量和数据类型

  变量:变量是存储数据的容器。在Python中,变量无需声明类型即可使用。

  数据类型:Python支持多种数据类型,包括整数(int)、浮点数(float)、字符串(str)、列表(list)、元组(tuple)、字典(dict)等。

运算符

  算术运算符:如加(+)、减(-)、乘(*)、除(/)。

  比较运算符:如等于(==)、不等于(!=)、大于(>)、小于(<)。

  赋值运算符:如赋值(=)、加赋值(+=)、减赋值(-=)。

控制结构

  条件语句:使用if、elif和else来控制条件逻辑。

  循环语句:for循环用于遍历集合,while循环用于重复执行,直到条件不满足。

函数

  函数是用来封装代码的一种方式,可以通过def关键字来定义。

  函数可以接受参数并返回结果。

类和对象

  类:使用class关键字定义,是创建对象的模板。

  对象:类的实例,可以具有属性和方法。

4. 实际应用

  打印输出:使用print()函数来输出信息。

  使用变量和数据结构:创建和操作列表、字典等数据结构。

  实现函数和类:定义和使用自己的函数和类来增强代码的模块性和重用性。

       通过本教程,您将能够从零开始学习Python,并逐步掌握使用这一强大工具的能力。实践是最好的学习方法,不断尝试和练习将帮助您更好地理解和运用Python编程。

为什么要学Python?学Python有什么用?

thbcm阅读(198)

       在当今的数字化时代,编程已成为一项宝贵的技能。Python,作为一种流行的编程语言,因其易于学习和强大的功能而受到全球开发者的青睐。本文将探讨学习Python的原因和它的实际应用,帮助你了解为什么这门语言值得学习。

为什么要学Python?

1. 易于学习和使用

Python以其清晰的语法和简洁的代码风格脱颖而出。相比其他编程语言,如Java或C++,Python的语法更接近英语,这降低了学习门槛,使初学者能够快速入门并实现功能。

2. 广泛的应用领域

Python的通用性让它在多个领域都有应用,从网站开发到数据科学,从自动化脚本到复杂的机器学习算法。无论你的兴趣在哪里,Python都可能有其用武之地。

3. 强大的库和框架

Python背后拥有一个庞大的生态系统,包括各种强大的库和框架。例如,Django和Flask框架让Web开发变得简单;Pandas和NumPy库支持复杂的数据分析;TensorFlow和PyTorch则在机器学习领域大放异彩。

4. 良好的职业前景

Python开发者的需求持续增长,特别是在数据科学和机器学习领域。掌握Python不仅能增强你的职业技能,还能打开通往各种高薪职位的大门。

5. 活跃的社区支持

Python有一个全球性的、活跃的社区,无论是在Stack Overflow、Reddit还是在本地用户组,你都可以轻松找到支持和资源,解决开发中遇到的问题。

学Python有什么用?

1. Web开发

利用Django、Flask等框架,Python可以快速开发安全、可扩展的Web应用程序。这些框架提供了许多用于处理数据库、表单、用户认证等常见Web开发任务的工具。

2. 数据分析和数据可视化

Python是数据科学领域的首选语言之一。使用Pandas进行数据清洗和分析,Matplotlib和Seaborn库可以帮助你将数据转换为直观的图表和报告。

3. 机器学习和人工智能

Python的简单语法和丰富的库资源使其成为实现机器学习算法的理想选择。库如Scikit-learn、TensorFlow和PyTorch提供了从线性回归到深度学习的各种工具和算法。

4. 自动化和脚本编写

Python简洁的语法非常适合编写日常自动化任务,如自动管理电子邮件、自动化报告生成或自动化软件测试。

5. 教育和科研

Python在教育领域也非常受欢迎,许多高校和中学已将Python纳入计算机科学和数据科学的课程中。此外,科研人员常用Python进行复杂的数学计算和模拟。

结论

       学习Python不仅可以开拓你的职业道路,还可以提供一个广阔的平台,让你在科技世界中畅游。无论你是一个寻求新技能的职场人士,还是对编程充满好奇的学生,Python都是一个绝佳的起点。

Python编程:从入门到精通

thbcm阅读(211)

Python是一种广泛使用的高级编程语言,以其出色的可读性和简洁的语法著称。无论你是初学者还是希望深化编程技能的开发者,Python都是一个极佳的选择。本文将指导你从Python的基础知识开始,一直学习到高级编程技巧,帮助你实现从入门到精通的转变。

入门基础

1. 安装Python

首先,你需要在你的计算机上安装Python。访问[Python官方网站](https://www.python.org/),下载并安装最新版本的Python。安装过程中,请确保将Python添加到你的环境变量中。

2. 了解基本概念

  变量和数据类型:学习如何使用变量来存储信息,以及Python支持的基本数据类型(如整数、浮点数、字符串、列表、字典等)。

  基本操作符:了解如何使用算术、比较和逻辑运算符。

3. 控制流程

  条件语句:使用if、elif和else来进行条件判断。

  循环:掌握for和while循环来重复执行代码块。

4. 函数

学习如何定义和调用函数,理解参数和返回值的概念,以及如何使用局部变量和全局变量。

5. 第一个Python程序

尝试编写一个简单的Python程序,如一个计算器或一个小游戏,以实践你学到的知识。

进阶应用

1. 面向对象编程(OOP)

  类和对象:了解如何定义类,创建对象,并理解封装、继承和多态性的概念。

  特殊方法:学习如何使用Python的特殊方法(如__init__ ,__str__,等)。

2. 错误和异常处理

  学习如何使用try、except块处理程序中的错误和异常。

3. 文件操作

  掌握如何读取和写入文件,包括文本文件和二进制文件。

4. 模块和包

  学习如何导入标准库中的模块,以及如何创建和使用自己的模块和包。

高级技能

1. 高级数据结构

  深入学习列表、字典、集合和元组等数据结构的高级用法。

2. 装饰器和生成器

  学习如何使用装饰器来修改函数的行为,以及如何使用生成器在需要时产生数据,而不是一次性生成。

3. 并发和并行

  探索如何使用threading和multiprocessing模块来提高程序的执行效率。

4. 网络编程

  学习如何使用socket编程进行网络通信,以及如何创建HTTP请求。

5. 数据库交互

  学习如何使用Python连接和操作数据库,如SQLite和MySQL。

实战项目

为了巩固你的Python技能,尝试完成一些实战项目,例如:

  Web爬虫:使用requests和BeautifulSoup库抓取网页数据。

  数据可视化:使用matplotlib或Seaborn库来展示数据。

  Web应用开发:使用Flask或Django框架开发Web应用。

  机器学习项目:使用scikit-learn或TensorFlow库进行数据分析和预测模型构建。

通过这些步骤,你可以系统地学习Python编程,并逐步提高到一个高水平。记住,编程技能的提升需要时间和实践,不断编写代码和解决问题是学习过程中不可或缺的部分。

从零开始的Python安装教程

thbcm阅读(199)

在数字化时代,编程技能成为了一项宝贵的资产。Python,作为一种广泛使用的编程语言,因其易于学习和功能强大而受到了全球开发者的青着。本文旨在为初学者提供一个详尽的指南,介绍如何从零开始安装和配置Python环境,确保你可以顺利地开始你的编程之旅。

1. 选择合适的Python版本

选择正确的Python版本对于保证开发环境的稳定性和兼容性至关重要。

确定操作系统位数

  查看系统信息:在Windows系统中,可以通过“控制面板”->“系统”查看操作系统是32位还是64位。在MacOS中,可以在“关于本机”中找到这些信息。

下载Python

  官方下载:访问 [Python官方网站](https://www.python.org/downloads/windows/),根据你的系统位数选择对应的版本下载。推荐下载离线安装版本,因为它会自动配置环境变量。

2. 安装Python

安装Python是设置编程环境的第一步。

运行安装程序

  修改安装选项:在安装过程中,确保勾选“Add Python 3.x to PATH”选项,这将Python添加到系统环境变量,使其可以在命令行中全局访问。

验证安装

  检查安装:安装完成后,打开命令提示符或终端,输入 `python –version` 或 `python3 –version`。如果系统返回Python的版本号,则表示安装成功。

3. 初步测试Python安装

确保Python能在你的机器上正常运行是非常重要的。

测试Python

  运行测试脚本:在命令行中输入 `python` 进入交互式模式,尝试运行简单的命令,例如 `print(‘Hello, World!’)`。

检查pip安装

  验证pip:pip是Python的包管理工具,输入 `pip –version` 确保它已正确安装。

4. 安装和配置代码编辑器

虽然可以在任何文本编辑器中编写Python代码,但使用专门的IDE可以大大提高你的效率。

选择编辑器

  下载PyCharm:访问 [PyCharm官网](https://www.jetbrains.com/pycharm/),选择下载Community(免费版)或者Professional(专业版)。

配置PyCharm

  创建新项目:安装并打开PyCharm,创建一个新项目。确保项目路径不在系统盘,以避免潜在的权限问题。

5. 编辑器功能测试

确保编辑器配置正确,可以正常运行Python代码。

创建并运行脚本

  测试脚本:在PyCharm中创建一个新的Python文件,输入 `print(‘测试’)`,使用快捷键 `Shift + F10` 运行程序。

如果一切设置正确,你应该能看到输出结果“测试”,这表明你的Python开发环境已经准备就绪。

通过遵循本文提供的指南,你可以确保Python环境的正确安装和配置,为学习和开发Python项目打下坚实的基础。随着技能的提高,你将能够探索Python在数据科学、网站开发、自动化和许多其他领域的广泛应用。

联系我们