Giter Club home page Giter Club logo

asprogramer's People

Contributors

gzqby avatar

asprogramer's Issues

记录一些轮子吧

hoist-non-react-statics

Copies non-react specific statics from a child component to a parent component. Similar to Object.assign, but with React static keywords blacklisted from being overridden.
--used by react-redux

react-is:

This package allows you to test arbitrary values and see if they're a particular React element type.
-- by react

co解析来理解Async函数

众所周知,async函数是generator和promise的语法糖,那么到底是怎样的语法糖哪?由于能力有限只能从co探究其实现。整体就是一个generator函数自动执行,并最终以promise返回最后一个yied值!

// co(gen)接受generator,是函数绑定this
if (typeof gen === 'function') gen = gen.apply(ctx, args);
// onFulfilled();执行
function onFulfilled(res) {
      var ret;
      try {
        ret = gen.next(res);
      } catch (e) {
        return reject(e);
      }
      next(ret);
      return null;
}


function next(ret) {
      // 判断结束
      if (ret.done) return resolve(ret.value);
      // 转promise
      var value = toPromise.call(ctx, ret.value);
      // 再执行onFulfilled
      if (value && isPromise(value)) return value.then(onFulfilled, onRejected);
      // 以上为正常执行的处理
      return onRejected(new TypeError('You may only yield a function, promise, generator, array, or object, '
        + 'but the following object was passed: "' + String(ret.value) + '"'));
}


function toPromise(obj) {
  if (!obj) return obj;
  if (isPromise(obj)) return obj;
  if (isGeneratorFunction(obj) || isGenerator(obj)) return co.call(this, obj);
  if ('function' == typeof obj) return thunkToPromise.call(this, obj);
  if (Array.isArray(obj)) return arrayToPromise.call(this, obj);
  if (isObject(obj)) return objectToPromise.call(this, obj);
  // 者一步应该是返回promise.resolve(obj)才更符合async函数的形式
  return obj;
}

进程、线程与浏览器的多进程架构

  1. 进程:一个进程就是一个程序的运行实例。详细解释就是,启动一个程序的时候,操作系统会为该程序创建一块内存,用来存放代码、运行中的数据和一个执行任务的主线程,我们把这样的一个运行环境叫进程。
  2. 线程:依附于进程,能并行多线程执行。
  3. Chrome浏览器采用多进程架构,各个页面间渲染不相互影响,进程间IPC通信
    chrome进程图
    图片查看
    如图:打开一个页面,同时开启了多个进程有:浏览器主进程,GPU进程,网络进程,渲染进程,插件进程(其中渲染、插件进程又是一个开一个进程,形成了打开浏览器一个页面就出现多个进程的场景)。
  4. 协程:JS来说之前是不完全具备协程能力的,比如不能真正意义实现sleep功能的。原本的异步回调主要可控制的执行都是在主线程,generator是实现了js协程能力,分步执行控制。

JavaScript 中的 DILOS 原则

#JavaScript 中的 DILOS 原则

DILOS 的含义:

  • D——依赖倒置反转原则
  • I——接口捆绑原则
  • L——里氏分离原则
  • O——开闭原则
  • S——多职责原则

依赖倒置反转原则

高级模块必须依赖低级模块。依赖实体而不是抽象。

function hipAPI(url, httpMethod) {
  ...
}
hipAPI('http://url.com', 'get');

function hipDifferentAPI(type, httpMethod) {
  if(type instanceof initialLoad) {

  }else if(type instanceof naBar) {

  }else {

  }
}

接口捆绑原则

强迫客户端依赖它们不用的 [代码]。
写的函数越少越好。把什么东西封装在一个放在其他地方的新函数里,并抽象化它的逻辑?可别这么干。怎么让人犯迷糊怎么来,需要代码的时候复制粘贴过来就行。

里氏分离原则

软件各部分的子级和父级不可以互换。
DRY。因为如果我们不遵循里氏分离原则,我们就会构建准确而健壮的继承链。将逻辑抽象为封装好的 base 原型 / 对象。我们还会对原型链中的不同方法按逻辑分组,它们的特定覆盖会让代码路径更加可预期和可发现。

开闭原则

对象应对修改开放,对扩展封闭。

function makeSound(animal) {
  if(animal === "dog"){
    ...
  }else if(animal === "cat") {
    ...
  }else if(animal === "crow") {
    ...
  }else if(animal === "sheep") {
    ...
  }else if(animal === "cow") {
    ...
  }else if(animal === "pig") {
    ...
  }else{
    ...
  }
}

多职责原则

确保你的函数 / 对象有多重职责。
优秀的编程人员常常会将他们的代码分成多个不同的对象或模块。但我可搞不清楚这种事情,我记不住它们都负责什么事情。
这种反模式有时被称为“瑞士军刀”,因为就算你要的只是一把剪子,但它也可以是指甲锉、锯子、镊子、开瓶器,也可以是软木钉。


FROM 极客时间 作者: Kealan Parr

html模版代码解析-结合ejs

执行步骤

  1. 形成参数配置—args2存在opt的选项的话复制到opt

    if (arguments.length == 2) {utils.shallowCopyFromList(opts, data, _OPTS_PASSABLE_WITH_DATA);
    
      }
  2. 处理cache—有cache,取,存以template和opt形成的compile

    if (options.cache) {
        if (!filename) {
          throw new Error('cache option requires a filename');
        }
        func = exports.cache.get(filename);
        if (func) {
          return func;
        }
        if (!hasTemplate) {
          template = fileLoader(filename).toString().replace(_BOM, '');
        }
      }
    
  3. compile—处理旧版scope问题,new Template返回其compile

    if (opts && opts.scope) {
        if (!scopeOptionWarned){
          console.warn('`scope` option is deprecated and will be removed in EJS 3');
          scopeOptionWarned = true;
        }
        if (!opts.context) {
          opts.context = opts.scope;
        }
        delete opts.scope;
      }
    
  4. createRegex—匹配对应的标示符号

    function () {
        var str = _REGEX_STRING;
        var delim = utils.escapeRegExpChars(this.opts.delimiter);
        var open = utils.escapeRegExpChars(this.opts.openDelimiter);
        var close = utils.escapeRegExpChars(this.opts.closeDelimiter);
        str = str.replace(/%/g, delim)
          .replace(/</g, open)
          .replace(/>/g, close);
        return new RegExp(str);
      },
    
  5. GenerateSource—

    1. parseTemplateText—用数组装匹配到的模版标示(<%= %>等)

          var result = pat.exec(str);
      
    2. matchs循环匹配openDelimiter和closeDelimiter,并scanLine(line)

      matches.forEach(function (line, index) {
              var closing;
              // If this is an opening tag, check for closing tags
              // FIXME: May end up with some false positives here
              // Better to store modes as k/v with openDelimiter + delimiter as key
              // Then this can simply check against the map
              if ( line.indexOf(o + d) === 0        // If it is a tag
                && line.indexOf(o + d + d) !== 0) { // and is not escaped
                closing = matches[index + 2];
                if (!(closing == d + c || closing == '-' + d + c || closing == '_' + d + c)) {
                  throw new Error('Could not find matching close tag for "' + line + '".');
                }
              }
              self.scanLine(line);
            });
      
    3. scanLine生成了source

      scanLine: function (line) {
      	...
      	this.source += 
      }
      
  6. compile函数根据source并添加函数定义给new Function初始化

          fn = new ctor(opts.localsName + ', escapeFn, include, rethrow', src);
    
  7. 最好传入data执行

    handleCache(opts, template)(data);
    

总结

  1. 使用var _REGEX_STRING = '(<%%|%%>|<%=|<%-|<%_|<%#|<%|%>|-%>|_%>)'; 匹配文本,以匹配到的内容为临界点分割成数组arr。(这一步很关键,这步后基本思路瞬间清晰了。所以假如要处理其他类型的文本,最关键依然该是分析文本特点,以关键标示形成适合的数据模型,方便进一步处理!)
  2. 对以上数组arr,遍历处理,以对应的标示(<%%|%%>|<%=|<%-|<%_|<%#|<%|%>|-%>|_%>)为依据输出对应执行语句
  3. 形成函数,传入data返回文本(也解释为什么<% arr.forEach(item) { %>能这样使用函数的)

一个正则

一个正则系列

写到的正则就记在这吧,以便后观

// 协议,主机地址,后缀,ip规则可加
/^http[s]?:\/\/([.-A-Za-z0-9]+(?:com|cc|top|cn)|\d{2,3}\.\d{1,3}\.\d{1,3}\.\d{1,3}).+/g.exec("https://127.0.0.1/122?231"),

单点登录分享

单点登录分享

登录

从业务出发,什么是登录?

  1. 验证你的身份
  • 本系统账号密码

  • 社群账号、微信谷歌

  • 等等

  1. 定位到你的userId

  2. 生成通关文碟

  • cookie

  • session

  • token

  1. 之后业务接口都是校验通关文碟,确认你的用户身份

单点登录

单点登录(Single Sign On),简称为 SSO,是比较流行的企业业务整合的解决方案之一。SSO的定义是在多个应用系统中,用户只需要登录一次就可以访问所有相互信任的应用系统。

百科的解释,两个关键词:多个应用,登录一次

换句话说,一个通关文碟,访问多个应用

  1. 让多个应用服务端都能识别一个通关文碟,它们肯定要是:统一的一个鉴权,或者相互调研验证的鉴权

  2. 多个应用客户端能持有一个通关文碟,通关文碟肯定是:放在一个公共读取的地方,或者相互通信、通道去拿到

以上2个条件每个都可以有多个方案,交叉组队方案就很多了,实际情况要安全、准确性等其他条件综合考虑。

BS架构下某书的方案

客户端:cookie、httpOnly、一个Domain

服务端:一个accounts服务

程序之异常处理

异常处理-软件工程最值得考量的一部份之一(甚至golang因异常处理方式不够优雅而受人诟病)

各种各样的编程语言,各种各样的错误形式,放在一起以表现形式分类,才能恰到好处:
  1. 重大异常

    物理因素等,无法处理

    1. 内存耗尽
    2. 栈溢出
    3. 等各种程序无能为力的异常
  2. 一般异常

    1. 程序明显逻辑问题的异常

      不捕获,抛出来,让开发者发现问题

      1. 数据库IP错误,无法连接
      2. Null读取值
      3. 类型错误
    2. 程序可处理的意外情况

      需要捕获异常,属于正常发生的不正常情况

      1. 查询文件找不到
      2. 前端网络错误

综上,处理方式可分为三类,无法处理着重关注;不处理可程序退出让开发者明确;多兜底防止程序退出

mobx推荐不使用setState是在讲什么

文章流程是这样的:首先是题目与几个观点,然后通过几个问题讲一讲mobx的逻辑,然后再回到题目的观点,最后就是对mobx或者其他方案的态度就是没态度。或者说团队开发是软工的事,个人就随心意

mobx推荐不使用setstate是在说什么

题目的来源是在读mobx文档时看到的,即以上链接,给出的几个观点

  1. setState is asynchronous
  2. setState causes unnecessary renders
  3. setState is not sufficient to capture all component state

通过几个问题来理解mobx的逻辑

  1. how can let React render?how can let react escape rerender?

    • there are useState, setState and force-update

      // 一种渲染和规避的方式
      class Demo extends React.Component{
        state = {
          box: 1
        }
      
        shouldComponentUpdate(_, state) {
          // console.log(arguments);
          return state.box>5 ? false : true;
        }
      
        render() {
          return <div>
            <h1>hello world, {this.state.box}</h1>
            <button onClick={()=>this.setState(prevState=>({
              box: prevState.box+1
            }))}>click+</button>
          </div>
        }
      }
      
  2. how MOBX render?

    const box = observable.box(1);
    const act = action(()=>{
      box.set(box.get()+1)
    })
    autorun(()=>{
      console.log(box.get());
    })
    
    act()
    act()
    act()
    act()
    
  3. what does the inject of Mobx-react do?

    基本主要就是做了把context作为props传递给组件

    function createStoreInjector(
        grabStoresFn: IStoresToProps,
        component: IReactComponent<any>,
        injectNames: string,
        makeReactive: boolean
    ): IReactComponent<any> {
        // Support forward refs
        let Injector: IReactComponent<any> = React.forwardRef((props, ref) => {
            const newProps = { ...props }
            const context = React.useContext(MobXProviderContext)
            Object.assign(newProps, grabStoresFn(context || {}, newProps) || {})
    
            if (ref) {
                newProps.ref = ref
            }
    
            return React.createElement(component, newProps)
        })
    
        if (makeReactive) Injector = observer(Injector)
        Injector["isMobxInjector"] = true // assigned late to suppress observer warning
    
        // Static fields from component should be visible on the generated Injector
        copyStaticProperties(component, Injector)
        Injector["wrappedComponent"] = component
        Injector.displayName = getInjectName(component, injectNames)
        return Injector
    }
    
  4. what does the observe of Mobx-react do?

    重要的,首先是Reaction对象,去track(利用getter把reaction传递给observable,最后addObserver)

    trackDerivedFunction<T>(derivation: IDerivation, f: () => T, context: any) {
        const prevAllowStateReads = allowStateReadsStart(true)
        // pre allocate array allocation + room for variation in deps
        // array will be trimmed by bindDependencies
        changeDependenciesStateTo0(derivation)
        derivation.newObserving_ = new Array(derivation.observing_.length + 100)
        derivation.unboundDepsCount_ = 0
        derivation.runId_ = ++globalState.runId
        const prevTracking = globalState.trackingDerivation
        globalState.trackingDerivation = derivation
        globalState.inBatch++
        let result
        if (globalState.disableErrorBoundaries === true) {
            result = f.call(context)
        } else {
            try {
                // 这里通过globalState同步关联
                result = f.call(context)
            } catch (e) {
                result = new CaughtException(e)
            }
        }
        globalState.inBatch--
        globalState.trackingDerivation = prevTracking
        // 这个地方是把Reaction 绑定到observable
        bindDependencies(derivation)
    
        warnAboutDerivationWithoutDependencies(derivation)
        allowStateReadsEnd(prevAllowStateReads)
        return result
    }
    
    const reaction = new Reaction(`${initialName}.render()`, () => {
            if (!isRenderingPending) {
                // N.B. Getting here *before mounting* means that a component constructor has side effects (see the relevant test in misc.js)
                // This unidiomatic React usage but React will correctly warn about this so we continue as usual
                // See #85 / Pull #44
                isRenderingPending = true
                if (this[mobxIsUnmounted] !== true) {
                    let hasError = true
                    try {
                        setHiddenProp(this, isForcingUpdateKey, true)
                        if (!this[skipRenderKey]) Component.prototype.forceUpdate.call(this)
                        hasError = false
                    } finally {
                        setHiddenProp(this, isForcingUpdateKey, false)
                        if (hasError) reaction.dispose()
                    }
                }
            }
        })
    
  5. why it doesn't re-render when i update simple context object, and it does when i update MOBX object?

    • 其实不是observable有什么想不到的东西,还是在数据变动,去触发react更新。
    const aaa = {
      box: 1,
      plus() {
        this.box++;
      },
    }
    
    const ctx = React.createContext(aaa)
    
    const MMMM = () => {
      const ctxx = React.useContext(ctx);
      const [_, setA] = React.useState(0);
      return <div>
        <h1>hello mobx, {ctxx.box}</h1>
        <button onClick={()=>{
          // act();
          ctxx.plus();
          console.log(ctxx.box, aaa.box);
          if(ctxx.box > 5) {
            setA(ctxx.box)
          }
        }}>
        click+
      </button></div>
    }
    

针对问题的思考

  1. 我的理解是这样的,数据和状态是分离的,所以能保持数据同步!
  2. 处理不必要渲染是这样的?针对class组件是使用shouldComponentUpdate!(函数组件暂未详细看)
  3. state当然不能管理所有的组件状态?一个对象就能管理即observable对象

总结

同步是否易于开发?(就是个个人感知问题!)是不是最优解哪?hooks能不能解决上述问题

我的总结没有答案。我想说的是:基于一点点的不同,一点点的变化,一点点的用户习惯,造轮子有没有必要?前端生态的繁荣有时候就是靠这些一点点,才有我们今天应对各种场景时,选择方案的从容。

so保持开放的心态,持续学习

Recoil基于源码解析与介绍

Recoil基于源码的原理介绍

Recoil是什么?

  1. facebook的亲儿子
  2. 状态管理
    • 符合React17新特性逻辑,多处render,recoil也可以一个应用中多处RecoilRoot
    • 就单个RecoilRoot治理下的来看还是个中心化的状态管理(状态是颗粒的,状态管理却是中心的)

上个图吧(以atom为例)

Recoil,atom与useRecoilState
图片查看
看图说特性:

  • 以订阅的形式,做每个组件独立更新
  • 创建状态就是一个key属性的对象,这很react
atom({
  key: "atom",
  default: "",
})
// 输出什么?
{key: "atom"}
  • 当use时候去订阅,去取值(这个值是存在Nodes里的,其实root节点也存的有状态,但是是做历史记录用的,并不是取值用的)
  • useSet时候去更新

亮点(当然还有Snapshot,waitFor...等API这里不讨论)

  • 传递的是{key},而不是传递数据,数据是随用随取的
  • 订阅分发给使用的组件更新re-render,而不是redux一样connect父级别组件去带动re-render

API

  • 当然不写了。API整体来看并没有很多,习惯hooks的基本没什么门槛,看懂原理的话,我相信你更能得心应手了!!!

掰开揉碎了讲SPA前端代码打包优化

Q:把4M的文件拆成2个2M的文件,但是network加载时间看起来是一样的?(此分享的由来)

Q1:代码打包优化的目的是什么?

更快的加载,更省资源

Q2:更快的加载为了什么?

用户体验,看到网页,一个正常的网页

基于以上,我们可以做什么?

  1. 代码压缩
  2. 代码分拆
  3. 缓存(CDN,前端)
  4. 基础设施(网速、带宽、HTTP2等)

最终聚焦,我们能做的:

  1. 代码压缩?
    a. 打包压缩
    b. gzip
  2. 缓存
    a.CDN
    b. 前端强制缓存(SPA应用强制缓存是个大特点,不需要协商缓存,利用次特点,最大化分拆优势)

代码分拆?这里是个重点,分拆技术都会,到底怎么规划

要考虑的硬件点:1. 浏览器同时加载资源几路?6,同源。要考虑的软件点:1. SPA网站需要加载的资源巨多

a. 怎么并行最大化?多源6路
b. 怎么串行最大化?一次传输,不拆包,不重复建立通路
c. 怎么不请求
以上这两点,都是理想化的,因为网速、带宽,各个资源大小不一。但是其实还是能说明一个点,4M拆2个有点粗暴
折中方案:
a. 媒体资源不同源
b. 不需要一味优化代码体积,打包工具推荐2M用就完了
c. 缓存,强制缓存,关键要分包,把基础依赖资源利用MD5固定文件路径强制缓存下来,所以这个对应上面的基础包体积大,并不是啥问题

html标签img的在业务开发中的场景方案分享

业务场景与现象

场景:

在账户找回业务场景中,需要使用用户的一部分信息,其中有图片信息。然后就出现一个问题,img标签src图片链接是不能显示的,然而用浏览器新开tab的方式是可以正常显示图片的。

分析:

登陆态与非登陆态表现不同的原因在,登陆态的可以获取预先协议规则,使用非img标签形式获取资源,而非登陆不能。代码中与浏览器tab表现不同的原因在:有无Referer

思考

线上image资源作为公开资源,不做一定的限制,面临问题的—盗链,以及带来的流量负担与版权问题

正反向方案

  • 正向:怎么做资源保护与下载:

    1. 常规操作就是根据referer做判断,能做到浏览器可查看
    2. 如果浏览器不能查看只能下载需要response headers加:Content-Disposition:attachment;filename=""
    3. 当然img资源get也是http,所以可以协议param去过滤访问
  • 反向:

    由于常规图片资源还是要兼容浏览器查看的,所以屏蔽referer就是应对方案。方法:

    1. 方法img标签referrerpolicy(兼容性有问题)
    2. <meta name="referrer" content="no-referrer">

一个很常规的web场景,多层级菜单

菜单树

  1. 问:近期在做一个平台后端项目,开发中有层级菜单。然后就一个场景:数据结构[{id,parentId,order}......],不限树层级数,同级同组有序,尽可能少的sql,尽可能小的复杂度,尽可能小的内存消耗,
  2. 答:一次sql,一次遍历,一个Array,一个Map解决
  3. 思路:
    a. sql orderBy查询出所有数据data
    b. new 一个Array,一个 Map
    c. 遍历data,是root级别,push进array;其他的操作是一样的:无论父子级别,先查自身是否存在于map中,存在就合并,并将合并后的push进map[parentid].children,parentid在map中可能不存在,set一个(parentid, {children:[]}).
    d. 因为sql查询是有序的,所以虽然push入不同数组但是都是有序的

也是想了一下午怎么更好的实现,感觉也挺有意思的,或许这就是人们讲算法数据结构才是程序员的终极奥义,不过我不怎么喜欢干刷算法题,未来要多找点有场景的多玩玩

WebAssembly

什么是WebAssembly

  • WebAssembly 是一种二进制编码格式,而不是一门新的语言。
  • WebAssembly 不是为了取代 JavaScript,而是一种补充(至少现阶段是这样),结合 WebAssembly 的性能优势,很大可能集中在对性能要求高(例如游戏,AI),或是对交互体验要求高(例如移动端)的场景。
  • C/C++ 等语言可以编译 WebAssembly 的目标文件,也就是说,其他语言可以通过编译器支持,而写出能够在浏览器前端运行的代码。

发展历史

从发展历史可以总结技术发展规律,如何从一个个人项目到W3C标准

截屏2024-01-04 16 44 30

从性能进一步探索前端方案:WebAssembly、Worker、JavaScript对比

为什么把worker拿出来,因为两者可以搭配使用

WebAssembly Worker JS
性能
安全性
生态丰富性
兼容性
适合任务 高性能、计算密集型任务 异步执行、耗时任务 快速开发、通用任务

eg用golang写wasm

  1. 安装golang环境
  2. 需要一些模版代码
// js胶水代码
cp "$(go env GOROOT)/misc/wasm/wasm_exec.js" .
// html模版代码
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>
</head>
<body>
    <div id="root"></div>
</body>
    <script src="wasm_exec.js"></script>
    <script>
    const go = new Go();
    WebAssembly.instantiateStreaming(fetch("main.wasm"), go.importObject)
        .then((result) =>{
            go.run(result.instance)
        });
    </script>
</html>
  1. 写wasm代码
package main

import (
    "fmt"
    "syscall/js"
    "time"
)

// js可以调用的函数
func forJsFunc(this js.Value, args []js.Value) any {
    // duration := int(js.Value(args[0]).Int())
    duration := args[0].Int()
    var cb = args[len(args)-1]
    go func() {
        // time.Sleep(time.Second * duration)
        time.Sleep(time.Duration(duration) * time.Second)
        str := fmt.Sprintf("it's %d second", duration)
        cb.Invoke(js.ValueOf(str))
    }()

    return nil
}

func main() {
    done := make(chan int, 0)
    // js的golbal
    var jsGlobal = js.Global()
    // Set、Get对象等
    var document = jsGlobal.Get("document")
    var root = document.Call("getElementById", "root")
    root.Set("innerHTML", js.ValueOf("hello world!"))

    var alert = jsGlobal.Get("alert")
    // 执行
    alert.Invoke("alert")

    // 设置js的全局函数
    jsGlobal.Set("wamsFunc", js.FuncOf(forJsFunc))
    <-done
}

// 编译
GOARCH=wasm GOOS=js go build -o test.wasm main.go

Golang syscall/js 文档

Zero Width Non-Joiner、ZeroWidthSpace

有趣的知识又增加了

Q: 文件解析出的文本的,肉眼可见的每组就百个字符,但是插入到数据库就会报错:row * data too long;
反复试探是不是工具代码哪里有问题?实在无解。最终去再遍历一遍打印出来字符的length,真的有巨长的文本啊,放到html中F12的element标签可以显示出来
image

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.