lampkid / blog Goto Github PK
View Code? Open in Web Editor NEWthe Source of My blog generated by hexo
the Source of My blog generated by hexo
React/Redux
Flexbox layout
Typescript/flow/babel/metro bundler
Static Analysis:Eslint/prettier
Android/iOS knowledge
DLS:Design Language System
Performance
flexbox engine :yoga
App Size
Initialization Time: runtime initialization
Initial Render Time
RN upgrading
Accessiblity
不同团队对RN的态度是不一样,有经验的团队自然会觉得RN很赞,自然也有团队会后悔使用RN。
使用RN中可能遇到的挑战
我们使用RN想达到什么目标,RN是否能满足?RN是否适合你的团队
React是怎么实现O(n)的 diff算法的?
https://reactjs.org/docs/reconciliation.html
VUE、git diff、text diff又是如何实现Diff的
如何实现JSON的Diff?
commitizen
conventional-changelog
conventional-changelog-cli
cz-conventional-changelog
npx commitizen init cz-conventional-changelog --save-dev --save-exact
conventional-changelog -p angular -i CHANGELOG.md -w
npx git-cz
package.json
"config": {
"commitizen": {
"path": "./node_modules/cz-conventional-changelog"
}
}
写在前面的话
—— 俞敏洪
我们人的生活方式有两种,第一种方式是像草一样活着。你尽管活着每年还在成长,但是你毕竟是 一棵草,你吸收雨露阳光,但是长不大,人们可以踩过你,但是人们不会因为你的痛苦而他产生痛苦, 人们不会因为你被踩了而来怜悯你,因为人们本身就没有看到你。所以我们每个人都应该像树一样的成 长,即使我们现在什么都不是,但是只要你有树的种子,即使被人踩到泥土中间,你仍然能够吸收泥土 的养分自己成长起来,当你长成参天大树以后,遥远的地方人们就能看到你,走近你。你能给人一片绿 色,活着是美丽的风景,死了依然是栋梁之才,活着死了都有用。这就是我们每一个人做人的标准和成 长的标准。
每一条河流都有自己不同的生命曲线,但是每一条河流都有自己的梦想,那就是奔向大海,我们的 生命有的时候会是泥沙,你可能慢慢地就会像泥沙一样沉淀下去了,一旦你沉淀下去了,也许你不用再 为了前进而努力了,但是你却永远见不到阳光了,所以不管你现在的生命是怎样的一定要有水的精神, 像水一样不断地积蓄自己的力量,不断地冲破障碍但你发现时机不到的时候,把自己的厚度给积累起 来,当有一天时机来临的时候,你就能够奔腾入海,成就自己的生命!
V8中的TypedArray和Node中的Unit8Array、Buffer
内存了解多少?除了栈内存、堆内存还有什么?
第一:基于React的项目搭建和框架设计和实战
第二:基于React的国际化项目实战
第三: 基于Koa的Node项目设计和实战。
这篇主要包括两个模块:
比如PHP、Node、Java相关框架,如Zend、Laravel、yog、Spring等
富文本编辑器
JSX ->JSON JSON->JSX->HTML
JSX ->HTML->Canvas->PDF生成
- | vuex | redux |
---|---|---|
store count | 1 | 1 |
action | method | object |
action trigger | dispatch | dispatch |
data processor | mutation handler | reducer |
trigger data processor | commit mutation | dispatch action |
get data | this.$store&mapState&getter | - |
process | dispatch->action->commit mutation->mutation handler -> state-change->getter | dispatch->action->reducer->state change->connect |
module | modules & register modules | redux(combine reducers) |
async | saga | mutaion sync,action async |
action intercept | plugin | middleware |
最近团队发起了React源码解读的分享,分享过程中大家对一些问题也讨论了很多,各执己见。由于之前团队很少做类似的分享,所以在React这么一个大型项目源码解读时,是没有方向和茫然的。分享过程中,自己梳理了几个问题。记录以备后续研究。
分享思路:
技术话题:
React中transaction事务的概念,是为了解决那哪些问题的, 举例说明使用场景
setState的原理,是异步的还是同步的,分别有哪些场景
setTimeout回调中setState处理方式,eventloop参与的过程
批量更新的原理,在事件处理的中是批量更新的,在生命周期中也是批量更新的吗?
有setTimeout时,断点调试还有用吗
React官网关于内部实现的文章和设计原则
mattgreer-react-internals
Under-the-hood-ReactJS
本文会从多个实际应用中的中间件实现 分析中间件的设计和实现。比如redux、Django、koa2等
// https://github.com/reduxjs/redux/blob/master/src/applyMiddleware.js
/**
* Composes single-argument functions from right to left. The rightmost
* function can take multiple arguments as it provides the signature for
* the resulting composite function.
*
* @param {...Function} funcs The functions to compose.
* @returns {Function} A function obtained by composing the argument functions
* from right to left. For example, compose(f, g, h) is identical to doing
* (...args) => f(g(h(...args))).
*/
export default function compose(...funcs) {
if (funcs.length === 0) {
return arg => arg
}
if (funcs.length === 1) {
return funcs[0]
}
return funcs.reduce((a, b) => (...args) => a(b(...args)))
}
/**
* Creates a store enhancer that applies middleware to the dispatch method
* of the Redux store. This is handy for a variety of tasks, such as expressing
* asynchronous actions in a concise manner, or logging every action payload.
*
* See `redux-thunk` package as an example of the Redux middleware.
*
* Because middleware is potentially asynchronous, this should be the first
* store enhancer in the composition chain.
*
* Note that each middleware will be given the `dispatch` and `getState` functions
* as named arguments.
*
* @param {...Function} middlewares The middleware chain to be applied.
* @returns {Function} A store enhancer applying the middleware.
*/
export default function applyMiddleware(...middlewares) {
return createStore => (...args) => {
const store = createStore(...args)
let dispatch = () => {
throw new Error(
`Dispatching while constructing your middleware is not allowed. ` +
`Other middleware would not be applied to this dispatch.`
)
}
const middlewareAPI = {
getState: store.getState,
dispatch: (...args) => dispatch(...args)
}
const chain = middlewares.map(middleware => middleware(middlewareAPI))
dispatch = compose(...chain)(store.dispatch)
return {
...store,
dispatch
}
}
}
// https://github.com/koajs/koa/blob/master/lib/application.js
// https://github.com/koajs/compose/blob/master/index.js
'use strict'
/**
* Expose compositor.
*/
module.exports = compose
/**
* Compose `middleware` returning
* a fully valid middleware comprised
* of all those which are passed.
*
* @param {Array} middleware
* @return {Function}
* @api public
*/
function compose (middleware) {
if (!Array.isArray(middleware)) throw new TypeError('Middleware stack must be an array!')
for (const fn of middleware) {
if (typeof fn !== 'function') throw new TypeError('Middleware must be composed of functions!')
}
/**
* @param {Object} context
* @return {Promise}
* @api public
*/
return function (context, next) {
// last called middleware #
let index = -1
return dispatch(0)
function dispatch (i) {
if (i <= index) return Promise.reject(new Error('next() called multiple times'))
index = i
let fn = middleware[i]
if (i === middleware.length) fn = next
if (!fn) return Promise.resolve()
try {
return Promise.resolve(fn(context, dispatch.bind(null, i + 1)));
} catch (err) {
return Promise.reject(err)
}
}
}
}
weex研究
weex playground
https://mp.weixin.qq.com/s/K6wXSGPywc7Ltm0T3lz-Sg
本地web调试
本地模拟器调试
真机调试
JavaScript
weex-vue-render
js service
比如iPhoneX尺寸兼容
比如下拉刷新
出现错误,如何自动降级或下线
背景:最近做一个商品库的项目时,需要一个实时搜索功能。当用户在输入框输入关键字时,实时根据关键字搜索结果。
问题:使用lodash.debounce时,特别是输入汉字时,当用户删除输入的内容时,删除的体验上不是很流畅,有点硌得慌。后续附上一个code demo。
解决方案:使用自己实现的debounce完美解决。
分析:lodash的debounce和自己实现的debounce到底有什么区别?
Hook、钩子,一种**或者说是设计模式,有很多应用。比如Wordpress的hook、sequenlize中hook的应用、React Hooks等。
https://webpack.js.org/contribute/debugging#devtools
https://nodejs.org/en/docs/guides/debugging-getting-started/
https://medium.com/@paul_irish/debugging-node-js-nightlies-with-chrome-devtools-7c4a1b95ae27
https://medium.com/webpack/webpack-bits-learn-and-debug-webpack-with-chrome-dev-tools-da1c5b19554
本文我们用Node来讨论文件上传与下载的问题。
利用Node中提供的各种库来谈谈文件上传与下载
node 8.4.0 下以下代码报错, 最后查找说不支持lookbehind, node 8.11.1 是ok的。
name.replace(/(?<=[a-z]+)(?=[A-Z]+)/g, '_')
下面就深入研究下这些高级的正则用法
http://blog.stevenlevithan.com/archives/mimic-lookbehind-javascript
redis的?
require的?
...
pid, net, ipc, mnt, uts,user
veth
类似chroot
一次团队分享中讨论的话题点,在此备忘。
作为程序员,更准确地说,我们用程序员地身份做着码农的事情。我们只是技术的使用者和搬运工。
作为软件开发工程师,我们只是在用前端开发或PHP工程师的一维角度去做着自己该做的事情,没有软件和软件开发的全局观
作为一个程序员,我们只是把技术作为纯粹的工具做事情。而我们却说,我们技术很厉害,我很精通JS、PHP、JAVA等。
作为前端开发人员,本身对业务,即对自己所做的事情本身不是很熟悉,对自己使用到的技术也只是使用。最后技术和业务两空空。
作为工程实践人员,我们也要有些学术型思维,去了解去研究技术本身,提升自己的深度。学术与工程不冲突。
今天分享下你所不知道的git
很多场景中我们都需要标记一条数据的唯一性,我们把标记这条数据的唯一性的标记称为uniqId,这个uniqId也可称为key。
如何保证uniqId的唯一性?
本文以软件开发工程师和Node角度来看,我们应该了解哪些知识?
Linux
Git
HTTP:Cookie
MVC:设计模式
模块规范:AMD/CMD/UMD/ module 、namespace
中间件**
Nginx:web服务器,静态资源访问和反向代理、负载均衡
redis/memcache:缓存
MySql/MongoDB: 数据存储
elasticSearch:全文检索
Kafka/MQ:消息队列
Devops
SRE
Docker
k8s
安全:基本的漏洞、安全产品、安全开发、安全运维
开始之前,先说下为什么会研究这个问题?
在分析别人的node代码,比如express、koa等时,发现了两种不同定义路由方法或者我们称之为action的方案。
function MyController() {
}
MyController.doAction = function() {
}
class MyController {
doAction() {
}
}
const ctrl = new MyController()
两种方案都在实际生产中有实践。要分析两种方案的优劣和区别,得先了解class方案实际上是怎么实现的。
然后从内存、性能、写法等多方面可以考量。
本文不讨论何种方案优劣,只作为本篇文章的引子!
研究路径:
定义一个类->定义一个类的方法->定义一个类的静态方法->定义一个类的属性->定义一个类的静态属性->私有属性的实现(不讨论)->私有方法的实现(不讨论)->继承一个类。
class MyClass {
}
"use strict";
function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }
var MyClass = function MyClass() {
_classCallCheck(this, MyClass);
};
定义一个类,实际上定义了一个函数,只是比普通函数多了一个实例检查,判断该实例是否是通过构造函数创建的。一般我们创建一个类的实例使用new MyClass()关键字。
定义一个doAction方法
class MyClass {
doAction() {
console.log('do something...');
}
}
"use strict";
var _createClass = function() {
function defineProperties(target, props) {
for (var i = 0; i < props.length; i++) {
var descriptor = props[i];
descriptor.enumerable = descriptor.enumerable || false; // 是否可枚举,如for ... in , Object.keys
descriptor.configurable = true; // 是否可配置
if ("value" in descriptor) descriptor.writable = true; // 是否可修改
Object.defineProperty(target, descriptor.key, descriptor); // 通过defineProperty定义类的方法
}
}
return function(Constructor, protoProps, staticProps) {
if (protoProps) defineProperties(Constructor.prototype, protoProps); // 原型属性定义
if (staticProps) defineProperties(Constructor, staticProps); // 静态属性定义,下面再讨论。
return Constructor;
};
} ();
function _classCallCheck(instance, Constructor) {
if (! (instance instanceof Constructor)) {
throw new TypeError("Cannot call a class as a function");
}
}
var MyClass = function() { // 类通过一个立即执行函数包裹并返回
function MyClass() { // 定义构造函数,并验证实例是否正确。
_classCallCheck(this, MyClass);
}
_createClass(MyClass, [{ // 通过_createClass方法定义类的方法
key: "doAction",
value: function doAction() {
console.log('do something...');
}
}]);
return MyClass;
} ();
configurable: 为true时,a.可删除该属性; b. 可配置除描述符的writable属性之外的属性,如enumerable、get、set、value等
writable:为true时,才可通过赋值改变定义属性的值,否则只读
enumerable:当为true时,才可通过for ... in ,Object.keys获取到定义的属性。
get\set,当读取一个属性或给一个属性赋值时,get/set会自动执行。很多现代js框架数据和dom绑定的核心原理。
class MyClass {
doAction() {
console.log('do something...');
}
// 静态方法
static doStaticAction() {
console.log('do something static');
}
}
'use strict';
var _createClass = function() {
function defineProperties(target, props) {
for (var i = 0; i < props.length; i++) {
var descriptor = props[i];
descriptor.enumerable = descriptor.enumerable || false;
descriptor.configurable = true;
if ("value" in descriptor) descriptor.writable = true;
Object.defineProperty(target, descriptor.key, descriptor);
}
}
return function(Constructor, protoProps, staticProps) {
if (protoProps) defineProperties(Constructor.prototype, protoProps);
if (staticProps) defineProperties(Constructor, staticProps); // here
return Constructor;
};
} ();
function _classCallCheck(instance, Constructor) {
if (! (instance instanceof Constructor)) {
throw new TypeError("Cannot call a class as a function");
}
}
var MyClass = function() {
function MyClass() {
_classCallCheck(this, MyClass);
}
_createClass(MyClass, [{
key: 'doAction',
value: function doAction() {
console.log('do something...');
}
}], [{
key: 'doStaticAction', // here,_createClass的第三个参数
value: function doStaticAction() {
console.log('do something static');
}
}]);
return MyClass;
} ();
我们可以在_createClass函数中发现:
if (protoProps) defineProperties(Constructor.prototype, protoProps);
if (staticProps) defineProperties(Constructor, staticProps); // here
普通方法和静态方法唯一的区别在于:方法是定一个在了构造函数的原型上还是构造函数本身。
我们知道。我们调用一个类的普通方法时,我们需要实例化。而调用静态方法时,可直接用类名直接引用调用。如MyClass.doStaticAction()
class MyClass {
prop = 1; // 定义一个实例属性
static staticProp = 2; // 定义一个静态属性
doAction() {
console.log('do something...');
}
static doStaticAction() {
console.log('do something static');
}
}
'use strict';
var _createClass = function() {
function defineProperties(target, props) {
for (var i = 0; i < props.length; i++) {
var descriptor = props[i];
descriptor.enumerable = descriptor.enumerable || false;
descriptor.configurable = true;
if ("value" in descriptor) descriptor.writable = true;
Object.defineProperty(target, descriptor.key, descriptor);
}
}
return function(Constructor, protoProps, staticProps) {
if (protoProps) defineProperties(Constructor.prototype, protoProps);
if (staticProps) defineProperties(Constructor, staticProps);
return Constructor;
};
} ();
function _classCallCheck(instance, Constructor) {
if (! (instance instanceof Constructor)) {
throw new TypeError("Cannot call a class as a function");
}
}
var MyClass = function() {
function MyClass() {
_classCallCheck(this, MyClass);
this.prop = 1; // 定义的实例属性
}
_createClass(MyClass, [{
key: 'doAction',
value: function doAction() {
console.log('do something...');
}
}], [{
key: 'doStaticAction',
value: function doStaticAction() {
console.log('do something static');
}
}]);
return MyClass;
} ();
MyClass.staticProp = 2; // 定义的静态属性
是不是发现了什么不一样的东东。
为什么方法和静态方法通过Object.defineProperty定义的,而属性和静态属性不一样了?
为什么没有把prop属性定义到构造函数的prototype上?
为什么没有通过Object.defineProperty将staticProp定义到构造函数constructor上?
如果采用和定义方法同样的方法Object.deifneProperty定义属性和静态属性会发生什么?
要解答这些问题,其实我们可以从《Javascript权威指南》中找到答案:
Javascript类相关的对象有三个:
构造函数对象:如在引文中提到的MyController.doAction,定义在构造函数对象中的属性都是类字段和类方法。即定义在了Constructor上。
原型对象:原型对象上的属性被类的所有实例所共享,Object.defineProperty(Constructor.prototype, doAction),即定义在了prototype上。
实例对象: 在实例对象上的属性只在实例上生效,如其中的属性MyClass中的prop,不会为所有实例所共享,即定义在了this上。
理解了上面三个对象,上面的问题自然迎刃而解。
class MyClass {
prop = 1;
static staticProp = 2;
doAction() {
console.log('do something...');
}
static doStaticAction() {
console.log('do something static');
}
}
class MyChildClass extends MyClass {
}
'use strict';
var _createClass = function() {
function defineProperties(target, props) {
for (var i = 0; i < props.length; i++) {
var descriptor = props[i];
descriptor.enumerable = descriptor.enumerable || false;
descriptor.configurable = true;
if ("value" in descriptor) descriptor.writable = true;
Object.defineProperty(target, descriptor.key, descriptor);
}
}
return function(Constructor, protoProps, staticProps) {
if (protoProps) defineProperties(Constructor.prototype, protoProps);
if (staticProps) defineProperties(Constructor, staticProps);
return Constructor;
};
} ();
function _possibleConstructorReturn(self, call) {
if (!self) {
throw new ReferenceError("this hasn't been initialised - super() hasn't been called");
}
return call && (typeof call === "object" || typeof call === "function") ? call: self;
}
function _inherits(subClass, superClass) {
if (typeof superClass !== "function" && superClass !== null) {
throw new TypeError("Super expression must either be null or a function, not " + typeof superClass);
}
subClass.prototype = Object.create(superClass && superClass.prototype, {
constructor: {
value: subClass,
enumerable: false,
writable: true,
configurable: true
}
});
if (superClass) Object.setPrototypeOf ? Object.setPrototypeOf(subClass, superClass) : subClass.__proto__ = superClass;
}
function _classCallCheck(instance, Constructor) {
if (! (instance instanceof Constructor)) {
throw new TypeError("Cannot call a class as a function");
}
}
var MyClass = function() {
function MyClass() {
_classCallCheck(this, MyClass);
this.prop = 1;
}
_createClass(MyClass, [{
key: 'doAction',
value: function doAction() {
console.log('do something...');
}
}], [{
key: 'doStaticAction',
value: function doStaticAction() {
console.log('do something static');
}
}]);
return MyClass;
} ();
MyClass.staticProp = 2;
var MyChildClass = function(_MyClass) {
_inherits(MyChildClass, _MyClass); // 调用_inherits实现继承
function MyChildClass() {
_classCallCheck(this, MyChildClass);
return _possibleConstructorReturn(this, (MyChildClass.__proto__ || Object.getPrototypeOf(MyChildClass)).apply(this, arguments)); // 构造函数比父类MyClass多了一个返回
}
return MyChildClass;
} (MyClass);
从上面可以看到,引入了继承,一切看起来不再那么简单。
不过总体来说,子类继承父类做了两个工作:
下面主要研究这两个函数具体是怎么做的?
当然还有一个很明显的问题,为什么父类在构造函数里不需要返回,而子类构造函数需要返回?
下面逐一分析。
说到这里,可能还是不太明白?
为了彻底搞明白继承这个事情,我们必须先了解下面几个问题:
这些我们可以另开文章注意研究讨论。
其实这个问题我们还可以继续讨论,如:
如果给子类添加新的属性或新的方法,是如何编译的?
如果有一个孙子类继承子类,又是如何编译,和父类MyClass的关系又如何?
上面我们可以说基本上都是以研究的思路一点一点逐步加深的思路去做的?
我会在另一篇文章里以总结的思路去重新梳理这篇文章?
比如:
.
├── app.js // 各种中间件和bootstrap,路由的聚合也在这个文件里,只有一级路由
├── controllers // controllers
│ └── messages.js
├── package.json
├── public // 静态文件
│ ├── scripts
│ └── styles
│ └── main.css
├── test // unittest
│ └── routeSpec.js
└── views template
├── layout.html
└── list.html
.
├── app.js 各种中间件以及路由中间件入口 bootstrap
├── config 各类环境的配置信息
│ ├── config.js
│ └── local.js
├── controller
│ └── index.js
├── log
├── model
├── package.json
├── public
│ ├── css
│ └── js
├── router // 具体路由映射controller
│ └── index.js
├── test
│ └── index-router-spec.js
└── view 模板
├── index.xtpl
└── layout
├── footer.xtpl
├── header.xtpl
└── layout.xtpl
.
├── LICENSE
├── README.md
├── knexfile.js 数据库配置信息
├── package.json
├── src
│ └── server
│ ├── auth.js 用户登录认证
│ ├── db
│ │ ├── connection.js // 创建数据库连接
│ │ ├── migrations // 数据表设计
│ │ │ ├── 20170817152841_movies.js
│ │ │ └── 20171231115201_users.js
│ │ ├── queries // 数据库DAO
│ │ │ ├── movies.js
│ │ │ └── users.js
│ │ └── seeds
│ │ ├── movies_seed.js
│ │ └── users.js
│ ├── index.js // app路由、中间件、启动
│ ├── routes // 不同模块的路由文件
│ │ ├── _helpers.js
│ │ ├── auth.js
│ │ ├── index.js
│ │ └── movies.js
│ ├── session.js session redis存储
│ └── views 模板
│ ├── admin.html
│ ├── login.html
│ ├── register.html
│ └── status.html
└── test
├── integration
│ ├── routes.auth.stub.test.js
│ ├── routes.auth.test.js
│ ├── routes.index.test.js
│ └── routes.movies.test.js
└── unit
└── sample.test.js
> https://github.com/eggjs/examples/tree/master/sequelize
├── README.md
├── README.zh-CN.md
├── app
│ ├── controller controller
│ │ ├── post.js action
│ │ └── user.js
│ ├── extend // 扩展
│ │ └── helper.js
│ ├── model // 数据表定义与DAO
│ │ ├── post.js
│ │ └── user.js
│ ├── router.js // 路由聚合
│ └── service // 服务层,调用model的DAO完成业务层逻辑
│ ├── post.js
│ └── user.js
├── config // 配置信息
│ ├── config.default.js
│ ├── config.unittest.js
│ └── plugin.js
├── database // 数据库配置信息
│ ├── config.json
│ └── migrations
│ ├── 20180813112934-user.js
│ └── 20180813112942-post.js
├── package.json
└── test
├── app
│ ├── controller
│ │ ├── post.test.js
│ │ └── user.test.js
│ └── service
│ └── post.test.js
└── factories.js
.
├── LICENSE
├── README.md
├── app
│ └── README.md
├── app.js
├── conf
│ ├── plugins
│ │ ├── dispatcher.js
│ │ ├── http.js
│ │ ├── log.js
│ │ ├── ral.js
│ │ ├── recv-reload.default.js
│ │ ├── reqlimit.js
│ │ └── views.js
│ └── ral
│ └── demo.js
├── home
│ ├── client
│ │ ├── page
│ │ │ ├── index.tpl
│ │ │ └── layout.tpl
│ │ ├── static
│ │ │ └── js
│ │ │ ├── README.md
│ │ │ ├── bigpipe.js
│ │ │ ├── index.js
│ │ │ ├── lazyload.js
│ │ │ ├── mod.js
│ │ │ └── page.js
│ │ └── widget
│ │ └── message
│ │ └── message.tpl
│ ├── fis-conf.js
│ ├── package.json
│ └── server
│ ├── action
│ │ ├── book.js
│ │ └── index.js
│ ├── lib
│ │ └── util.js
│ ├── model
│ │ └── index.js
│ └── router.js
├── package.json
├── plugins
│ └── README.md
├── static
└── views
比如图书系统中,book表,应该直接用自增id作为book记录的唯一id还是设计一个book_id字段用于表示book记录的唯一性?
比如订单表,order表中,order_id字段的设计?
使用自增主键是否总是最佳实践?
比如老师和学生,其之间的关联关系设计有以下两种方法:
比如供应商、店铺、商品,供应商可以将商品供应给多家店铺,多家店铺售卖多个商品,我们表字段应该如何设计?
使用where id in [1, 2] 还是 使用where id = 1 or id =2
数据库 timezone的处理以及engine/ORM对timezone的处理
在NodeJS使用sequelize时,sequelize设置时区为+8:00,存储数据为当前时间,没有问题。
当使用sequelize查询结果时,查询的结果早了8小时。
一个字段:比如用status表示审核通过或失败,通过后,如果启用status变为启用
两个字段:用status表示审核状态,用active表示是否生效
索引根据查询字段组合设计
数据表里有name,title,description字段,根据一个关键字query 做or查询,这个需要建索引吗?建单列索引还是联合索引? select * from table where name like '%a%' or title like '%a' or description like '%a';
最左原则
窗口、viewport尺寸、DOM尺寸、事件位置等
CMS工厂
登录SDK
H5工厂
H5调用Native能力的JS SDK
H5离线客户端缓存
Bigpipe
SSR
该部分均为平台性质的,且平台具有开放性
A declarative, efficient, and flexible JavaScript library for building user interfaces.
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
An Open Source Machine Learning Framework for Everyone
The Web framework for perfectionists with deadlines.
A PHP framework for web artisans
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
Some thing interesting about web. New door for the world.
A server is a program made to process requests and deliver data to clients.
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
Some thing interesting about visualization, use data art
Some thing interesting about game, make everyone happy.
We are working to build community through open source technology. NB: members must have two-factor auth.
Open source projects and samples from Microsoft.
Google ❤️ Open Source for everyone.
Alibaba Open Source for everyone
Data-Driven Documents codes.
China tencent open source team.