03-React事件处理 生命周期 Diffing算法

React事件处理

背景

1.通过onXxx属性指定事件处理函数(注意大小写)

  • React使用的是自定义(合成)事件, 而不是使用的原生DOM事件
比如原生onclick的事件在React中变成了onClick,这么搞是为了更好的兼容性
  • React中的事件是通过事件委托方式处理的(委托给组件最外层的元素)
比如,div标签中有input,button等标签,这里面的事件最终都会被委托给最外层的div上

事件委托的原理是事件冒泡,这么做的原因是高效

2.通过event.target得到发生事件的DOM元素对象 ~~~ 不要过度使用ref

受控组件与非受控组件

功能:需求: 定义一个包含表单的组件
输入用户名密码后, 点击登录显示输入的信息
在这里插入图片描述

非受控组件(不推荐)

非受控组件主要是用ref来做管理,而ref获取的是DOM,React官方建议少用ref

比如一个表单,点击button进行提交的这个动作,作为H5的默认动作,默认是不阻止提交的,这个就叫非受控组件

在这里插入图片描述

<script type="text/babel">
    class Login extends React.Component{
        handleSubmit=()=>{
            //阻止默认的表单提交
            event.preventDefault()
            // 解构对象,拿到ref设置的DOM
            // 其实这是一种现用现取的逻辑,所以是非受控组件
           const {username,password} =this
           alert(`${username.value},${password.value}`)
        }
        render(){
            return (
                <div>
                    <form action="www.atguigu.com" onSubmit={this.handleSubmit}>
                        {/*将属性通过ref设置到对象身上,以便使用时获取*/}
                        用户名<input ref={(c)=>this.username=c} type="text" name="username"></input>
                        密码<input ref={(c)=>this.password=c} type="password" name="password"></input>
                        <button>登陆</button>
                    </form>
                </div>
            )
        }
    }
    ReactDOM.render(<Login/>,document.getElementById("test"))
</script>

受控组件(推荐)

页面中所有输入的DOM(input,radio…等等),输入的时候,就把输入的内容,set到state里面,等需要用的时候,再取出来
而不是像非受控组件一样,等到需要用的时候,再去现获取。而且非受控组件写了大量的ref属性,在React看来也是不推荐的写法(类似vue双向绑定)

例子:
在这里插入图片描述
在这里插入图片描述

稍加修改,我们把数据暂存到state里面,用state来暂存可以达到同样的效果
在这里插入图片描述
如果是多个的属性,用ref获得到大量的DOM元素就会很乱,不如统一扔进state更方便

最后代码:

<script type="text/babel">
    class Login extends React.Component{
        //初始化一下state,如果不写也可以
        state={
            username:"",
            password:""
        }

        // 管理表单中的n多个属性
        saveUsername=(event)=>{
            //set的时候用this.setState({key:value})
            this.setState({username:event.target.value})
        }
        savePassword=(event)=>{
            // 注意要用setState的API,如果是this.state就会被认为是更新操作
            this.setState({password:event.target.value})
        }
        showValue=(event)=>{
            //阻止提交后发生跳转
            event.preventDefault()
            // 解构,这时就得到的属性,而不是之前的DOM了
            const {username,password}=this.state
            //所以就不再需要再像ref一样去DOM.value,因为直接获取到的就是属性,而不是DOM
            console.log(username,password)
        }
        render(){
            return (
                <div>
                    <form onSubmit={this.showValue}>
                        {/*每次change的时候都会实时同步到state里面*/}
                        用户名<input onChange={this.saveUsername} type="text" name="username"></input>
                        密码<input onChange={this.savePassword} type="password" name="password"></input>
                        <button>登陆</button>
                    </form>
                </div>
            )
        }
    }
    ReactDOM.render(<Login/>,document.getElementById("test"))
</script>

在这里插入图片描述

着重注意一下这里,其实就是ref 解构出来DOMstate 解构出来属性上的区别
在这里插入图片描述

柯里化概念

只有函数才有柯里化

高阶函数: 如果一个函数符合下面2个规范中的任何一个,那该函数就是高阶函数。

  • 若A函数,接收的参数是一个函数,那么A就可以称之为高阶函数。
  • 若A函数,调用的返回值依然是一个函数,那么A就可以称之为高阶函数。
    常见的高阶函数有: Promise、setTimeout、arr.map()等等

函数的柯里化: 通过函数调用继续返回函数的方式,实现多次接收参数最后统一处理的函数编码形式

高阶函数——函数柯里化

上面的内容其实不难发现,有很大优化空间

比如:
如果有大量的属性,那么复用性很差,有大量冗余,所以不建议这么搞

   // 管理表单中的n多个属性
   saveUsername=(event)=>{
       //set的时候用this.setState({key:value})
       this.setState({username:event.target.value})
   }
   savePassword=(event)=>{
       // 注意要用setState的API,如果是this.state就会被认为是更新操作
       this.setState({password:event.target.value})
   }
<input onChange={this.saveUsername} type="text" name="username"></input>

理所当然的就想着抽共同调用,抽共通的话就需要把当前的key的名字传进去

重点来了

从这样

<input onChange={this.saveUsername} type="text" name="username"></input>

到这样

<input onChange={this.saveUsername("username")} type="text" name="username"></input>

会有一个问题,就是this.saveUsername是一个属性this.saveUsername("username")是一个函数,而这个函数是没有返回值的!
这样就会导致onChange得到的函数return一个undefined。这里的undefined是因为没有标记return

所以怎么办呢,就是把函数的return用箭头函数改造一下!我让return有返回值,但是返回一个空的箭头处理,即有了返回值,又有了处理。

 // 管理表单中的n多个属性
 saveValue = (value) => {
   //这个event是React自动传入,我们无法手动set,所以不能在方法里传入
   return (event) => {
     this.setState({ [value]: event.target.value });
   };
 };
 //调用时传入key
<input onChange={this.saveUsername("username")} type="text" name="username"/>

这里为什么value要用[ ]套一下?

this.setState({ [value]: event.target.value });
这里的value用[]套一下是因为它是当前对象的一个变量,而不是一个字符串。在JavaScript中,当你使用方括号([])来访问对象的属性时,如果属性名是一个变量,那么你需要将变量放在方括号内。这样,你就可以动态地访问和设置对象的属性值。
换句话说,这个方括号([]),直接把value从字符串转换成对象的一个属性了

在这里插入图片描述

贴上完整代码:

<!--JSX转换成JS用的依赖,因为浏览器不认识JSX,只认识JS-->
<script type="text/babel">
  class Login extends React.Component {
    //初始化一下state,如果不写也可以
    state = {
      username: "",
      password: "",
    };

    // 管理表单中的n多个属性
    saveValue = (value) => {
      //这个event是React自动传入,我们直接取值即可
      return (event) => {
        this.setState({ [value]: event.target.value });
      };
    };

    render() {
      return (
        <div>
          <form>
            用户名
            <input
              onChange={this.saveValue("username")}
              type="text"
              name="username"
            ></input>
            密码
            <input
              onChange={this.saveValue("password")}
              type="password"
              name="password"
            ></input>
            <button>登陆</button>
          </form>
        </div>
      );
    }
  }
  ReactDOM.render(<Login />, document.getElementById("test"));
</script>

不用柯里化的写法

不用柯里化对其进行改造,也就是不再采用上面的return箭头函数

关键在于在标签里就把event传进去
改造一下,此时event就直接传入方法了:

<input onChange={(event) => {this.saveValue("username", event)} type="text" name="username" ></input>

saveValue = (value, event) => {
  this.setState({ [value]: event.target.value });
};

测试效果是一样的,好用

全部代码:

<script type="text/babel">
 class Login extends React.Component {
    //初始化一下state,如果不写也可以
    state = {
      username: "",
      password: "",
    };

    // 管理表单中的n多个属性
    saveValue = (value, event) => {
      this.setState({ [value]: event.target.value });
    };

    render() {
      return (
        <div>
          <form>
            用户名
            <input
              onChange={(event) => {
                this.saveValue("username", event);
              }}
              type="text"
              name="username"
            ></input>
            密码
            <input
              onChange={(event) => {
                this.saveValue("password", event);
              }}
              type="password"
              name="password"
            ></input>
            <button>登陆</button>
          </form>
        </div>
      );
    }
  }
  ReactDOM.render(<Login />, document.getElementById("test"));
</script>

React生命周期

React生命周期可以分为旧版和新版,这里旧版生命周期并非弃用,新版只是在旧版生命周期的上面,废弃了三个API,新增了两个API,所以还是有学习旧版生命周期的必要性。

旧版生命周期

可以看到,可以分为两大部分,分别为挂载初始化时组件更新时

render函数贯穿两大部分,因为无论是初始化,还是组件更新,都需要重新渲染,diffing差分等等。

每个部分都有对应的函数供我们使用。

在这里插入图片描述

初始化阶段API(由ReactDOM.render()触发—初次渲染)

主要集中于这四个API,无论代码的顺序如何,都会按照这个生命周期的顺序进行执行。
在这里插入图片描述

  • 1、constructor()
    完成了React数据的初始化,state设值等等。

  • 2、componentWillMount()
    组件已经完成初始化数据,但是还未渲染DOM时执行的逻辑,主要用于服务端渲染,网络请求等。

  • 3、render()
    组件开始渲染真实DOM。

  • 4、componentDidMount()
    组件第一次渲染完成时执行的逻辑,此时DOM节点已经生成了。

代码:

<script type="text/babel">
  class Login extends React.Component {
    constructor(Props) {
      super(Props);
      console.log("constructor 执行");
    }

    componentWillMount() {
      console.log("componentWillMount 执行");
    }

    componentDidMount() {
      console.log("componentDidMount 执行");
    }

    render() {
      console.log("render 执行");
      return <div>123</div>;
    }
  }
  ReactDOM.render(<Login />, document.getElementById("test"));
</script>

执行可以发现,按照生命周期的顺序输出
在这里插入图片描述

更新阶段API(由组件内部this.setSate()或父组件重新render触发)

一般来说,更新阶段API都是在属性变更时触发,比如state属性变化,页面上组件变化,就会触发更新阶段的API
在这里插入图片描述

  • 1、componentWillReceiveProps(nextProps)
    接收父组件新的props时,重新渲染组件执行的逻辑,括号里的参数可以选择接收之后打印一下。注意,这个API在初次接收的时候是不会更新的,只有第二次接收之前才会触发

  • 2、shouldComponentUpdate(nextProps, nextState)
    在setState以后,state发生变化,组件会进入重新渲染的流程时执行的逻辑。在这个生命周期中return false可以阻止组件的更新,主要用于性能优化。

  • 3、componentWillUpdate(nextProps, nextState)
    shouldComponentUpdate返回true以后,组件进入重新渲染的流程时执行的逻辑。

  • 4、render()
    页面渲染执行的逻辑,render函数把jsx编译为函数并生成虚拟dom,然后通过其diff算法比较更新前后的新旧DOM树,并渲染更改后的节点。

  • 5、componentDidUpdate(prevProps, prevState)
    重新渲染后执行的逻辑。

父子组件传值例子:

定义了两个类组件(A组件 , B组件),B组件在A组件内使用,A组件向B组件传值,每次只要值更新,就会触发更新生命周期函数

<script type="text/babel">
  class A extends React.Component {
    // 给state默认值
    state = {
      car: "宝马",
    };
    // 更新传入值
    changeCar = () => {
      this.setState({ car: "奥迪" });
    };

    render() {
      return (
        <div>
          <div>A组件</div>
          <button onClick={this.changeCar}>更新组件,给B传值触发更新</button>
          {"B组件传入A的state属性"}
          <B car={this.state.car} />
        </div>
      );
    }
  }

  class B extends React.Component {
    render() {
      return <div>{this.props.car}</div>;
    }
  }

  ReactDOM.render(<A />, document.getElementById("test"));
引出API

在这个传值的过程中会触发很多生命周期API,挨个试验一下

  • 1、componentWillReceiveProps(nextProps)
    接收父组件新的props时,重新渲染组件执行的逻辑,括号里的参数可以选择接收之后打印一下。注意,这个API在初次接收的时候是不会更新的,只有第二次接收之前才会触发

在这里插入图片描述


  • 2、shouldComponentUpdate(nextProps, nextState) 参数不传也完全可以
    setState操作就会触发这个钩子,,state发生变化,组件会进入重新渲染的流程时执行的逻辑。在这个生命周期中return false或不指定返回内容(默认undefined) 可以阻止组件的更新相当于更新组件的阀门

在这里插入图片描述
稍微修改一下代码,手动return true,就可以继续更新组件了

 shouldComponentUpdate() {
   console.log("shouldComponentUpdate 执行了!");
   return true;
 }

在这里插入图片描述


  • 3、componentWillUpdate(nextProps, nextState)参数不传也完全可以
    shouldComponentUpdate返回true以后,组件进入重新渲染的流程时执行的逻辑。通俗讲就是渲染前的钩子
  • 4、render()
    页面渲染执行的逻辑,render函数把jsx编译为函数并生成虚拟dom,然后通过其diff算法比较更新前后的新旧DOM树,并渲染更改后的节点。
  • 5、componentDidUpdate(prevProps, prevState)参数不传也完全可以
    重新渲染后执行的逻辑。通俗讲就是渲染完毕后的钩子
    在这里插入图片描述

代码(这里只有更新阶段钩子)

<script type="text/babel">
    class A extends React.Component {
      // 给state默认值
      state = {
        car: "宝马",
      };
      // 更新传入值
      changeCar = () => {
        this.setState({ car: "奥迪" });
      };

      shouldComponentUpdate() {
        console.log("A标签的 shouldComponentUpdate 执行了!");
        return true;
      }

      componentWillUpdate() {
        console.log("A标签的 componentWillUpdate 执行了!(组件渲染前)");
        return false;
      }

      componentDidUpdate() {
        console.log("A标签的 componentDidUpdate 执行了!(组件渲染完毕)");
        return false;
      }

      render() {
        console.log("A标签的 render 执行了!");
        return (
          <div>
            <div>A组件{this.state.car}</div>
            <button onClick={this.changeCar}>更新A组件</button>
          </div>
        );
      }
    }
    ReactDOM.render(<A />, document.getElementById("test"));
  </script>
组件卸载(由ReactDOM.unmountComponentAtNode()触发)

最后一个API,在组件卸载之前触发

  • componentWillUnmount()

组件卸载方法:ReactDOM.unmountComponentAtNode()

组件的卸载前执行的逻辑,比如进行“清除组件中所有的setTimeout、setInterval等计时器”或“移除所有组件中的监听器removeEventListener”等操作。

旧版生命周期总结

在这里插入图片描述

1. 初始化阶段: 由ReactDOM.render()触发---初次渲染
		1.	constructor()
		2.	componentWillMount()
		3.	render()
		4.	componentDidMount() =====> 常用
			一般在这个钩子中做一些初始化的事,例如:开启定时器、发送网络请求、订阅消息
2. 更新阶段: 由组件内部this.setSate()或父组件render触发
		1.	shouldComponentUpdate()
		2.	componentWillUpdate()
		3.	render() =====> 必须使用的一个,不渲染没法显示
		4.	componentDidUpdate()
3. 卸载组件: 由ReactDOM.unmountComponentAtNode()触发
		1.	componentWillUnmount()  =====> 常用
			一般在这个钩子中做一些收尾的事,例如:关闭定时器、取消订阅消息

新旧生命周期对比

新版本生命周期相对于旧版本,废弃了三个带will的API(componentWillMount(),componentWillReceiveProps(),componentWillUpdate())
新增了两个API static getDerivedStateFromProps(),getSnapshotBeforeUpdate()

在这里插入图片描述
注意:对于已经过时的API不会马上废弃,而是在控制台进行Warning提醒,并且在后续的React版本中,如果非要使用过时的API,就必须在API的前缀上加入UNSAFE_前缀,作为提醒。
比如,从React17版本开始就得加入前缀:
在这里插入图片描述

注意,这里的API UNSAFE并不是说这个API就会有安全问题,而是说在未来的预计更新中有概率出现问题。
比如现在切换到React 17版本,再使用过期API就会有提示
在17版本下,使用过时的componentWillMount,PS:这里选的是不需要条件就可以触发的API,另外两个过时的API触发都需要条件

 componentWillMount() {
   console.log("componentWillMount执行");
 }

在这里插入图片描述

这几个UNSAFE_ 的API本身用的频率就很低,所以了解一下即可

新版生命周期

初始化阶段API

在这里插入图片描述


  • 1、constructor()

完成了React数据的初始化,state设值等等。之前写过就不赘述了


  • 2、static getDerivedStateFromProps()

首先这个组件是静态的,如果不用static,就会报错。看控制台报错,说明这个方法不属于对象,需要用static来进行声明
在这里插入图片描述

组件挂载阶段render前的最后一次调用,并且在初始挂载及后续更新时都会被调用。适用于第一次的初始化组件以及后续的更新过程中(包括自身状态更新以及父传子)。返回一个state就更新state,返回一个null就不做更新动作

可以传入props和state

static getDerivedStateFromProps(props,state){
	console.log('getDerivedStateFromProps',props,state);
	return null
}

在这里插入图片描述

如果这个位置返回一个固定的state的对象,那么这个return的值就会一直影响state,导致其无法更新,因为其return的值是一个固定的state。那肯定就更新不了state了。

 static getDerivedStateFromProps(props, state) {
   console.log("getDerivedStateFromProps", props, state);
   return {"key":"value"};
 }

举一个props影响state的例子,用react的官方例子:
在这里插入图片描述
在这里插入图片描述


  • 3.render()

组件挂载依靠这个api,不render就不会重新渲染,之前说过,这里不赘述了


  • 4.componentDidMount()

组件挂载完毕之后触发的,也就是render之后

//组件挂载完毕的钩子
componentDidMount(){
	console.log('Count---componentDidMount');
}

在这里插入图片描述

更新阶段API

主要集中在这5个钩子
在这里插入图片描述


  • 1.getDerivedStateFromProps()
    贯穿于组件挂载阶段和更新阶段的API,React 会在初始挂载和后续更新时调用 render 之前调用它。它应该返回一个对象来更新 state,或者返回 null 就不更新任何内容。

比如我想做一个点击按钮就+1的,更新state就会触发组件更新,就会触发这个API
在这里插入图片描述

<script type="text/babel">
	//创建组件
	class Count extends React.Component{
		//构造器
		constructor(props){
			console.log('Count---constructor');
			super(props)
			//初始化状态
			this.state = {count:0}
		}

		//加1按钮的回调
		add = ()=>{
			//获取原状态
			const {count} = this.state
			//更新状态
			this.setState({count:count+1})
		}
		
		//若state的值在任何时候都取决于props,那么可以使用getDerivedStateFromProps
		static getDerivedStateFromProps(props,state){
			console.log('getDerivedStateFromProps',props,state);
			return null
		}

		render(){
			console.log('Count---render');
			const {count} = this.state
			return(
				<div>
					<h2>当前求和为:{count}</h2>
					<button onClick={this.add}>点我+1</button>
				</div>
			)
		}
	}
	
	//渲染组件
	ReactDOM.render(<Count count={199}/>,document.getElementById('test'))
</script>

  • 2.shouldComponentUpdate(nextProps, nextState)

和老版本的那个一样,当 props 或 state 发生变化时,shouldComponentUpdate() 会在渲染执行之前被调用。默认返回为true,返回false则阻止更新

控制组件自身或者子组件是否需要更新,尤其在子组件非常多的情况下
在之前的触发state更新的基础上加入API,查看更新时效果

shouldComponentUpdate(props, state) {
  console.log("shouldComponentUpdate 执行", props, state);
  // return false阻止更新
  return false;
}

在这里插入图片描述

如果改为return true,那么就会没有问题,继续让state更新

shouldComponentUpdate(props, state) {
  console.log("shouldComponentUpdate 执行", props, state);
  // return true继续更新
  return true;
}

在这里插入图片描述


  • 3.render()

这个没啥好说的, 前面的"阀门API"如果调用了,并且都return true了 render就会重新执行,如果不调用那就无所谓了,不会影响render()。
如果反过来, 前面的"阀门API"如果调用了,并且return false了,render后续就无法执行。


  • 4.getSnapshotBeforeUpdate()

在最后一次渲染(提交到dom节点)之前调用,getSnapshotBeforeUpdate(prevProps,prevState,),这两个参数就是DOM更新前的参数。
在更新之前获取快照,返回值传递给componentDidUpdate(prevProps,prevState,?snapshotValue)的snapshotValue上面。这个"快照"指的是在组件更新之前捕获的某个状态state或数据props的瞬时影像,可以取这个快照里对象的某一个属性,也可以return一个任意的数值。

如果单用这个getSnapshotBeforeUpdate(),是不行的,要搭配componentDidUpdate()使用,要接收参数的

如果单用getSnapshotBeforeUpdate()的话,控制台就会报警
在这里插入图片描述
两个搭配在一起使用

//在更新之前,render之后获取快照
getSnapshotBeforeUpdate(prevProps,prevState){
	console.log('getSnapshotBeforeUpdate');
	return 'atguigu'
}

//组件挂载完毕的钩子
componentDidUpdate(prevProps,precState,snapshot){
	console.log('componentDidUpdate 执行!',"getSnapshotBeforeUpdate传入的参数",snapshot);
}

在这里插入图片描述


  • 5.componentDidUpdate()

组件更新后触发的函数,和旧版本一样,这里先讨论单独使用componentDidUpdate()的场景
触发一下组件更新操作,触发API
在这里插入图片描述

如果是和getSnapshotBeforeUpdate()配合使用的话,我们将获取到其返回值

 // // 在更新之前,render之后获取快照
 getSnapshotBeforeUpdate(prevProps, prevState) {
   console.log("getSnapshotBeforeUpdate");
   return "atguigu";
 }

 // //组件挂载完毕的钩子
 componentDidUpdate(prevProps, precState, snapshot) {
   console.log("componentDidUpdate 执行 组件更新完毕", snapshot);
 }

点击更新操作
在这里插入图片描述


最后验证一下新版本生命周期钩子的执行顺序
在这里插入图片描述

组件卸载(由ReactDOM.unmountComponentAtNode()触发)
  • componentWillUnmount()

在组件卸载之前触发

组件卸载方法:ReactDOM.unmountComponentAtNode(),但是已经在18版本被取代
在这里插入图片描述
例子:

<script type="text/babel">
  class Count extends React.Component {
    componentWillUnmount() {
      console.log("componentWillUnmount 执行,组件即将卸载");
    }

    unMount=()=>{
      ReactDOM.unmountComponentAtNode(document.getElementById("test"))
    }

    render() {
      return <div><button onClick={this.unMount}>卸载组件</button></div>;
    }
  }

  //渲染组件
  ReactDOM.render(<Count />, document.getElementById("test"));
</script>

在这里插入图片描述

单击button,组件就会卸载,在真正卸载之前就会触发componentWillUnmount()执行
在这里插入图片描述

虚拟DOM与DOM Diffing算法

颗粒度:DOM Diffing算法对比的最小粒度是标签,且逐层对比
在这里插入图片描述

  • diffing算法应用在 react / vue 中,用于比较虚拟DOM和真实DOM。
  • 虚拟DOM中采用的算法,把树形结构按照层级分解,只比较同级元素,不同层级的节点只有创建和删除操作。
  • diffing算法会从根节点开始,一层层的向下比较,如果在某一层的某个节点发现不同了,他就会直接替换这个节点下面的所有子树。
  • 渲染真实DOM所消耗的性能是很大的,很多操作都会导致页面重新渲染。 通过diff算法对比新旧vdom之间的差异,可以最小化的执行dom操作,从而提高代码性能。

Diffing算法简单解析

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

小程序如何设置自取模式下的服务方式

设置自取模式下的服务方式是非常重要的&#xff0c;尤其是对于到店自取和到店堂食这两种不同的服务模式。下面我们就来介绍一下如何在小程序中设置这两种服务方式。 在小程序管理员后台->配送设置处&#xff0c;在服务方式处&#xff0c;设置自取情况下的服务方式。默认是&…

深度学习检测小目标常用方法

前言 在深度学习目标检测中&#xff0c;特别是人脸检测中&#xff0c;小目标、小人脸的检测由于分辨率低&#xff0c;图片模糊&#xff0c;信息少&#xff0c;噪音多&#xff0c;所以一直是一个实际且常见的困难问题。不过在这几年的发展中&#xff0c;也涌现了一些提高小目标…

Docker学习——⑤

文章目录 1、什么是Docker Container&#xff08;容器&#xff09;2、容器的生命周期2.1 容器 OOM2.2 容器异常退出2.3 容器暂停 3、容器命令详解4、容器操作案例4.1 容器批量处理技巧4.2 容器交互模式4.3 容器自动重启4.4 容器环境变量配置 5、综合实战5.1 Mysql 容器化安装5.…

Python基础教程之十六:Python multidict示例–将单个键映射到字典中的多个值

1.什么是multidict词典> 在python中&#xff0c;“ multidict ”一词用于指代字典&#xff0c;在字典中可以将单个键映射到多个值。例如 多重结构 multidictWithList {key1 : [1, 2, 3],key2 : [4, 5]}multidictWithSet {key1 : {1, 2, 3},key2 : {4, 5}}1. list如果要…

霸榜双11!科技创新助力九牧卫浴赢战全渠道

文 | 螳螂观察 作者 | 余一 双11&#xff0c;这个一年一度的全民购物节&#xff0c;再一次将市场的消费情绪推到顶点。然而双11对于消费者来说是一次狂欢节&#xff0c;但对于品牌方来说则相当于一次“期末考试”。 回顾历年双11&#xff0c;能够拔得头筹的无疑都是行业内的…

Spring 常见面试题

1、Spring概述 1.1、Spring是什么? Spring是一个轻量级Java开发框架,目的是为了解决企业级应用开发的业务逻辑层和其他各层的耦合问题Spring最根本的使命是解决企业级应用开发的复杂性&#xff0c;即简化Java开发。这些功能的底层都依赖于它的两个核心特性&#xff0c;也就是…

Unity--UGUI创建基本的UI

随着UI系统的引入&#xff0c;已添加了新组件&#xff0c;这些组件将有助于创建特定于GUI的功能。其中一些元素包括文本&#xff0c;图像&#xff0c;按钮等。在本教程中&#xff0c;您将学习创建和使用基本UI。 1.创建基本的UI 通过Unity的用户界面&#xff08;UI&#xff09;…

98 多数元素

多数元素 题解1 哈希表题解2 Boyer-Moore 投票算法 给定一个大小为 n 的数组 nums &#xff0c;返回其中的多数元素。多数元素是指在数组中出现次数 大于 ⌊ n / 2 ⌋ ⌊ n/2 ⌋ ⌊n/2⌋ 的元素。 你可以假设数组是非空的&#xff0c;并且给定的数组总是存在多数元素。 示例…

图解电商系统的架构演进

具体以商城为例&#xff0c; 展示web端应用的架构演变过程。 特点&#xff1a; 1、所有的功能集成在一个项目工程中。 2、所有的功能打在一个war包部署到服务器。 3、通过部署应用集群和数据库集群来提高系统的性能。 优点 1、项目架构简单&#xff0c;前期开发成本低&#xf…

面试了8位00后,我是真的有被震惊到~

听人劝、吃饱饭,奉劝各位小伙伴,不要订阅该文所属专栏。 作者:不渴望力量的哈士奇(哈哥),十余年工作经验, 跨域学习者,从事过全栈研发、产品经理等工作,现任研发部门 CTO 。荣誉:2022年度博客之星Top4、博客专家认证、全栈领域优质创作者、新星计划导师,“星荐官共赢计…

深度学习(生成式模型)——Classifier Guidance Diffusion

文章目录 前言问题建模条件扩散模型的前向过程条件扩散模型的反向过程条件扩散模型的训练目标 前言 几乎所有的生成式模型&#xff0c;发展到后期都需要引入"控制"的概念&#xff0c;可控制的生成式模型才能更好应用于实际场景。本文将总结《Diffusion Models Beat …

OAuth2.0双令牌

OAuth 2.0是一种基于令牌的身份验证和授权协议&#xff0c;它允许用户授权第三方应用程序访问他们的资源&#xff0c;而不必共享他们的凭据。 在OAuth 2.0中&#xff0c;通常会使用两种类型的令牌&#xff1a;访问令牌和刷新令牌。访问令牌是用于访问资源的令牌&#xff0c;可…

STM32笔记—DMA

目录 一、DMA简介 二、DMA主要特性 三、DMA框图 3.1 DMA处理 3.2 仲裁器 3.3 DMA通道 扩展: 断言&#xff1a; 枚举&#xff1a; 3.4 可编程的数据传输宽度、对齐方式和数据大小端 3.5 DMA请求映像 四、DMA基本结构 4.1 DMA_Init配置 4.2 实现DMAADC扫描模式 实现要求…

从黑白电视到《孤注一掷》,聊聊冰山下的高清技术

点击文末“阅读原文”即可参与节目互动 剪辑、音频 / 卷圈 运营 / SandLiu 卷圈 监制 / 姝琦 产品统筹 / bobo 场地支持 / 声湃轩北京录音间 联合制作 / RTE开发者社区 电影《孤注一掷》的制作&#xff0c;为什么需要借助 AI 实现高清化&#xff1f;高清与实时高清&#…

程序员35岁之后如何规划?建议收藏!

文章目录 一、年纪大能不能进大厂&#xff1f;二、为什么说35是危机&#xff1f; 1.精力衰退2.脑力衰退3.知识/技术迭代 三、年龄大的程序员有哪些出路&#xff1f; 1.技术管理2.创业3.技术外包4.做老师5.做自媒体6.写书 四、结语 我自己今年已有44了&#xff0c;从2021年开始…

Unity Mirror学习(一) SyncVars特性使用

官网中所说的网络对象&#xff0c;指的是挂了 NetworkIdentity组件的对象 官网中所说的玩家对象&#xff0c;指的是NetworkManager脚本上的PlayerPrefab预制体 这个概念对阅读官网文档很重要&#xff0c;我刚开始并不理解&#xff0c;走了歪路 SyncVars&#xff08;同步变量&a…

使用Plsql+oracle client 连接 Oracle数据库

2011年入职老东家X煤集团的时候&#xff0c;在csnd上写了一篇blog&#xff0c;题目叫“什么是ERP”&#xff0c;从此跳入DBA了这个烂坑&#xff0c;目前公司的数据库一部分是Oracle&#xff0c;另一部分是MySQL的&#xff0c;少量MSSQL&#xff0c;还需要捡起来一部分&#xff…

2023.11.7: OpenAI DevDay总结

New Model&#xff1a;ChatGPT4.0 turbo 更长的context&#xff1a;支持长达128000个tokens的context 更好的控制方案&#xff1a; 更有利于API调用JSON Mode Function calling Reproducible outputs 通过一个seed使得模型的回答总是保持一致 Better Knowledge 支持知识检索…

vue-cal 使用教程

目录 0. 介绍及效果展示 1.vue2环境安装 2.页面引入 3.使用 4.效果图 0. 介绍及效果展示 vue-cal 组件比较灵活&#xff0c;可以随意切换年、月、周、日、时间历图&#xff0c;放几张截图看下效果 1.vue2环境安装 vue3直接可以看本文最下方的API&#xff0c;有详解 npm …

【Unity ShaderGraph】| 物体靠近时局部溶解,根据坐标控制溶解的位置【文末送书】

前言 【Unity ShaderGraph】| 物体靠近时局部溶解&#xff0c;根据坐标控制溶解的位置一、效果展示二、根据坐标控制溶解的位置&#xff0c;物体靠近局部溶解三、应用实例&#x1f451;评论区抽奖送书 前言 本文将使用ShaderGraph制作一个根据坐标控制溶解的位置&#xff0c;物…