Giter VIP home page Giter VIP logo

blogs's Introduction

Hi there 👋

blogs's People

Contributors

clumsyme avatar

Stargazers

 avatar

Watchers

 avatar  avatar

blogs's Issues

中文字符串排序

// 字符串原型比较方法
a.localeCompare(b, 'zh-Hans-CN')

// 字符串数组排序
sa.sort((a, b) => a.localeCompare(b, 'zh-Hans-CN'))
// 或者比较属性
sa.sort((a, b) => a.name.localeCompare(b.name, 'zh-Hans-CN'))

// 大量数据使用Intl.Collator对象
var ic = new Intl.Collator('zh-Hans-CN')
sa.sort(ic.compare)
// 或者比较属性
sa.sort((a, b) => ic.compare(a.name, b.name))

String.prototype.localeCompare()

state 与 props

stateprops的改变都可引起组件的render

如果在接收到数据后还要对数据进行处理,则使用state管理数据可知道什么时候数据改变以更改状态,可减少数据处理代码的运行。

使用props直接在render中处理数据可保证数据改变时直接反映在组件内,cmd、cwm等周期函数则不行,数据处理函数在数据不改变的情况下作了无用处理,一个方法是在cwrp周期函数检查props,在属性变化时再处理数据。

最好是在数据改变的地方处理数据,作为props传递给子组件。如原始数据在redux处直接处理,传递给子组件,就减少了不必要的数据处理。

JavaScript迭代协议

// this is like __iter__ method in python
class MyIter {
    constructor(limit) {
        this.now = 0
        this.limit = limit
        this[Symbol.iterator] = () => ({
            next: () => {
                if (this.now < this.limit) {
                    this.now += 1
                    return { value: this.now**2, done: false }
                } else {
                    return { done: true }
                }
            }
        })
    }
}

let mi = new MyIter(5)

[...mi] // [1, 4, 9, 16, 25]

// Then again
[...mi] // []

let nmi = new MyIter(3)

for (let i of nmi) {
    console.log(i)
}
// 1
// 4
// 9

OR LIKE THIS

class MyIter {
    constructor(limit) {
        this.now = 0
        this.limit = limit
    }
    [Symbol.iterator]() {
        return {
            next: () => {
                if (this.now < this.limit) {
                    this.now += 1
                    return { value: this.now ** 2, done: false }
                } else {
                    return { done: true }
                }
            }
        }
    }
}

react 前后属性对比

子组件在运行componentWillReceiveProps函数时,若属性值是可变类型(JS对象,如数组),修改只是对原对象的修改,则this.propsnextProps将指向同一个对象。

典型的,

class Parent extends Component {
    state = {
        i: 0,
        nums: []
    }
    onClick = () => {
        let { nums, i } = this.state
        nums.push(i++)
        this.setState({ nums, i })
    }
    render() {
        return (
            <div>
                <button onClick={this.onClick}>{this.state.i}</button>
                <Child nums={this.state.nums} />
            </div>
        )
    }
}

Child组件每次在nums属性变化时,this.propsnextProps都指向同一个对象this.stat.nums。如何实现对比?

1

this.props缓存,如

componentWillReceiveProps(nextProps) {
    if (nextProps.nums.length !== this.state.nums.length) {
        this.setState({
            nums: JSON.parse(JSON.stringify(nextProps.nums))
        })
        // 已对比出变化,可执行自己的代码
    }
}

该方法可不依赖父级组件的代码,即使父组件每次传递过来的都是同一个对象也没关系。
但属性传递逻辑较复杂。

2

在父组件内设置状态时,避免新旧状态指向同一对象:

2.1

使用immutable

2.2

手动解决:

onClick = () => {
    let { nums, i } = this.state
    nums.push(i++)
    nums = JSON.parse(JSON.stringify(nums))
    this.setState({ nums, i })
}

flex

一个指定了flex属性的容器,在其子元素尺寸过大时会撑大该容器,即使指定其flex: 0 0

这样的话,就会使容器及其各父元素内容overflow

而值得注意的是,如果指定了容器的width,则只需设置可能过大的子元素的overflow即可避免父元素overflow,而单指定flex-basis不会产生width效果,也就是即使指定过大子元素的overflow,父元素仍然overflow

因此如果只想让子元素overflow: auto,即子元素过大时自己滚动,不会导致父元素被撑大,首先设置子元素overflow: auto,然后:

  • 设置容器overflow: hidden
  • 或指定容器的width。(若希望子元素未指定overflow属性时不被hidden时用这个)

commonjs 循环 import

commonjs 在 require 时会先执行引入的模块,所以循环引用时:被引入文件再引入原文件的时候,只引入了 require 语句之前那部分。

// a.js
let { b } = require('./b')

let a = 'a'
exports.a = a

console.log('in a:', a, b)
setTimeout(() => {
    console.log('in a timeout:', a, b)
})

//b.js
let { a } = require('./a')

let b = 'b'
exports.b = b

console.log('in b:', a, b)
setTimeout(() => {
    console.log('in b timeout:', a, b)
})
node a

输出:

in b: undefined b
in a: a b
in b timeout: undefined b
in a timeout: a b

直接 require 变量,在该模块内,该变量不会变,类似闭包。

但是 require 整个包的话,包可以作为引用:

// a.js
let moduleB = require('./b')

let a = 'a'
exports.a = a

console.log('in a:', a, moduleB.b)
setTimeout(() => {
    console.log('in a timeout:', a, moduleB.b)
})

// b.js 
let moduleA = require('./a')

let b = 'b'
exports.b = b

console.log('in b:', moduleA.a, b)
setTimeout(() => {
    console.log('in b timeout:', moduleA.a, b)
})

node a 输出:

in b: undefined b
in a: a b
- in b timeout: undefined b
+ in b timeout: a b
in a timeout: a b

容器组件还是展示组件?

写React App时,用Dan Abramov介绍的模式将组件分为容器组件展示组件确实更利于理解app逻辑,但是有时候写组建的时候难免会纠结一个组件是写作容器组件还是写作展示组件。

写作容器组件的话,可能这个组件只是一个容器组件的子组件,从父组件直接获取props可能更简单,而如果该组件写作容器组件,该组件的子元素同样面临这个问题,一级一级往下究竟到哪一步可以写作展示组件呢?;

写作展示组件的话(通常推荐用函数构建,所以没有周期函数,没有内部状态),组件自身也可能有状态,也有可能有各种回调,可能会改变父组件状态,也有可能发送http请求等。

结合一直以来的经验,总结几点选择依据:

  1. 如果组件只接收数据用于展示,选择展示组件。
  2. 如果组件需要多次使用,选择展示组件。
  3. 如果组件只用到一次(视为模块),写作容器组件。
  4. 如果子组件只是涉及自身状态或父组件状态更改,选择展示组件。
  5. 如果父组件状态多而复杂,则子组件按不同功能写作不同容器组件。

以上只是一些参考依据,实际中可能不完全对。而且应该要明白:编程模式是用来方便我们编写程序的,而不是束缚手脚让我们的代码来适应模式的。容器组件和展示组件都可能有容器子组件和展示子组件,它们的界限也不是那么明确,所以不一定要在一开始就确定好一个组件是哪种类型;如果一开始分不出用哪种类型,大可暂时不管这个问题。

无语的 falsy 值及相等操作符

问题引出:[]等于false

JavaScript中视为false的有false, null, undefined, 0, "", NaN

那么,看下边的表达式:

[] == false
//  true

if ([]) {
    console.log('啦啦啦')
}
// 啦啦啦

额?[]不是等于false么?
而且,再看这里:

![] == false
// true

=_=!

究竟相等不相等?

不过这不是bug,而是由于JavaScript语言对==的处理方式引起的。

JavaScript相等性判断

  1. ==

  2. ===

  3. Object.is

先说后两个:

全等操作符===

全等操作符比较两个值是否相等,两个被比较的值在比较前都不进行隐式转换。如果两个被比较的值具有不同的类型,这两个值是不全等的。否则,如果两个被比较的值类型相同,值也相同,并且都不是 number 类型时,两个值全等。最后,如果两个值都是 number 类型,当两个都不是 NaN,并且数值相同,或是两个值分别为 +0 和 -0 时,两个值被认为是全等的。

在日常中使用全等操作符几乎总是正确的选择。对于除了数值之外的值,全等操作符使用明确的语义进行比较:一个值只与自身全等。对于数值,全等操作符使用略加修改的语义来处理两个特殊情况:第一个情况是,浮点数 0 是不分正负的。区分 +0 和 -0 在解决一些特定的数学问题时是必要的,但是大部分境况下我们并不用关心。全等操作符认为这两个值是全等的。第二个情况是,浮点数包含了 NaN 值,用来表示某些定义不明确的数学问题的解,例如:正无穷加负无穷。全等操作符认为 NaN 与其他任何值都不全等,包括它自己。(等式 (x !== x) 成立的唯一情况是 x 的值为 NaN)

Object.is()

Object.is 在三等号判等的基础上特别处理了 NaN 、 -0 和 +0 ,保证 -0 和 +0 不再相同,但 Object.is(NaN, NaN) 会返回 true。

非严格相等==

与全等操作符不同的是,非严格相等操作符在比较两个值A == B的时候,如果两者类型不同,会先进行类型转换,转换为同一类型后再进行比较。具体的转换规则如下:

Undefined Null Number String Boolean Object
Undefined true true false false false IsFalsy(B)
Null true true false false false IsFalsy(B)
Number false false A === B A === ToNumber(B) A=== ToNumber(B) A=== ToPrimitive(B)
String false false ToNumber(A) === B A === B ToNumber(A) === ToNumber(B) ToPrimitive(B) == A
Boolean false false ToNumber(A) === B ToNumber(A) === ToNumber(B) A === B false
Object false false ToPrimitive(A) == B ToPrimitive(A) == B ToPrimitive(A) == ToNumber(B) A === B

ToNumber(A) 尝试在比较前将参数 A 转换为数字,这与 +A(单目运算符+)的效果相同。通过尝试依次调用 A 的A.toString 和 A.valueOf 方法,将参数 A 转换为原始值(Primitive)。

第一列为被比较值A的类型,第一排为被比较值B的类型。

关于[] == false

如此我们看[] == false[]Object类型,falseBoolean类型,所以真正的比较表达式是:

ToPrimitive([]) == ToNumber(false)

ToPrimitive([])通过调用[].toString()得到空字符串""ToNumber(false)false转换为数字0,因此:

"" == 0

然后是字符串与数字进行非严格相等比较,又进行了类型转换:

ToNumber("") === 0

也就是:

0 === 0

因此返回true

所以,[] == false表达式的值为true,但空数组最想本身[]是不被视为false

关于![] == false

逻辑非操作符!的优先级(15)高于等号操作符优先级(10),因此在比较前先进行的是![],结果是false,因此实际比较是:

false == false

因此返回true

不是bug的bug

Explicit is better than implicit.

Readability counts.

好的代码应该是清晰明了、可读性好的,语言最好也是。而在一个相等操作符==上,JavaScript进行了如此多的内部操作,不仅新手容易迷惑,就连有经验的程序员也可能一时搞不明白一个表达式到底出了什么问题。因此也有了如下观点:

最好永远都不要使用相等操作符。全等操作符的结果更容易预测,并且因为没有隐式转换,全等比较的操作会更快。

参考:

CSS backdrop-filter

backdrop-filter属性可以很方便的实现毛玻璃效果,其作用是将其值作用于在该元素后边的元素上。

.cover {
    backdrop-filter: blur(5px);
}

如此就可以使.cover具有了毛玻璃效果。


在Safari使用设置position为sticky失败

<div style={{position: this.state.collapsed ? 'static' : 'sticky'}}></div>

不管state如何,上述div从来没有定位为sticky,其它定位可以,原生js设置CSS position属性也不能设置为sticky,应该是Safari的问题。

Chrome, FireFox正常

CSS rgba 与 opacity 的区别

rgbaaAlpha 合成,可以产生部分透明或全透明的视觉效果。

opacity 为透明度。

用法与区别:

rgba:作用于一个元素,应用于colorbackgroundColorborderColor 等属性

下图文字没有透明度
rgba

opacity: 作用于整个元素及其子元素

下图文字也有透明度
opacity

CSS @supports

语法:

@supports <supports_condition> {
      /* specific rules */
}

supports_conditiontrue时应用specific rules

@support (--css-variables: 1) {
    .test {
        --main-color: lime
    }
}

上例在浏览器支持--css-variables: 1这样的CSS样式格式时,test类会应用--main-color: lime这一条样式规则。

支持逻辑操作符

  • and
@support((--a: 1) and (dispaly: flex)) {
    .test {
        --flex: flex;
        dispaly: var(--flex)
    }
}
  • or
@support((display: flex) and (dispaly: grid)) {
    .test {
       /* lalala */
    }
}
  • not
@support(not (--a: 1) ) {
    .test {
        /* lalala */
    }
}
  • 组合
@support(not ((--a: 1) and (display: grid))) {
    .test {
        /* lalala */
    }
}

margin 负值

  • width属性的元素,margin-leftmargin-right为负值会移动元素,

  • 没有width属性的元素,margin-leftmargin-right为负值增加元素宽度,

  • margin-top为负值会向上移动元素

  • margin-bottom为负值会向上移动下边的元素

函子

函子(Functor)

haskell 内的 Functor 定义:

class Functor f where 
   fmap :: (a -> b) -> f a -> f b 

简单来说,Functor 就是一个定义了 fmap 方法的对象,它可以被作为 map 函数的参数。

map 接收一个 a -> b 类型的函数和一个函子 f a,返回一个新的函子 f b 类型的函数。

function plusOne(x) {
    return x + 1
}

plusOne([3]) // ! wrong
R.map(plusOne, [3]) // [4]

// ---> [3] -> [plsuOne(3)]

R.map(plusOne, MyObject(1)) // MyObject(plusOne(1))
//=> MyObject(2)

R.map(function(x) { return 'I am ' + x}, MyObject("Yo")) // MyObject("I am Yo")
R.map(function(x) { return x.id}, MyObject({id: 2718})) // MyObject(2718)

// map 方法就像是打开 MyObject,对 MyObject 内的值进行操作,再关闭 MyObject

class MyObject {
    constructor(value) {
        this.__value = value
    }

    map(func) {
        return new MyObject(func(this.__value))
    }
}

// 我们通过对 MyObject 定义 map, MyObject 可以看做一个 Functor

// some use of Functor
// type safe
class Maybe {
    constructor(value) {
        this.__value = value
    }

    map(func) {
        return this.__value ? new Maybe(func(this.__value)) : new Maybe(null)
    }
}

R.map(plusOne, new Maybe(1)) // Maybe(2)
R.map(plusOne, new Maybe(null) // Maybe(null)

// 对于 Functor,我们需要调用 map 方法来修改它的值,而不能直接修改它的值。
//! 动态的类型安全

// default value
class Either {
    // left as default
    constructor(left, right) {
        this.__left = left
        this.__right = right
    }

    map(func) {
        return this.right 
            ? new Either(this.__left, func(this.__right)) 
            : new Either(func(this.__left), this.__right)
    }
}

R.map(plusOne, new Either(1, 2)) // Either(1, 3)
R.map(plusOne, new Either(1, null)) // Either(2, null)

// auto handle Promise
Promise.prototype.map = function(func) {
    let thisPromise = this
    return this.then(function(response) {
        return func(response)
    })
}

function handleResponse(response) {
    return response.json().then(json => {
        // doSthWithJson
        return 'done'
    })
}

let mapped = R.map(handleResponse, fetch('/someAPI'))

await mapped // 'done'


// DEMO
// we have a side effect
let setProp = function (prop, value, obj) {
  obj[prop] = value
  return obj
}.autoCurry()

let title = document.getElementById('title')
// getGreeting :: User -> String
let getGreeting = compose(R.concat("Welcome "), R.prop("name"))
// updateGreetingHtml :: User -> undefined
let updateGreetingHtml = compose(setProp('textContent', R.__, title), getGreeting)

updateGreetingHtml(currentUser)

// what if we dont have a currentuser
map(updateGreetingHtml, Either({name: 'Guest'}, currentUser))

// 使用 Functor,你不能直接操作 Functor 的值,在程序其他地方必须使用 map(包括 filter) 来进行操作,
// 你不必关心其内部结构,只用知道他可以被 map

react root

function App() {
    return (
        <div>
            <h1>0</h1>
            <button>Click</button>
        </div>
    )
}
stateDiagram
    FiberRootNode: ReactDom.createRoot 生成

    HostRootFiber: typeof:FiberNode
    HostRootFiber: tag:HostRoot
    HostRootFiber: return:null


    container: 渲染 Dom 节点,#root

    FiberRootNode --> HostRootFiber: current
    HostRootFiber --> FiberRootNode: stateNode

    container --> HostRootFiber: __reactContainere$random
    FiberRootNode --> container: containerInfo

    HostRootFiber --> App: child
    App --> HostRootFiber: return

    App --> div: child
    div --> App: return

    div --> h1: child
    h1 --> div: return
    h1 --> button: sibling

    button --> div: return

    FiberRootNode --> HostRootFiber:alter: Nextcurrent

    HostRootFiber:alter --> App:alter: child
    App:alter --> HostRootFiber:alter: return

    App:alter --> div:alter: child
    div:alter --> App:alter: return

    div:alter --> h1:alter: child
    h1:alter --> div:alter: return
    h1:alter --> button:alter: sibling

    button:alter --> div:alter: return

React Hooks 的链表结构

React Hooks 如何知道每次渲染对应正确的 hooks?

React Hooks的结构是一个链表:
每一个 Hooks 对象结构为:

{
    memoizedState: null,
    queue: null,
    next: null,
}

有一个链表的头部,在 React 内部称为 firstWorkInProgressHook,保存着组件内所有的 Hooks。

还有一个链表,workInProgressHook,对应的是上述链表的一个节点,在组件内部就是调用useMyHook() 的时候的当前的 Hooks。每一次我们调用useMyHook(),React 内部会调用一个方法来生成一个 workInProgressHook,其源代码为(React-Dom/server的版本,与 ReactFiberHooks 也就是客户端版本的原理是一致的):

function createWorkInProgressHook(): Hook {
  if (workInProgressHook === null) {
    // This is the first hook in the list
    if (firstWorkInProgressHook === null) {
      isReRender = false;
      firstWorkInProgressHook = workInProgressHook = createHook();
    } else {
      // There's already a work-in-progress. Reuse it.
      isReRender = true;
      workInProgressHook = firstWorkInProgressHook;
    }
  } else {
    if (workInProgressHook.next === null) {
      isReRender = false;
      // Append to the end of the list
      workInProgressHook = workInProgressHook.next = createHook();
    } else {
      // There's already a work-in-progress. Reuse it.
      isReRender = true;
      workInProgressHook = workInProgressHook.next;
    }
  }
  return workInProgressHook;
}

我们以组件的两次 render 来介绍该链表是如何初始化以及如何应对更新的:

  • 初始条件下(组件还未渲染),firstWorkInProgressHookworkInProgressHook 都是 null 0️⃣
  • 初次渲染:
    • 第一个 Hooks:firstWorkInProgressHook = workInProgressHook = createHook() 1️⃣
    • 第二个 Hooks:workInProgressHook = workInProgressHook.next = createHook() 2️⃣
    • ...
    • 第 n 个 Hooks: workInProgressHook = workInProgressHook.next = createHook() 3️⃣
    • 渲染结束,React 调用 finishHooks,重置 workInProgressHooknull 4️⃣
0️⃣:
// firstWorkInProgressHook = workInProgressHook = null
firstWorkInProgressHook
                        
                          null
                        
     workInProgressHook

1️⃣:
// workInProgressHook = workInProgressHook.next = createHook()
          firstWorkInProgressHook
                                 
                          null    Hook1
                                 
              workInProgressHook

2️⃣:
// workInProgressHook = workInProgressHook.next = createHook()
          firstWorkInProgressHook
                                 
                           null   Hook1 ⟶️ Hook2
                                           
                         workInProgressHook
3️⃣:
// workInProgressHook = workInProgressHook.next = createHook()
          firstWorkInProgressHook
                                 
                           null   Hook1 ⟶️ Hook2 ...⟶️... HookN
                                                          
                                        workInProgressHook
4️⃣:
// workInProgressHook = null
          firstWorkInProgressHook
                                 
                           null   Hook1 ⟶️ Hook2 ...⟶️... HookN
                          
        workInProgressHook

下一次 render:

  • 开始前,链表状态和上次 render 结束一致 0️⃣
  • 第一个 Hooks:workInProgressHook = firstWorkInProgressHook1️⃣
  • 第二个 Hooks: workInProgressHook = workInProgressHook.next2️⃣
  • ...
  • 第 n 个 Hooks: workInProgressHook = workInProgressHook.next3️⃣
  • 渲染结束,React 调用 finishHooks,重置 workInProgressHooknull 4️⃣
0️⃣:
// firstWorkInProgressHook = Hook1
// workInProgressHook = null
          firstWorkInProgressHook
                                 
                           null   Hook1 ⟶️ Hook2 ...⟶️... HookN
                          
        workInProgressHook

1️⃣:
// workInProgressHook = firstWorkInProgressHook(Hook1)
          firstWorkInProgressHook
                                 
                           null   Hook1 ⟶️ Hook2 ...⟶️... HookN
                                 
               workInProgressHook

2️⃣:
// workInProgressHook = workInProgressHook.next(Hook2)
          firstWorkInProgressHook
                                 
                           null   Hook1 ⟶️ Hook2 ...⟶️... HookN
                                           
                         workInProgressHook
3️⃣:
// workInProgressHook = workInProgressHook.next(HookN)
          firstWorkInProgressHook
                                 
                           null   Hook1 ⟶️ Hook2 ...⟶️... HookN
                                                          
                                        workInProgressHook
4️⃣:
// workInProgressHook = null
          firstWorkInProgressHook
                                 
                           null   Hook1 ⟶️ Hook2 ...⟶️... HookN
                          
        workInProgressHook

所以:

  • 初次渲染的时候,Hooks 链表为空,每次 useMyHook() 的时候都会新建一个 Hooks 作为当前的 Hooks(workInProgressHook)
  • 再次渲染的时候,按照调用顺序,依次取上次生成的 Hooks 链表各个节点(每个节点就是一个 Hooks)

这也是为什么我们需要保证在每次渲染的时候各个 Hooks 以相同的顺序被调用。

计算值与应用值

Window.getComputedStyle() 方法给出应用活动样式表后的元素的所有CSS属性的值,并解析这些值可能包含的任何基本计算。

getComputedStyle 的返回值是 resolved values, 通常跟CSS2.1中的computed values是相同的值。 但对于一些旧的属性,比如width, height, padding 它们的值又为 used values。 最初, CSS2.0定义的计算值Computed values 就是属性的最终值。 但是CSS2.1 重新定义了 computed values 为布局前的值, used values布局后的值。布局前与布局后的区别是, width 或者 height的 百分比可以代表元素的宽度,在布局后,会被像素值替换.

计算值可能是百分数,根据实际布局才能决定数值(像素)。应用值为最终布局后的值,单位为像素。


关于fixed

<div id="out">
  <div id="in">
    <div id="mostin">
    </div>
  </div>
</div>

#out#in均有定位,#mostinfixed定位;
若设置#in最初transform: scale(0),后续因事件改变为transform: scale(1),则此时#mostin的定位将会是相对于#in而不是相对于屏幕

跨站请求携带 cookie

usecase

foo.com 页面内发送了一个 bar.com 的 GET 请求, 默认不会携带 cookie,如何解决呢?

  1. fetch请求允许携带认证信息
fetch('http://bar.com', {
    credentials: 'include',
})
  1. 服务器必须允许携带认证信息
Access-Control-Allow-Credentials: true
  1. 服务器必须指定允许的域名
Access-Control-Allow-Origin: http://foo.com

此处不能使用通配符*

如果没有2、3,既是携带 cookie,返回信息也会被浏览器阻止

第三方 cookie

跨域 cookie 被视为第三方 cookie,如果浏览器被用户设置为不接受第三方 cookie,那么上述fetch请求不会设置 cookie:

Set-Cookie: pageAccess=3;

关闭第三方 cookie 的情况下,该 cookie 将不能被设置

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.