120分钟React快速扫盲教程

  在教程开端先说些题外话,我喜欢在学习一门新技术或读过一本书后,写一篇教程或总结,既能帮助消化,也能加深印象和发现自己未注意的细节,写的过程其实仍然是一个学习的过程。有个记录的话,在未来需要用到相关知识时,也方便自己查阅。

  React既不是一个MVC框架,也不是一个模板引擎,而是Facebook在2013年推出的一个专注于视图层,用来构建用户界面的JavaScript库。它推崇组件式应用开发,而组件(component)是一段独立的、可重用的、用于完成某个功能的代码,包含了HTML、CSS和JavaScript三部分内容。React为了保持灵活性,只实现了核心功能,提供了少量的API,一些DOM方法都被剥离到了react-dom.js中。这么做虽然轻巧,但有时候要完成特定的业务场景,还是需要与其他库结合,例如Redux、Flux等。React不仅让函数式编程愈加流行,还引入了JSX语法(能把HTML嵌入进JavaScript中)和Virtual DOM技术,大大提升了更新页面时的性能。在React中,每个组件的呈现和行为都由特定的数据所决定,而数据的流动都是单向的,即单向数据流。在编写React时,推荐使用ES6语法,官方的文档也使用了ES6语法,因此,在学习React之前,建议对ES6有所了解,避免不必要的困惑。

  下面是一段较为完整的React代码,本文大部分的示例代码来源于此,阅读下面的代码可以对React有一个感性的认识。

import React, { Component } from 'react';
import ReactDOM from 'react-dom';
import PropTypes from 'prop-types';
class Search extends Component {//static defaultProps = {//    url: "http://jane.com"//};
    constructor(props) {super(props);this.state = {txt: "请输入关键字"};
    }componentWillMount() {console.log("component will mount");}componentDidMount() {console.log("component did mount");this.refs.txt.addEventListener("blur", (e) => {this.getValue(e);});console.log(this.refs)}handle(keyword, e) {console.log(keyword);console.log(this);console.log(this.select.value);}getValue(e) {console.log(e.target.value);}refresh(e) {this.setState({type: e.target.value});}
    render() {console.log("render");let {type} = this.state;console.log(type);return (<div>{this.props.children}<select value={type} onChange={this.refresh.bind(this)}><option value="1">标题</option><option value="2">内容</option></select><select defaultValue={2} ref={(select) => this.select = select}><option value="1">标题</option><option value="2">内容</option></select><input placeholder={this.state.txt} ref="txt" defaultValue="教程" style={{marginLeft:10, textAlign:"center"}}/><button className="btn" data-url={this.props.url} onClick={this.handle.bind(this, "REACT")}>{"<搜索>"}</button></div>
        );}
}
Search.defaultProps = {url: "http://jane.com"
};
ReactDOM.render(<Search url="http://www.pwstrick.com"><h1>React扫盲教程</h1></Search>,document.getElementById("container")
);

一、JSX语法

  JSX是对JavaScript语法的一种扩展,它看起来像HTML,同样拥有清晰的DOM树状结构和元素属性,如下代码所示。但与HTML不同的是,为了避免自动插入分号时出现问题,在最外层得用圆括号包裹,并且必须用一个元素包裹(例如下面的<div>元素)其它元素,所有的元素还必须得闭合。

(<div><input placeholder={this.state.txt} /><button className="btn">{"<搜索>"}</button>
</div>)

1)元素

  JSX中的元素分为两种:DOM元素和组件元素(也叫React元素),DOM元素就是HTML文档映射的节点,首字母要小写;而组件元素的首字母要大写。无论是DOM元素还是组件元素,最终都会通过React.createElement()方法转换成JSON对象,如下所示,JSON对象是简化过的。

//React.createElement()方法
React.createElement("div", null, [React.createElement("input", { placeholder: `${this.state.txt}` }, null),React.createElement("button", { className: "btn" }, "<搜索>")
]);
//简化过的JSON对象
{type: "div",props: {children: [{type: "input",props: {placeholder: `${this.state.txt}`}},{type: "button",props: {className: "btn",children: "<搜索>"}}]}
}

  由于JSX中的元素能够被编译成对象,因此还可以把它们应用到条件、循环等语句中,或者作为一个值应用到变量和参数上。

2)属性

  JSX中的属性要用驼峰的方式表示,例如maxlength要改成maxLength、readonly要改成readOnly。还有两个比较特殊的属性:class和for,由于这两个是JavaScript中的关键字,因此要改名,前者改成className,后者改成htmlFor。

  JSX中的属性值不仅可以是字符串,还可以是表达式。如果是表达式,那么就要用花括号(“{}”)包裹。而在JSX中,任何位置都可以使用表达式。

  有一点要注意,为了防止XSS的攻击,React会把所有要显示到DOM中的字符串进行转义,例如“<搜索>”转义成“&lt;搜索&gt;”。

3)Virtual DOM

  众所周知,DOM操作会引起重绘和重排,而这是非常消耗性能的。React能把元素转换成对象,也就是说可以用对象来表示DOM树,而这个存在于内存中的对象正是Virtual DOM。Virtual DOM相当于一个缓存,当数据更新后,React会重新计算Virtual DOM,再与上一次的Virtual DOM通过diff算法做比对(如下图所示),最后只在页面中更新修改过的DOM。由于大部分的操作都在内存中进行,因此性能将会有很大的提升。

二、组件

  组件的构建方式有3种:React.createClass()、ES6的类和函数。当用ES6的类来构建时,所有的组件都继承自抽象基础类React.Component,该抽象类声明了state、props、defaultProps和displayName等属性,定义了render()、setState()和forceUpdate()等方法。注意,在组件的构造函数constructor()中要调用super()函数,用于初始化this和执行抽象类的构造函数。

import React, { Component } from 'react';
class Search extends Component {constructor (props) {super(props);}render() {return ();}
}

  组件中的render()方法是必须的,它会返回一个元素、数字或字符串等各种值。render()是一个纯函数,即输出(返回值)只依赖输入(参数),并且执行过程中没有副作用(不改变外部状态)。

  组件之间可以相互嵌套,而它们的数据流是自顶向下流动的(如下图所示),即父组件将数据传给子组件。此处传递的数据就是组件的配置参数,由props属性控制,而组件的内部状态保存在state属性中。

1)props

  如果一个组件要做到可复用,那么它应该是可配置的。为此,React提供了props属性,它的使用如下所示。

class Search extends Component {render() {return (<div><button className="btn" data-url={this.props.url}>{"<搜索>"}</button></div>
        );}
}
<Search url="http://www.pwstrick.com" />

  先给Search组件定义一个名为url的属性,然后在组件内部,可以通过引用props属性来获取url的值。有一点要注意,props是只读属性,因此在组件内部无法修改它。

  React为组件提供了默认的配置,可以调用它的静态属性defaultProps。总共有两种写法实现默认配置,如下代码所示,其中写法一用到了ES6中的static关键字。

//写法一
class Search extends Component {static defaultProps = {url: "http://jane.com"};
}
//写法二
Search.defaultProps = {url: "http://jane.com"
};
<Search />

  此时,即使组件不定义url属性,在组件内部还是会有值。

  props还有一个特殊的属性:children,它的值是组件内的子元素,如下代码所示,children属性的值为“<h1>React扫盲教程</h1>”。

class Search extends Component {render() {return (<div>{this.props.children}</div>
        );}
}
<Search><h1>React扫盲教程</h1>
</Search>

2)state

  组件的呈现会随着内部状态和外部配置而改变,通常会在组件的构造函数中初始化需要的内部状态,如下代码所示,为文本框添加默认提示。

class Search extends Component {constructor (props) {super(props);this.state = {txt: "请输入关键字"};}
}

  React还提供了setState()方法,用于更新组件的状态。注意,不要通过直接为state赋值的方式来更新状态,因为setState()方法在更新状态后,还会调用render()方法,重新渲染组件。此外,React为了提升性能,会把多次setState()调用合并成一次,像下面这样写打印出的txt属性的值仍然是前一次的值,因此状态更新是异步的。

this.setState({txt: "React"
});
console.log(this.state.txt);    //"请输入关键字"

3)生命周期

  组件的生命周期(life cycle)可简单的分为4个阶段:初始化(Initialization)、挂载(Mounting)、更新(Updation)和卸载(Unmounting),具体如下图所示。每个阶段都会对应几个方法,其中包含will的方法会在某个方法之前被调用,而包含did的方法会在某个方法之后被调用。

1、在初始化阶段,会设置props、state等属性。

2、在挂载阶段,两个挂载方法将以组件的render()为分界点。

3、更新阶段发生在传递props或执行setState()的时候。

4、当一个组件被移除时,就会调用componentWillUnmount()方法。

当组件在页面中输出时,在控制台将依次输出“will mount”、“render”和“did mount”。

class Search extends Component {componentWillMount() {console.log("will mount");}componentDidMount() {console.log("did mount");}render() {console.log("render");}
}

三、React和DOM

1)ReactDOM

  如果要把组件添加到真实的DOM中,那么就需要使用ReactDOM中的render()方法,如下代码所示,其实在前面已经调用过几次这个方法了。

ReactDOM.render(<Search />,document.getElementById("container")
);

  此方法可接收三个参数,第一个是要渲染(即添加)的元素,第二个是容器元素(即添加的位置),第三个是可选的回调函数,会在渲染或更新之后执行。

  ReactDOM还提供了另外两个方法:unmountComponentAtNode()findDOMNode(),具体可参考官方文档。

2)事件

  React实现了一种合成事件(SyntheticEvent),合成事件只有冒泡传播,并且它的注册方式、事件对象和事件处理程序中的this对象都与原生事件不同。

1、合成事件会通过设置元素的属性来注册事件,但与原生事件不同的是,属性的命名要用驼峰的写法而不是全部小写,并且属性值可以是任意类型而不再仅是字符串,如下代码所示。React已经封装好了一系列的事件类型(原生事件类型的一个子集),并且已经处理好它们的兼容性,提供的事件类型可以参考官网

class Search extends Component {handle(e) {console.log("click");}render() {return (<div><button onClick={this.handle}>搜索</button></div>
        );}
}

2、合成事件中的事件对象(event object)是一个基于W3C标准的SyntheticEvent对象的实例,它不但与原生的事件对象拥有相同的属性和方法(例如cancelable、preventDefault()、stopPropagation()等),还完美解决了兼容性问题。

3、React的事件处理程序中的this对象默认是undefined,因为注册的事件都是以普通函数的方式调用的。如果要让this指向当前组件,那么可以用bind()方法或ES6的箭头函数。

class Search extends Component {//bind()方法
    handle1(e) {console.log(this);}//箭头函数handle2 = (e) => {console.log(this);};render() {return (<div><button onClick={this.handle1.bind(this)}>搜索</button><button onClick={this.handle2}>搜索</button></div>
        );}
}

4、在向事件处理程序传递参数时,要把事件对象放在最后,如下代码所示。

class Search extends Component {handle(keyword, e) {console.log(keyword);console.log(this);}render() {return (<div><button onClick={this.handle1.bind(this, "REACT")}>搜索</button></div>
        );}
}

5、如果要为组件中某个元素注册原生事件,那么可以利用元素的ref属性和组件的refs对象实现。例如实现一个文本框在失去焦点时,打印输出它的值,如下代码所示。注意,原生事件的注册要在componentDidMount()方法内执行。

class Search extends Component {componentDidMount() {this.refs.txt.addEventListener("blur", (e) => {this.getValue(e);});}getValue(e) {console.log(e.target.value);}render() {return (<div><input placeholder={this.state.txt} ref="txt" /></div>
        );}
}

  在上面的代码中,ref属性的值被设为了“txt”,此时,在refs对象中就会出现一个名为“txt”的属性,关于这个它们的具体用法可以参考官网

3)表单

  HTML中的表单元素(例如<input>、<select>和<radio>等)在React都有相应的组件实现,React还把表单中的组件分为受控和非受控。

  受控组件(controlled component)的状态由React组件控制,它的每个状态的改变都会有一个与之对应的事件处理程序,并且在程序内部会调用setState()方法更新状态。React推荐使用受控组件,下面是一个受控组件,注意,选择框(<select>元素)中的value属性表示选中项。

class Search extends Component {refresh(e) {this.setState({type: e.target.value});}render() {let {type} = this.state;return (<div><select value={type} onChange={this.refresh.bind(this)}><option value="1">标题</option><option value="2">内容</option></select></div>
        );}
}

  非受控组件(uncontrolled component)的状态不受React组件控制,也不用为每个状态编写对应的事件处理程序,但可以通过元素的ref属性获取它的值,非受控组件的写法更像是传统的DOM操作。在使用非受控组件时,如果要为其设置默认值,可以使用属性defaultValue或defaultChecked,具体如下所示。

class Search extends Component {handle(e) {console.log(this.select.value);}render() {return (<div><select defaultValue={2} ref={(select) => this.select = select}><option value="1">标题</option><option value="2">内容</option></select><button onClick={this.handle.bind(this)}>搜索</button></div>
        );}
}

4)样式

  在React问世的初期,由于它推崇组件模式,因此会要求HTML、CSS和JavaScript混合在一起,这与过去的关注点分离正好相反。React已将HTML用JSX封装,而对CSS的封装,则抛出了CSS in JS的解决方案,即用JavaScript写CSS。

  在React中的元素都包含className和style属性,前者可设置CSS类,后者可定义内联样式。style的属性值是一个对象,其属性就是CSS属性,但属性名要用驼峰的方式命名,例如margin-left改成marginLeft,具体如下所示。

class Search extends Component {render() {return (<div><input style={{marginLeft:10, textAlign:"center"}}/></div>
        );}
}

  注意,属性名不会自动补全浏览器前缀,并且React会自动给需要单位的数字加上px。在MDN上给出了CSS属性用JavaScript命名的对应关系,可在此处参考

  由于React处理CSS的功能并不强大,因此市面上出现了很多与CSS in JS相关第三方类库,例如classnamespolished.js等,有外国网友还专门搜集了40多种相关的类库。

  虽然这种方式能让组件更方便的模块化,但同时也彻底抛弃了CSS,既不能使用CSS的特性(例如选择器、媒体查询等),也无法再用CSS预处理器(例如SASS、LESS等)。为了解决上述问题,又有人提出了CSS Modules

  如果要在React中制作动画,官方推荐使用React Transition GroupReact Motion。不过,你也可以使用普通的动画库(例如animejs),只要在DOM渲染好以后调用即可。

四、React进阶

1)跨级通信

  React数据流动是单向的,组件之间通信最常见的方式是父组件通过props向子组件传递信息,但这种方式只能逐级传递,如果要跨级通信(即父组件与孙子组件通信),那么可以利用状态提升实现,但这样的话,代码会显得很不优雅并且很臃肿。好在React包含一个Context特性,可以满足刚刚的需求,不过官方不建议大量使用该特性,因为它不但会增加组件之间的耦合性,还会让应用变得混乱不堪,下图演示了两种数据传递的过程。在理解Context特性后,能更合理的使用状态管理容器Redux。

   当一个组件设置了Context后,它的子组件就能直接访问Context中的内容,Context相当于一个全局变量,但作用域仅限于它的子组件中。总共有两种Context的实现方式,都基于生产者消费者模式。首先来看第一种,具体代码如下所示。

import PropTypes from 'prop-types';
class Grandpa extends Component {getChildContext() {return { name: "strick" };}render() {return (<Son />);
    }
}
Grandpa.childContextTypes = {name: PropTypes.string
};
class Son extends Component {render() {return (<Grandson />);
    }
}
class Grandson extends Component {render() {let { name } = this.context;return (<div>爷爷叫{name}</div>);
    }
}
Grandson.contextTypes = {name: PropTypes.string
};

  在上面的代码中,创建了三个组件,Grandpa是最上层的父组件(生产者),Son是中间的子组件,Grandson是最下层的孙子组件(消费者)。首先在Grandpa中,声明了一个静态属性childContextTypes和一个getChildContext()方法,这两个是必须的,否则无法实现数据传递。其中childContextTypes是一个对象,它的属性名就是要传递的变量名,而属性值则通过PropTypes指明了该变量的数据类型,getChildContext()方法返回的对象就是要传递的一组变量和它们的值。然后在Son中渲染Grandson组件。最后为Grandson声明一个静态属性contextTypes,同样是个对象,并且属性名和属性值与childContextTypes中的相同。

  第二种方式是在React 16.3的版本中引入的,比起第一种方式,写法更加简洁,并且Context的生产者和消费者都以组件的方式实现,如下所示。

let NameContext = React.createContext({ name });
class Grandpa extends Component {render() {return (<NameContext.Provider value={{name: "strick"}}><Son /></NameContext.Provider>
        );}
}
class Son extends Component {render() {return (<Grandson />);
    }
}
class Grandson extends Component {render() {return (<NameContext.Consumer>{(context) => (<div>爷爷叫{context.name}</div>
                )}</NameContext.Consumer>
        );}
}

  上面的代码依然创建了三个组件,名字也和第一种方式中的相同。除了中间组件Son之外,另外两个组件的内容发生了变化。首先,通过React.createContext()方法创建一个Context对象,此对象包含两个组件:Provider和Consumer,前者是生产者,后者是消费者。然后在Grandpa的render()方法中设置Provider组件的value属性,此属性相当于getChildContext()方法。最后在Grandson组件中调用Context对象,注意,Consumer组件的子节点只能是一个函数。

2)高阶组件

  高阶组件(higher-order component,简称HOC)不是一个真的组件,而是一个函数,它的参数中包含组件,其返回值是一个功能增强的新组件。高阶组件是一个没有副作用的纯函数,它遵循了装饰者模式的设计思想,不会修改传递进来的原组件,而是对其进行包装和拓展,不仅增强了组件的复用性和灵活性,还保持了组件的易用性。下面演示了高阶组件是如何控制props和state的。

class Button extends Component {render() {return (<div><button>{ this.props.txt }</button></div>
        );}
}
//高阶组件
function HOC(Mine) {class Wrapped extends Component {constructor() {super();this.state = {txt: "提交"};}render() {return <Mine {...this.state} />;
        }}return Wrapped;
}
let Wrapped = HOC(Button);

  高阶组件HOC()的函数体中创建了一个名为Wrapped的组件,在它的构造函数中初始化了state状态。然后在其render()方法中使用了{...this.state},这是JSX的一种语法,在state对象前添加扩展运算符,可把它解构成组件的一组属性。最后在Button组件中调用传递进来的属性。

  高阶组件还有迁移重复代码、劫持render()方法和引用refs等功能。

五、后记

  就先整理这些了,如有错误,欢迎指正,后面还会陆续加入漏掉的知识点。

  最后,我想说下,其实自己也是一个React初学者,通过这样的梳理后,对React有了更为深刻的理解,在后续的学习中能容易的吸收新的知识点。

 

源码下载:

https://github.com/pwstrick/react

 

参考资料:

React中文文档

《深入React技术栈》

React.js 小书

React WIKI

《深入浅出React和Redux》 

React入门实例教程 阮一峰

React入门教程

全栈React: 第1天 什么是 React?

深度剖析:如何实现一个 Virtual DOM 算法

從零開始學 ReactJS

react component lifecycle

CSS Modules 入门及 React 中实践

CSS in JS 简介

聊一聊我对 React Context 的理解以及应用

转载于:https://www.cnblogs.com/strick/p/10015551.html

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/450424.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

微信小程序 悬浮按钮

2019独角兽企业重金招聘Python工程师标准>>> 效果视频 https://pan.baidu.com/s/1yfrDaG9YAX0--v0EA3awZA 布局需要按照圆形排列&#xff0c;所以我们需要计算每个点的坐标 代码部分 <view styleposition:fixed; wx:for"{{list}}" wx:for-index"i…

Micronaut教程:如何使用基于JVM的框架构建微服务

\本文要点\\Micronaut是一种基于jvm的现代化全栈框架&#xff0c;用于构建模块化且易于测试的微服务应用程序。\\tMicronaut提供完全的编译时、反射无关的依赖注入和AOP。\\t该框架的开发团队和Grails框架的开发团队是同一个。\\tMicronaut框架集成了云技术&#xff0c;服务发现…

解决Coldfusion连接MySQL数据库的问题

在连接MySQL时&#xff0c;出现了如下错误&#xff1a; Connections to MySQL Community Server are not supported. Please contact MySQL to obtain a MySQL Enterprise or Commercial version. 解决方案&#xff1a; step 1: download the JDBC driver JDBC Driver for MySQ…

C语言union关键字

union 关键字的用法与struct 的用法非常类似。union 维护足够的空间来置放多个数据成员中的“一种”&#xff0c;而不是为每一个数据成员配置空间&#xff0c;在union 中所有的数据成员共用一个空间&#xff0c;同一时间只能储存其中一个数据成员&#xff0c;所有的数据成员具有…

Python学习第一天-第2节

*本节课内容参见&#xff1a;https://www.cnblogs.com/jin-xin/articles/7459977.html运行第一个Python程序 print(hello world) 将文本文件保存为以.py结尾的文件&#xff0c;如hello_world.py &#xff0c;在终端中&#xff0c;运行命令&#xff1a;Python hello_world.py&am…

JDK1.8使用Dubbo时需注意

2019独角兽企业重金招聘Python工程师标准>>> Dubbo自带的很多包都比较旧了&#xff0c;其中的javassist在JDK1.8上运行会报错 而且错误通常比较诡异&#xff0c;javassist是编辑和创建Java字节码的类库&#xff0c;常见的错误会从spring中报出 解决办法&#xff1a;…

深入了解RabbitMQ工作原理及简单使用

深入了解RabbitMQ工作原理及简单使用 RabbitMQ系列文章 RabbitMQ在Ubuntu上的环境搭建深入了解RabbitMQ工作原理及简单使用RabbitMQ交换器Exchange介绍与实践RabbitMQ事务和Confirm发送方消息确认——深入解读使用Docker部署RabbitMQ集群你不知道的RabbitMQ集群架构全解RabbitM…

Spring3.2新注解@ControllerAdvice

前些天发现了一个巨牛的人工智能学习网站&#xff0c;通俗易懂&#xff0c;风趣幽默&#xff0c;忍不住分享一下给大家。点击跳转到教程。 ControllerAdvice&#xff0c;是spring3.2提供的新注解&#xff0c;从名字上可以看出大体意思是控制器增强。让我们先看看ControllerAdv…

C语言关键字

C语言do、while、for关键字—循环 C 语言中循环语句有三种&#xff1a;while 循环、do-while 循环、for 循环。while 循环&#xff1a;先判断while 后面括号里的值&#xff0c;如果为真则执行其后面的代码&#xff1b;否则不执行。while&#xff08;1&#xff09;表示死循环。…

jQuery核心

jQuery(selector) jQuery 的核心功能都是通过这个函数实现的。 jQuery中的一切都基于这个函数&#xff0c;或者说都是在以某种方式使用这个函数。这个函数最基本的用法就是向它传递一个表达式&#xff08;通常由 CSS 选择器组成&#xff09;&#xff0c;然后根据这个表达式来查…

预处理

C语言##预算符 和#运算符一样&#xff0c;##运算符可以用于宏函数的替换部分。这个运算符把两个语言符号组合成单个语言符号。看例子&#xff1a;#define XNAME(n) x ## n如果这样使用宏&#xff1a;XNAME(8)则会被展开成这样&#xff1a;x8看明白了没&#xff1f; ##就是个粘合…

cAdvisor+InfluxDB+Grafana 监控Docker

容器的监控方案其实有很多&#xff0c;有docker自身的docker stats命令、有Scout、有Data Dog等等&#xff0c;本文主要和大家分享一下比较经典的容器开源监控方案组合&#xff1a;cAdvisorInfluxDBGrafan 一、概念 1). InfluxDB是什么nfluxDB是用GO语言编写的一个开源分布式时…

计算机网络知识简单介绍

一、网络基础 1.网络指的是什么&#xff1f; 计算机与计算机之间通过物理链接介质&#xff08;网络设备&#xff09;连接到一起。 计算机与计算机之间基于网络协议通信&#xff08;网络协议就相当于计算机界的英语&#xff09; 2.osi七层协议&#xff1a; 互联网协议按照功能不…

Linux下安装FFmpeg

FFmpeg官网&#xff1a;http://www.ffmpeg.org 官网介绍 FFmpeg is the leading multimedia framework, able to decode, encode, transcode, mux, demux, stream, filter and play pretty much anything that humans and machines have created. It supports the most obscure…

【Python web 开发】viewset 实现商品详情页的接口

我们如何来完成商品详情页的接口呢&#xff1f; 首先要配置一个商品详情的url 按照我们正常的接口配法 &#xff0c;应该是后面要加一个id 的&#xff0c;为什么这里没有加id 呢? ,应该是rooter register 的作用吧&#xff0c;等我在学习一遍基础再来回答&#xff1f; 那么我…

Ignite中的机器学习介绍

为什么80%的码农都做不了架构师&#xff1f;>>> 本系列共6篇文章&#xff0c;会通过一些代码示例&#xff0c;讲解如何在Ignite中使用机器学习库&#xff0c;本文是本系列的第一篇。 从Ignite的2.4版本开始&#xff0c;机器学习就可以用于生产环境了。在这个版本中…

新架构让数据中心犹如PC

摘要&#xff1a;随着VL2网络拓扑结构带来了对等带宽&#xff0c;大量数据可以存放在远方的数据中心&#xff0c;访问起来却犹如它们就在本地&#xff0c;这将对数据中心的架构产生重大影响。Todd Hoff参加了Hot Interconnects大会&#xff0c;对微软VL2架构做了详细解读。CSDN…

mongodb分片概念和原理-实战分片集群

一、分片分片是一种跨多台机器分发数据的方法。MongoDB使用分片来支持具有非常大的数据集和高吞吐量操作的部署。问题&#xff1a;具有大型数据集或高吞吐量应用程序的数据库系统可能会挑战单个服务器的容量。例如&#xff0c;高查询率会耗尽服务器的CPU容量。工作集大小大于系…

加入初创企业需要想清楚的几个问题

摘要&#xff1a;加入一家初创企业是一段充满冒险的旅程。沿途不会都是美景&#xff0c;更别忘了最初的梦想。 去初创公司面试&#xff0c;你一般会纠结于被问到什么问题。但更重要的是问自己&#xff1a;你下定决心在接下来的5年中“从头再来”吗&#xff1f;你能接受这份薪资…

地图市场三足鼎立:诺基亚官方确认与亚马逊合作

摘要&#xff1a;诺基亚确认为亚马逊新推出的平板提供地图服务&#xff0c;至此地图市场“三家分晋”的格局已趋明朗。 路透社之前曾报道称亚马逊在新版Kindle中将使用诺基亚提供的地图服务。但直到今日&#xff0c;这则消息才得到双方的确认。诺基亚方面确认将为亚马逊提供地图…