0%

什么是向量

向量是由方向和长度构成的量。通过由箭头表示。

什么是span

The set of all possible vectors that you can reach with a linear combination of a given pair of vectors is called the span of those two vectors

释义

v向量与w向量全部线性组合构成的向量集合称为“张成的空间”

av + bw 其中a,b都在实数范围内变动

什么是基

The basis of a vector space is a set of linearly independent vectors that span the full space

向量空间的一个基是张成(铺开)该空间的一个线性无关向量集

什么是矩阵

矩阵每一列表示一个维度的向量从而描述了一组基向量。矩阵是一种基于基向量改变来描述向量空间线性变换的语言。

什么是线性无关?如何说明向量v,向量w,向量u线性无关

科学家推荐的理解是:存在且仅存在一组标量组合[0,0,0]使得三个向量的加和为0向量时,说明三个向量线性无关
适用于教学目的的解释是:不存在任何一组标量组合[a,b]使的两个向量的加和等于第三个向量,说明三个向量线性无关

什么是线性变换

总结来说,线性变换应当看作是“保持网格线平行且等距分布”的变换。线性变换有两个特征,其一是直线仍是直线,其二是原点仍是原点。

变换和函数差不多,两者都是input -> output,不过前者有一种运动的概念。

线性变换矩阵的空间几何意义

线性变换实质上变换的是向量空间的基向量,向量空间中的任意一点都可通过变换后的基向量矩阵计算得出。
基向量矩阵,也可以理解为变换矩阵,是指线性变换之后基向量(i帽,j帽)的落脚点,即基向量从[[1, 0], [0, 1]]线性变换[[0, -1], [-1, 0]]。

单块应用

所有功能都揉于一个容器中,可以简单有效的配合事务做到业务数据的ACID,但是内部相互之间依赖关系较复杂,耦合度较高,存在不易拆解、不易扩展、不灵活等弊端

微服务关键设计原则

  • 微服务是一系列根据业务流程拆分出来的业务单元
  • 它们是一系列包含了业务逻辑并能采用简单信道和协议与之进行通信的智能端点
  • 根据设计,微服务架构是去中心化的,旨在构建强壮,弹性的系统应用

关键好处

  • 弹性。系统处理变化的能力。
  • 可伸缩性。对某个微服务单独做cluster应付高负载强计算而不牵动其他模块。
  • 技术多样性。秉承高内聚,低耦合的原则,每个微服务对外暴露接口,但内部实现完全透明,也就是内部说可以用nodejs、erlang、golang等等语言实现。
  • 可替换性。指替换系统中某个模块而不影响系统的能力。有利于减少解决技术债务
  • 独立性。小而独立,分而治之。
  • 易于部署。微服务是自治的工作单元,可单独部署与升级。

SOA

面向服务架构,这也是一种软件设计原则。大体上,SOA与微服务架构是非常想想的。那么他们之间的区别是什么呢?

  • 微服务是细粒度的SOA组件,它们是关注点更窄的轻量级服务
  • 推崇执行标准不同。SOA未推崇,以J2EE技术栈中的ESB举例;而微服务推崇使用http
  • 领域模型。在微服务架构中,每个微服务通常自治数据库,并且隔离领域模型;而在SOA架构中各业务组件通常IO同一个大型数据库,并且业务组件之间共享领域模型。

模块化的基本原则(SOLID)

‘use strict’

  • 单一职责原则。尽可能的只处理某一范围的逻辑功能,如字符串操作、二次封装的http请求模块
  • 开放封闭原则。对功能扩展开放,对修改公用代码关闭
  • 理氏替换原则。
  • 接口分离原则。JS与C#、Java不同,它不是一门面向接口的语言。但是可通过module.exports变量将公用函数暴露给其他模块使用。
  • 依赖倒置原则(反转控制和依赖注入)。依赖倒置指模块间应依赖于抽象,反转控制指创建某个类实例的逻辑移交给某IoC容器控制,依赖注入指在IoC容器中对类实例配置所需依赖的操作。

服务器DevOps工具

  • chef. infrastructure automation
  • inspec. compliance automation
  • habitat. application automation

  • 适用群体

有一定前端知识的用户群体

  • MSE概述

结论是MSE提供了实现无插件且基于web的流媒体的能力。可以支持比如自适应码率,精确控制时间的H5直播和点播功能。业界比较出名的有DASH以及HLS协议,这两种协议都基于http协议,有较好的防火墙穿透功能(只要防火墙不拦截80与443端口流量,而一般来说都不会拦截),HLS对苹果设备极度友好而DASH跨平台兼容性更好,不过这两者劣势都是实时性不好通常延迟有好几秒之长,取而代之的一般是基于web技术有webRTC以及非web技术RTP。

  • MediaSource概述/含义

属于Media Source Extensions(MSE)标准中的一个接口,每一个MediaSource实例代表了一个媒体源数据应用于HTML媒体元素比如<video/><audio/>,通常附着于HTML媒体元素在用户代理中播放。

  • 本质

MediaSource = EventTarget + SourceBuffer + 其他属性比如说duration和readyState + 其他方法比如说isTypeSupported

  • 用处

高级的音视频媒体流播放方式代替传统URL类型

  • 用法

    import React, { Component } from “react”;
    import webmUrl from ‘./3.webm’;

    class VideoPlayer extends Component {
    videoDom;
    getUserMedia() {

    return navigator.mediaDevices.getUserMedia({ video: true, audio: true });

    }
    play = (url, mimeType = “webm”) => {

    let mimeCodec, mediaSource;
    if (mimeType === "webm") {
      mimeCodec = 'video/webm; codecs="vorbis, vp8"';
    }
    
    const sourceOpen = () => {
      // 新增mediaSource对象
      let sourceBuffer = mediaSource.addSourceBuffer(mimeCodec);
      fetch(url, {
        responseType: 'arraybuffer'
      }).then(data => data.arrayBuffer()).then(buffer => {
        sourceBuffer.addEventListener("updateend", () => {
          if (mediaSource.readyState === "open") {
            mediaSource.endOfStream();
          }
          this.videoDom.play();
        });
        sourceBuffer.appendBuffer(buffer);
      });
    };
    
    // 检查可用性
    if ("MediaSource" in window && MediaSource.isTypeSupported(mimeCodec)) {
      mediaSource = new MediaSource();
      this.videoDom.src = URL.createObjectURL(mediaSource);
      mediaSource.addEventListener("sourceopen", sourceOpen);
    } else {
      console.error("Unsupported MIME type or codec: ", mimeCodec);
    }

    };
    componentDidMount = () => {

    this.play(webmUrl);

    };
    render() {

    return (
      <div className="recorder-wrapper">
        <canvas style={ { width: 0, height: 0 }} />
        <video
          ref={dom => (this.videoDom = dom)}
          style={ { width: 400, height: 400 }}
        />
      </div>
    );

    }
    }

    export default VideoPlayer;

  • index.js:1509 Uncaught Error: The error you provided does not contain a stack trace.

    at B (index.js:1509)
    at G (index.js:1816)
    at index.js:1831
    at index.js:1850
    at index.js:1343

    B @ index.js:1509
    G @ index.js:1816
    (anonymous) @ index.js:1831
    (anonymous) @ index.js:1850
    (anonymous) @ index.js:1343
    stream-media.js:25 Uncaught (in promise) DOMException

根因是该媒体文件不兼容MSE标准(可能原因是容器格式不兼容也有可能是音视频编码器不兼容),请check mimeCodec和真实视频完全一致,要查看视频容器的源信息需要借助ffmpeg等三方工具。

  • Tips

ffmpeg -i test.webm

记录学习webgl踩坑

当gl.drawElements报警告时,请check未出现以下情况,如出现请先解决

  • 索引数组中的最大值 * 每个顶点所占浮点数个数(包含图元所需顶点数和Color)> 顶点数组长度

当gl.drawArrays报警告时,请check未出现以下情况,如出现请先解决

  • 第二个参数Count数 * 每个顶点所占浮点数个数(包含图元所需顶点数和Color) > 顶点数组长度

当gl.drawElements和gl.drawArrays都没报错,但仍没有画面时,请check

  • Color值从生成直到FragmentShader使用到该Color值前有没有做归一化或?换句话说就是可能被裁剪了。顶点值也是如此。
  • 如果是用gl.TRIANGLE画几何体,注意是否画的是正面(FRONT_FACE)即逆时针绘制。换句话说可能是gl.CULL_FACE。

snowy框架注意点

  • 自定义geometry类中的positions属性必须归一化
  • indices一般都要UInt8Array类型并且必须和drawElements的第三个参数对齐

Common Checks

  • 坚持使用 transform 和 opacity 属性更改来实现动画。
  • 使用 will-change 或 translateZ 提升移动的元素。
  • 避免过度使用提升规则;各层都需要内存和管理开销。

Several Questions

  • 有多少layers?合理的数量是多少?每一个layer的原因。
  • 在不通电的多倍屏(如13寸MBP)的匿名模式窗口中打开查看Layers面板。每个layer渲染一帧耗时?确保所有layer加起来小于15ms。
  • 在做动画时,有多少个layer重新绘制?考虑减少不必要的layer重新绘制或者复杂的layer拆解。

Performance Targets

  • 每个layer力争4 - 5毫秒的时间(尤其针对于可能要做的Admin移动端来说尤为重要)。
  • 每个稍大(绘制时间超过1ms)layer都具有必要性,否则销毁。
  • 动画过程中,通过观察Layers和Animation面板确定每个layers重绘都是必要的。
  • 如果Layers面板中的layer绘制时间求和的结果在15ms以内,上述就都不必check了。
  • 在Performance面板中一定一定不要存在forced layout,如果有请消灭它。

Other Actions

  • 坚持仅合成器的属性和管理层计数,否则使用FLIP原则使得从开销更大的属性重新映射为变形和透明度的更改。

Refs

  • Layers面板使用方式查漏补缺
  • FLIP Principle
  • Inspect Your Animation
  • 降低绘制复杂度、减小绘制区域
  • 坚持仅合成器的属性和管理层计数

菜单栏收缩动画性能瓶颈分析案例

  • 动画属性不符合预期

*重绘制layers完全超乎预期
*Antd Loading提升一个Layer而且占用内存超预期很多
*没必要的layer开销超预期很多
*同一个DOM却提升两个layer
*动画过程中,.basic-layout-container未提升新layer,且提升之后Layer出现闪动(似乎是layer销毁却又重新创建)
*降低绘制复杂度
*减小绘制区域(Antd Loading没必要随父元素展开,用绝对定位或者定高来限制绘制区域,水印亦是如此)

prepare

  1. Shadowsocks家族vpn软件,亲测RocketVPN不可用。因为命令行连接谷歌域名必须要建立https连接,并且会失败。解决方案是命令行翻墙。至少git和curl需要翻墙。
    • git config –global https.proxy localhost:1087
    • /.bashrc或者/.zshrc中设置curl全局代理。即尾行键入export https_proxy=http://localhost:1087
  2. 充足的时间。因为chromium在Google Git上有12G+,clone非常慢,fetch –tags比较慢,另外sync非常慢。
  3. 足够的HD空间。因为需要Xcode(解压后12G+),Chromium源码(12G+)。
  4. 需要保证(不知道怎么保证但就是要)。如果macOS版本和Xcode版本存在兼容性问题,会卡在gn gen out/Default(第8步)。
  5. Install Xcode, launch it, accept the license agreement, and run sudo xcode-select -s /path/to/Xcode.app to continue.

steps

官方教程不全,应该是编译最新版本且环境比较理想的情况下。因此整理一条在mac下编译M68版本且能跑通的操作序列。

*** 请务必确认终端已经科学上网。

  1. mkdir chromium && cd chromium
  2. fetch –nohooks chromium(后续再执行hooks)
  3. git fetch –tags
  4. git checkout -b release/68 68.0.3440.92
  5. cd ..
  6. gclient sync –with_branch_heads –jobs 16
  7. gclient runhooks (如果第6步提示Running hooks: 100% (64/64), done.则可省略此步骤)
  8. gn gen out/Default
  9. autoninja -C out/Default chrome

须确保每一条命令无Error。Warning可忽略。

Chromium Build教程传送门 前人踩坑,后人乘凉

我卡在macOS SDK(10.14.3)和Xcode(10.2 Beta3)版本不兼容,夭折。

what?

贝塞尔曲线(bezier curve),由线段和节点组成,节点是可拖动的支点,线段像可伸缩的皮筋。是计算机图形学中相当重要的参数曲线。

cubic-bezier curve公式

$$B(t)=P_0(1-t)^3+3P_1t(1-t)^2+3P_2t^2(1-t)+P_3t^3, 0 \leq t \leq 1$$

Features

  1. 起始于P0结束于Pn的曲线,即所谓的端点插值法
  2. 曲线的起始点(结束点)相切于贝塞尔多边形的第一节(最后一节)
  3. 一条曲线可在任意点切割成两条或任意多条子曲线,每一条子曲线仍是贝塞尔曲线

升阶

n次贝塞尔曲线可以转换成完全相同的n+1次贝塞尔曲线。

cubic-bezier曲线在浏览器timing-function中的应用

Compatibility

Web Components are now implemented natively on Safari and Chrome (~70% of installed browsers), and run well on Firefox, Edge, and IE11 using polyfills

Best Practices

Google Polymer

Concept

原生级web组件,是一种现代化web开发模式

Features(vs React、Vue)

  1. 提供原生级的作用域隔离(包括js与css),实现真正意义上的组件化

Short Boards

  1. 社区暂不活跃,导致优质组件不多等等
  2. 最低仅支持IE11,而且需要polyfills,兼容差一些
  3. 是否支持reactive components
  4. API不稳定

How

Web Components特性主要由四项技术构成Custom Elements、Shadow DOM、HTML Templates、HTML Imports

Custom Elements V0 API、Shadow DOM V0 API、HTML Imports将在2019年4月于M73被移除,并配套迁移至Custom Elements V1、Shadow DOM V1 API、ES Module API

Timer Demo

window.customElements.define('c-timer', class extends HTMLElement {
  constructor() {
    super()
    const shadowRoot = this.attachShadow({
      mode: 'open'
    })

    console.log(shadowRoot)

    const text = document.createElement('span')
    text.classList.add('testCls')
    text.textContent = this.getAttribute('start')

    shadowRoot.appendChild(text)

    const style = document.createElement('style')
    style.textContent = `
      .test {
        font-size: 3vw;
      }
    `
    shadowRoot.appendChild(style)

    setInterval(() => {
      text.textContent = Number(text.textContent) + 1
    }, 999)
  }
})

使用

<c-input start="111" />

架构图

  • Introduction
  • Core Thinking
    • Data-Driven
    • Pub and Sub
  • Architecture Design
    • Config
    • Base Layout
      • Header (Toolbar)
      • Left Sidebar(Set of widgets)
      • Right Siderbar(Area of widgets controllers)
      • Body(Area of central scene)
      • Popup(Area of system popup)
    • Core Abstract
      • Item
      • Widget
      • Editor
    • Widget System(Why not named component ?)
      • Item
      • Widget
      • Editor
      • Attrs
  • Core FEATURES
    • Flexiably Draggable
    • Joyful UI
    • Excellent Performance(Not that exactly)
    • Less Code For Developers
    • Abundant Opeations & Interactions
      • Dpr Support
      • Layer Support
      • Delete Widget
      • Indicator
      • Magnetic Attraction
      • Undo And Redo
      • Rotate And Resize
      • Realtime Interactions
    • Easy-to-use Data Structure
  • ROADMAP
    • Pull Away Engine
    • Make A GitBook
    • Add More Features
      • Ruler
      • Popover
      • Grid Lines
      • Zoom
      • Lock Layer
      • Alignment
      • Copy And Paste
      • Group And Break-up
      • Keyboard Hot Key
      • Page Guideline
      • Customizable Themes
      • i18n
      • Mobile Simulation
      • Portrait And Landscape
  • Core Libraries
    • react
    • react-dom
    • mobx
    • mobx-react
    • react-dnd
    • react-dnd-html5-backend
    • antd
    • react-color
    • lodash

  • 基本用法
  • 基本原理
    • 概述
    • 绑定与注册
    • 触发与dispatch
  • 合成事件(SyntheticEvent)
    • 概念
    • 优势
  • 事件池概念

基本用法

class DemoCom extends React.Component {
    handleClick(e) {
        alert('click')
    }
    render() {
        return <div onClick={this.handleClick}></div>
    }
}

注意点

  • 驼峰格式属性名
  • 值为事件处理器而非字符串
  • v14以后版本必须使用e.preventDefault()显示阻止浏览器默认事件而非return false

基本原理

概述

通过事件委托合成事件配合事件池批处理队列机制实现Event System

绑定与注册

所谓绑定,即建立事件处理器与实际Dom的关联。 所谓注册,即push事件处理器到关联Event Type的执行(callback)队列中等待派发。 而在React中,绑定与注册过程需要经过如下步骤,分别为:

  1. React Component在mountComponent以及updateComponent阶段都需要执行_updateDOMProperties处理JSX属性,然后遍历其属性并识别出事件属性
  2. (由于所有事件绑定在document上)通过ReactEventListener类的enqueuePutListener原型方法将事件进行注册,由Event Type与React对象进行了二维划分
  3. 通过EventPluginHub类的putListener原型方法储存事件等待派发

触发与dispatch

所谓dispatch,即依次执行对应Event Type相关的回调方法 而React自身实现一套捕获/冒泡机制并使用批处理的方式进行事件dispatch,关键步骤如下:

  1. 用户触发绑定在document上的TopLevel Event,执行ReactEventListener类dispatchEvent原型方法,将“bookKeeping”(可以理解为申请执处理)方法push到React内置的批处理队列中等待执行
  2. 当批处理tick到达,执行ReactBrowserEventEmitter.handleTopLevelImpl原型方法,该方法获取Dom与React对象,并且找到该React对象的祖先对象生成数组,从当前React对象向祖先遍历从而实现冒泡,并执行相同事件类型callback(也就是事件处理器)
  3. 执行ReactBrowserEventEmitter.handleTopLevel,通过合成事件构造器构造或者被析构后的事件对象重用两种方式生成合成事件(不同事件类型合成事件不一样),然后进入批处理队列等待执行
  4. 当批处理tick到达,遍历events,顺序执行event,然后遍历event相关的listeners,for循环依次执行,如果遇到stopPropagation则break,否则执行事件处理函数

SyntheticEvent

概念

对浏览器原生事件作一层封装的增强型事件对象,称为合成事件。 注意

  • 合成事件被Proxy封装
  • 原则上不建议和原生事件混用

优势

  • 兼容性。抹除IE与W3C标准差异,并提供与原生相同的API
  • 便捷性。提供onCopy等组合后事件,另外提供onClickCapture在捕获阶段执行事件处理器
  • 效率性。事件载体复用。

其他

Event System通过事件池与批处理机制对事件执行进行了性能优化,但并不见得比原生Event System性能好

事件池

概念

用于存放被析构的event栈。

如何形成

每次event对象使用完毕后(未使用event.persist()情况下)在release阶段生成并push至event栈。

如何利用

React内部在处理事件返回值时,分两种情况。

  1. 使用event.persist(),强制使用nativeEvent,此时不会使用事件池来优化。
  2. 不调用时,React返回一个合成事件。先判断事件池中是否存在可用的event实例对象,如果有则重用该实例并通过EventConstructor构造出新的合成事件后返回给事件处理器,反之则使用new EventConstructor()构造全新合成事件,并在使用完毕即进入release阶段,该阶段React将析构该合成事件后把event壳的引用push到事件池中等待复用。