当前位置: 首页 > news >正文

React16源码: React.Children源码实现

React.Children


1 ) 概述

  • 这个API用的也比较的少,因为大部分情况下,我们不会单独去操作children
  • 我们在一个组件内部拿到 props 的时候,我们有props.children这么一个属性
  • 大部分情况下,直接把 props.children 把它渲染到我们的jsx 里面就可以了
  • 很少有情况需要去操作一下这个children,但是一旦需要去操作这个children呢
    • 直接使用react点children的API,而不是你直接去操作dom
    • 大部分时候拿到的 children,可能是一个合理的react element,或者是一个数组
  • React提供Children这个API去操作它,一定是有一个合理的原因的

2 )示例演示

import React from 'react'function ChildrenDemo(props) {console.log(props.children)console.log(React.Children.map(props.children, c => [c, c]))return props.children
}export default () => (<ChildrenDemo><span>1</span><span>2</span></ChildrenDemo>
)
  • 上面这个代码非常简单,创建了一个组件叫 ChildrenDemo
    • 里面有两个 span 作为children,在 props.children 里面,就可以拿到
  • 第一个打印出来的就是 props.children
    • 它就是两个 react element 节点
  • 第二个打印的是 map 的返回值
    • 我们通过react.children.map, 传入这个props.children 和一个callback
    • 这个callback,返回的是一个数组, 这个数组里面,包含两个相同的节点
      • 那这时候打印出来的是4个节点
      • 也就是每个span都被克隆成2份,2个span是4份
      • 前两个children 都是1,后两个都是2
    • 再来改一下 console.log(React.Children.map(props.children, c => [c, [c, c]]))
      • 它会输出六个节点
      • 0, 1, 2,的children是 1
      • 3, 4, 5 的 children 是2
      • 也就是说 react.children的map function返回的是一个数组,它会继续把它展开
      • 里面不管传了多少层嵌套的数组,最终都会展开成一层数组,即: 被拍平
    • 拍平后有几个元素,map中的当前child就会被克隆成几份
  • 这就是 React.Children.map,跟普通原生的数组.map 的一个本质区别

3 )源码分析

定位到 React.js 中

const React = {Children: {map,forEach,count,toArray,only,},// ... 省略其他
};
  • 这个对象里面有五个函数,跟原生数组操作非常的像
  • 前两个是最重要的,就是map 和 forEach, 它和数组的意义是一样的
  • 但它实际的操作可能跟数组的map和forEach会有一定的区别
  • map是这些方法所有逻辑里面最复杂的一个,而 map 和 forEach 是差不多的
    • 它们唯一的区别是一个有返回一个没有返回
    • map是通过我们传入的一个方法之后,返回的一个新的数组
    • 而forEach 中只在 null 的判断中返回,其实并非真实的返回值

再定位到 ReactChildren.js 中

/*** Copyright (c) Facebook, Inc. and its affiliates.** This source code is licensed under the MIT license found in the* LICENSE file in the root directory of this source tree.*/import invariant from 'shared/invariant';
import warning from 'shared/warning';
import {getIteratorFn,REACT_ELEMENT_TYPE,REACT_PORTAL_TYPE,
} from 'shared/ReactSymbols';import {isValidElement, cloneAndReplaceKey} from './ReactElement';
import ReactDebugCurrentFrame from './ReactDebugCurrentFrame';const SEPARATOR = '.';
const SUBSEPARATOR = ':';/*** Escape and wrap key so it is safe to use as a reactid** @param {string} key to be escaped.* @return {string} the escaped key.*/
function escape(key) {const escapeRegex = /[=:]/g;const escaperLookup = {'=': '=0',':': '=2',};const escapedString = ('' + key).replace(escapeRegex, function(match) {return escaperLookup[match];});return '$' + escapedString;
}/*** TODO: Test that a single child and an array with one item have the same key* pattern.*/let didWarnAboutMaps = false;const userProvidedKeyEscapeRegex = /\/+/g;
function escapeUserProvidedKey(text) {return ('' + text).replace(userProvidedKeyEscapeRegex, '$&/');
}const POOL_SIZE = 10;
const traverseContextPool = [];
function getPooledTraverseContext(mapResult,keyPrefix,mapFunction,mapContext,
) {if (traverseContextPool.length) {const traverseContext = traverseContextPool.pop();traverseContext.result = mapResult;traverseContext.keyPrefix = keyPrefix;traverseContext.func = mapFunction;traverseContext.context = mapContext;traverseContext.count = 0;return traverseContext;} else {return {result: mapResult,keyPrefix: keyPrefix,func: mapFunction,context: mapContext,count: 0,};}
}function releaseTraverseContext(traverseContext) {traverseContext.result = null;traverseContext.keyPrefix = null;traverseContext.func = null;traverseContext.context = null;traverseContext.count = 0;if (traverseContextPool.length < POOL_SIZE) {traverseContextPool.push(traverseContext);}
}/*** @param {?*} children Children tree container.* @param {!string} nameSoFar Name of the key path so far.* @param {!function} callback Callback to invoke with each child found.* @param {?*} traverseContext Used to pass information throughout the traversal* process.* @return {!number} The number of children in this subtree.*/
function traverseAllChildrenImpl(children,nameSoFar,callback,traverseContext,
) {const type = typeof children;if (type === 'undefined' || type === 'boolean') {// All of the above are perceived as null.children = null;}let invokeCallback = false;if (children === null) {invokeCallback = true;} else {switch (type) {case 'string':case 'number':invokeCallback = true;break;case 'object':switch (children.$$typeof) {case REACT_ELEMENT_TYPE:case REACT_PORTAL_TYPE:invokeCallback = true;}}}if (invokeCallback) {callback(traverseContext,children,// If it's the only child, treat the name as if it was wrapped in an array// so that it's consistent if the number of children grows.nameSoFar === '' ? SEPARATOR + getComponentKey(children, 0) : nameSoFar,);return 1;}let child;let nextName;let subtreeCount = 0; // Count of children found in the current subtree.const nextNamePrefix =nameSoFar === '' ? SEPARATOR : nameSoFar + SUBSEPARATOR;if (Array.isArray(children)) {for (let i = 0; i < children.length; i++) {child = children[i];nextName = nextNamePrefix + getComponentKey(child, i);subtreeCount += traverseAllChildrenImpl(child,nextName,callback,traverseContext,);}} else {const iteratorFn = getIteratorFn(children);if (typeof iteratorFn === 'function') {if (__DEV__) {// Warn about using Maps as childrenif (iteratorFn === children.entries) {warning(didWarnAboutMaps,'Using Maps as children is unsupported and will likely yield ' +'unexpected results. Convert it to a sequence/iterable of keyed ' +'ReactElements instead.',);didWarnAboutMaps = true;}}const iterator = iteratorFn.call(children);let step;let ii = 0;while (!(step = iterator.next()).done) {child = step.value;nextName = nextNamePrefix + getComponentKey(child, ii++);subtreeCount += traverseAllChildrenImpl(child,nextName,callback,traverseContext,);}} else if (type === 'object') {let addendum = '';if (__DEV__) {addendum =' If you meant to render a collection of children, use an array ' +'instead.' +ReactDebugCurrentFrame.getStackAddendum();}const childrenString = '' + children;invariant(false,'Objects are not valid as a React child (found: %s).%s',childrenString === '[object Object]'? 'object with keys {' + Object.keys(children).join(', ') + '}': childrenString,addendum,);}}return subtreeCount;
}/*** Traverses children that are typically specified as `props.children`, but* might also be specified through attributes:** - `traverseAllChildren(this.props.children, ...)`* - `traverseAllChildren(this.props.leftPanelChildren, ...)`** The `traverseContext` is an optional argument that is passed through the* entire traversal. It can be used to store accumulations or anything else that* the callback might find relevant.** @param {?*} children Children tree object.* @param {!function} callback To invoke upon traversing each child.* @param {?*} traverseContext Context for traversal.* @return {!number} The number of children in this subtree.*/
function traverseAllChildren(children, callback, traverseContext) {if (children == null) {return 0;}return traverseAllChildrenImpl(children, '', callback, traverseContext);
}/*** Generate a key string that identifies a component within a set.** @param {*} component A component that could contain a manual key.* @param {number} index Index that is used if a manual key is not provided.* @return {string}*/
function getComponentKey(component, index) {// Do some typechecking here since we call this blindly. We want to ensure// that we don't block potential future ES APIs.if (typeof component === 'object' &&component !== null &&component.key != null) {// Explicit keyreturn escape(component.key);}// Implicit key determined by the index in the setreturn index.toString(36);
}function forEachSingleChild(bookKeeping, child, name) {const {func, context} = bookKeeping;func.call(context, child, bookKeeping.count++);
}/*** Iterates through children that are typically specified as `props.children`.** See https://reactjs.org/docs/react-api.html#reactchildrenforeach** The provided forEachFunc(child, index) will be called for each* leaf child.** @param {?*} children Children tree container.* @param {function(*, int)} forEachFunc* @param {*} forEachContext Context for forEachContext.*/
function forEachChildren(children, forEachFunc, forEachContext) {if (children == null) {return children;}const traverseContext = getPooledTraverseContext(null,null,forEachFunc,forEachContext,);traverseAllChildren(children, forEachSingleChild, traverseContext);releaseTraverseContext(traverseContext);
}function mapSingleChildIntoContext(bookKeeping, child, childKey) {const {result, keyPrefix, func, context} = bookKeeping;let mappedChild = func.call(context, child, bookKeeping.count++);if (Array.isArray(mappedChild)) {mapIntoWithKeyPrefixInternal(mappedChild, result, childKey, c => c);} else if (mappedChild != null) {if (isValidElement(mappedChild)) {mappedChild = cloneAndReplaceKey(mappedChild,// Keep both the (mapped) and old keys if they differ, just as// traverseAllChildren used to do for objects as childrenkeyPrefix +(mappedChild.key && (!child || child.key !== mappedChild.key)? escapeUserProvidedKey(mappedChild.key) + '/': '') +childKey,);}result.push(mappedChild);}
}function mapIntoWithKeyPrefixInternal(children, array, prefix, func, context) {let escapedPrefix = '';if (prefix != null) {escapedPrefix = escapeUserProvidedKey(prefix) + '/';}const traverseContext = getPooledTraverseContext(array,escapedPrefix,func,context,);traverseAllChildren(children, mapSingleChildIntoContext, traverseContext);releaseTraverseContext(traverseContext);
}/*** Maps children that are typically specified as `props.children`.** See https://reactjs.org/docs/react-api.html#reactchildrenmap** The provided mapFunction(child, key, index) will be called for each* leaf child.** @param {?*} children Children tree container.* @param {function(*, int)} func The map function.* @param {*} context Context for mapFunction.* @return {object} Object containing the ordered map of results.*/
function mapChildren(children, func, context) {if (children == null) {return children;}const result = [];mapIntoWithKeyPrefixInternal(children, result, null, func, context);return result;
}/*** Count the number of children that are typically specified as* `props.children`.** See https://reactjs.org/docs/react-api.html#reactchildrencount** @param {?*} children Children tree container.* @return {number} The number of children.*/
function countChildren(children) {return traverseAllChildren(children, () => null, null);
}/*** Flatten a children object (typically specified as `props.children`) and* return an array with appropriately re-keyed children.** See https://reactjs.org/docs/react-api.html#reactchildrentoarray*/
function toArray(children) {const result = [];mapIntoWithKeyPrefixInternal(children, result, null, child => child);return result;
}/*** Returns the first child in a collection of children and verifies that there* is only one child in the collection.** See https://reactjs.org/docs/react-api.html#reactchildrenonly** The current implementation of this function assumes that a single child gets* passed without a wrapper, but the purpose of this helper function is to* abstract away the particular structure of children.** @param {?object} children Child collection structure.* @return {ReactElement} The first and only `ReactElement` contained in the* structure.*/
function onlyChild(children) {invariant(isValidElement(children),'React.Children.only expected to receive a single React element child.',);return children;
}export {forEachChildren as forEach,mapChildren as map,countChildren as count,onlyChild as only,toArray,
};
  • 翻到最下面,看到 mapChildren as map,这边 export 出去的是 map

  • 对应的,我们来看 mapchildren 这个方法

    /*** Maps children that are typically specified as `props.children`.** See https://reactjs.org/docs/react-api.html#reactchildrenmap** The provided mapFunction(child, key, index) will be called for each* leaf child.** @param {?*} children Children tree container.* @param {function(*, int)} func The map function.* @param {*} context Context for mapFunction.* @return {object} Object containing the ordered map of results.*/
    function mapChildren(children, func, context) {if (children == null) {return children;}const result = [];mapIntoWithKeyPrefixInternal(children, result, null, func, context);return result;
    }
    
    • 开始会调用一个方法叫 mapIntoWithKeyPrefixInternal

       function mapIntoWithKeyPrefixInternal(children, array, prefix, func, context) {let escapedPrefix = '';if (prefix != null) {escapedPrefix = escapeUserProvidedKey(prefix) + '/';}const traverseContext = getPooledTraverseContext(array,escapedPrefix,func,context,);traverseAllChildren(children, mapSingleChildIntoContext, traverseContext);releaseTraverseContext(traverseContext);
      }
      
    • 代码上是先处理了一下 escapedPrefix, 这个倒没什么,后面调用的方法和 forEachChildren 是差不多的

    • 进入这里的 getPooledTraverseContext 方法

    • 它先判断是否已有存在池中是否节点,如果有,则pop一个

    • 并将传入的内容都挂载到这个pop出来的对象上面,用于记录

    • 再经过一系列作用之后,执行到上面的 releaseTraverseContext 就是对对象进行清空

    • 上面的过程涉及到了一个对象池的概念,也就是缓存池,用于节省操作的性能

      • js是单线程语言,对大量对象进行操作,比如挂载和删除,可能会造成内存抖动的问题
      • 可能导致浏览器内的页面性能很差
      • 它设置Pool Size的大小是 10,是一个渐进的过程
      • 一开始是空的,随着对象的创建会进行缓存,接着复用
    • 总体来说,它会做一个非常重要的事情,就是到一个叫做 contextPool 的地方去获取一个 context

    • 接下去所有流程都是在这个函数里面调用了 traverseAllChildren 这个方法

    • 调用完所有的方法之后,它会把这个context再返回到这个 contextPool 里面

    • 调用的 traverseAllChildren 方法没有什么操作,本质上调了 traverseAllChildrenImpl 的方法

      /*** Traverses children that are typically specified as `props.children`, but* might also be specified through attributes:** - `traverseAllChildren(this.props.children, ...)`* - `traverseAllChildren(this.props.leftPanelChildren, ...)`** The `traverseContext` is an optional argument that is passed through the* entire traversal. It can be used to store accumulations or anything else that* the callback might find relevant.** @param {?*} children Children tree object.* @param {!function} callback To invoke upon traversing each child.* @param {?*} traverseContext Context for traversal.* @return {!number} The number of children in this subtree.*/
      function traverseAllChildren(children, callback, traverseContext) {if (children == null) {return 0;}return traverseAllChildrenImpl(children, '', callback, traverseContext);
      }
      
    • 进入 traverseAllChildrenImpl 这个方法会判断我们的children是否是一个数组或者是一个iterator对象

    • 这代表它们是多个节点是可以遍历的, 如果它是多个节点,它会去循环每一个节点

    • 然后对每一个节点再重新调用这个 traverseAllChildrenImpl 这个方法, 也就是递归实现

    • 最终要传入这个 traverseAllChildrenImpl 方法的children,是以单个节点的时候

    • 才会去执行真正的 mapSingleChildIntoContext 方法, 在这个方法里面会调用

    • React.Children.map 传入的第二个参数,也就是那个map function

    • 它会传入上面遍历出来的最终的单个节点,返回想要的map结果的一个数据

    • 拿到一个map数据之后,它会进行一个判断,是否是数组,如果不是数组

    • 它会在result中插入克隆节点,并替换key,防止有相同的key出现

    • 如果是数组的话,又会回过头来去调用这个 mapIntoWithKeyPrefixInternal,到这里完成了一个大的递归

    • 在这么一个递归的过程下去,最终是把里面返回的所有层级的数组都进行了一个展开

    • 展开之后就变成了一个一维数组, 这就是它的一个整体的流程

  • 然后再来对比一下 forEachChildren

    /**
    * Iterates through children that are typically specified as `props.children`.
    *
    * See https://reactjs.org/docs/react-api.html#reactchildrenforeach
    *
    * The provided forEachFunc(child, index) will be called for each
    * leaf child.
    *
    * @param {?*} children Children tree container.
    * @param {function(*, int)} forEachFunc
    * @param {*} forEachContext Context for forEachContext.
    */
    function forEachChildren(children, forEachFunc, forEachContext) {if (children == null) {return children;}const traverseContext = getPooledTraverseContext(null,null,forEachFunc,forEachContext,);traverseAllChildren(children, forEachSingleChild, traverseContext);releaseTraverseContext(traverseContext);
    }
    
    • 可以看到它最后没有 return,这就是 forEachChildrenmapChildren 的本质区别
  • 关于export 出去的 toArray

    function toArray(children) {const result = [];mapIntoWithKeyPrefixInternal(children, result, null, child => child);return result;
    }
    
    • toArraymapChildren 唯一的区别就是 map function
    • 换句话说,它的map function,其实就是 child => child
    • 它其实也会把数组展开,只是说没有map的过程
  • 还有 export 出去的 onlyChild

    function onlyChild(children) {invariant(isValidElement(children),'React.Children.only expected to receive a single React element child.',);return children;
    }
    
    • 其实就是判断一下这个children是否是单个的合理的 react element 节点
    • 如果是的话,就返回,不是的话,给出提醒
  • 最后 export 出去的 countChildren

    function countChildren(children) {return traverseAllChildren(children, () => null, null);
    }
    
    • 内部调用 traverseAllChildren, 本质上还是调用 traverseAllChildrenImpl
    • 最终返回的是统计后的值 subtreeCount
  • 最后还有一个 节点 key 相关的处理,主要核心实现是在 getComponentKey 也是个递归的处理

    • 打印出的每个节点上,都会有一个key,这个key的处理也是比较核心的
    • 参考 ChildrenDemo中的 React.Children.map 中的回调 c => [c, [c,c]] 这里会总计打印出6个节点
      • 可以看到第一个节点是 .0/.0
      • 然后第二个节点是 .0/.1:0
      • 然后第三个节点是 .0/.1:1
    • 可以按照上述函数和顶层声明的两个变量 SEPARATORSUBSEPARATOR
    • 理解下这个打印出的结果

相关文章:

React16源码: React.Children源码实现

React.Children 1 ) 概述 这个API用的也比较的少&#xff0c;因为大部分情况下&#xff0c;我们不会单独去操作children我们在一个组件内部拿到 props 的时候&#xff0c;我们有props.children这么一个属性大部分情况下&#xff0c;直接把 props.children 把它渲染到我们的jsx…...

深度学习|4.1 深L层神经网络 4.2 深层网络的正向传播

4.1 深L层神经网络 对于某些问题来说&#xff0c;深层神经网络相对于浅层神经网络解决该问题的效果会较好。所以问题就变成了神经网络层数的设置。 其中 n [ i ] n^{[i]} n[i]表示第i层神经节点的个数&#xff0c; w [ l ] w^{[l]} w[l]代表计算第l层所采用的权重系数&#xff…...

印象笔记03 衍生软件使用

印象笔记03 衍生软件使用 Verse 以下内容来源于官方介绍 VERSE是一款面向未来的智能化生产力工具&#xff0c;由印象笔记团队诚意推出。 你可以用VERSE&#xff1a; 管理数字内容&#xff0c;让信息有序高效运转&#xff1b;搭建知识体系&#xff0c;构建你的强大知识库&am…...

R语言【CoordinateCleaner】——cc_gbif(): 根据通过 method 参数定义的方法,删除或标记地理空间中异常值的记录。

cc_gbif()是R语言包coordinatecleaner中的一个函数&#xff0c;用于清理GBIF&#xff08;全球生物多样性信息设施&#xff09;数据集的地理坐标。该函数可以识别潜在的坐标错误&#xff0c;并对其进行修正或删除。 以下是cc_gbifl()函数的一般用法和主要参数&#xff1a; cc_…...

模式识别与机器学习-集成学习

集成学习 集成学习思想过拟合与欠拟合判断方法 K折交叉验证BootstrapBagging随机森林的特点和工作原理&#xff1a; BoostingAdaBoost工作原理&#xff1a;AdaBoost的特点和优点&#xff1a;AdaBoost的缺点&#xff1a; Gradient Boosting工作原理&#xff1a;Gradient Boostin…...

vue简单实现滚动条

背景&#xff1a;产品提了一个需求在一个详情页&#xff0c;一个form表单元素太多了&#xff0c;需要滚动到最下面才能点击提交按钮&#xff0c;很不方便。他的方案是&#xff0c;加一个滚动条&#xff0c;这样可以直接拉到最下面。 优化&#xff1a;1、支持滚动条&#xff0c;…...

计算机网络第一课

先了解层级&#xff1a; 传输的信息称为协议数据单元&#xff08;PDU&#xff09;&#xff0c;PDU在每个层次的称呼都不同&#xff0c;见下图&#xff1a;...

初识大数据,一文掌握大数据必备知识文集(12)

&#x1f3c6;作者简介&#xff0c;普修罗双战士&#xff0c;一直追求不断学习和成长&#xff0c;在技术的道路上持续探索和实践。 &#x1f3c6;多年互联网行业从业经验&#xff0c;历任核心研发工程师&#xff0c;项目技术负责人。 &#x1f389;欢迎 &#x1f44d;点赞✍评论…...

安全防御之授权和访问控制技术

授权和访问控制技术是安全防御中的重要组成部分&#xff0c;主要用于管理和限制对系统资源&#xff08;如数据、应用程序等&#xff09;的访问。授权控制用户可访问和操作的系统资源&#xff0c;而访问控制技术则负责在授权的基础上&#xff0c;确保只有经过授权的用户才能访问…...

Iceberg从入门到精通系列之二十:Iceberg支持的字段类型

Iceberg从入门到精通系列之二十&#xff1a;Iceberg支持的字段类型 Iceberg 表支持以下类型&#xff1a; 字段类型描述注释booleanTrue or falseint32 位有符号整数可以提升到longlong64 位有符号整数float32 位 IEEE 754 浮点可以提升到doubledouble64 位 IEEE 754 浮点decim…...

Unity坦克大战开发全流程——结束场景——通关界面

结束场景——通关界面 就照着这样来拼 写代码 hideme不要忘了 修改上一节课中的代码...

K8S三种发布方式和声明式资源管理

蓝绿发布 把应用服务集群标记位两个组&#xff0c;蓝组和绿组&#xff0c;先升级蓝组&#xff0c;先要把蓝组从负载均衡当中移除&#xff0c;绿组继续提供服务&#xff0c;蓝组升级完毕&#xff0c;再把绿组从负载均衡当中移除&#xff0c;绿组升级&#xff0c;然后都加入回负载…...

从千问Agent看AI Agent——我们很强,但还有很长的路要走

前言 最近双十一做活动买了台新电脑&#xff0c;显卡好起来了自然也开始大模型的学习工作了&#xff0c;这篇文章可能是该系列的第一弹&#xff0c;本地私有化部署千问agent&#xff0c;后面还会尝试一些其他的大模型结合本地知识库或者做行业垂直模型训练的&#xff0c;一步…...

Word2Vector介绍

Word2Vector 2013 word2vec也叫word embeddings&#xff0c;中文名“词向量”&#xff0c;google开源的一款用于词向量计算的工具&#xff0c;作用就是将自然语言中的字词转为计算机可以理解的稠密向量。在word2vec出现之前&#xff0c;自然语言处理经常把字词转为离散的单独的…...

书生·浦语大模型全链路开源体系----(1)

书生浦语大模型全链路开源体系 什么是大语言模型&#xff1f; 大语言模型是指具有大规模参数和强大语言理解能力的机器学习模型。这些模型通常使用深度学习技术&#xff0c;特别是递归神经网络&#xff08;RNN&#xff09;或变换器&#xff08;Transformer&#xff09;等架构…...

第四篇 行为型设计模式 - 灵活定义对象间交互

第四篇&#xff1a;行为型设计模式 - 灵活定义对象间交互 行为型设计模式关注对象之间的交互和职责分配&#xff0c;旨在定义对象间的高效、灵活的通信机制。以下是十一种常见行为型设计模式的详解及其应用场景。 1. 策略模式详解及其应用场景 详解&#xff1a; 策略模式定义…...

2023最新租号平台系统源码支持单独租用或合租使用

这是一款租号平台源码&#xff0c;采用常见的租号模式。目前网络上还很少见到此类类型的源码。 平台的主要功能如下&#xff1a; 支持单独租用或采用合租模式&#xff1b; 采用易支付通用接口进行支付&#xff1b; 添加邀请返利功能&#xff0c;以便站长更好地推广&#xf…...

数据库的连接

连接数据库 我们使用WinR输入cmd打开运行窗口 输入:sqlplus并回车 输入用户名和密码,我用的是Scott,密码我自己设置的123456,Scott默认的密码是tiger,回车 这种情况表示登录成功 在连接Scott成功的情况下创建一些数据,在我的资源里面有个Oracle数据基础可以下载,直接复制粘…...

第14课 利用openCV快速数豆豆

除了检测运动&#xff0c;openCV还能做许多有趣且实用的事情。其实openCV和FFmpeg一样都是宝藏开源项目&#xff0c;貌似简单的几行代码功能实现背后其实是复杂的算法在支撑。有志于深入学习的同学可以在入门后进一步研究算法的实现&#xff0c;一定会受益匪浅。 这节课&#…...

在前端利用Broadcast Channel实现浏览器跨 Tab 窗口通信的方法

Broadcast Channel 在前端&#xff0c;我们经常会用postMessage来实现页面间的通信&#xff0c;但这种方式更像是点对点的通信。对于一些需要广播&#xff08;让所有页面知道&#xff09;的消息&#xff0c;用postMessage不是非常自然。Broadcast Channel 就是用来弥补这个缺陷…...

【Apache Doris】自定义函数之 JAVA UDF 详解

【Apache Doris】自定义函数之 JAVA UDF 详解 一、背景说明二、原理简介三、环境信息3.1 硬件信息3.2 软件信息 四、IDE准备五、JAVA UDF开发流程5.1 源码准备5.1.1 pom.xml5.1.2 JAVA代码 5.2 mvn打包5.2.1 clean5.2.2 package 5.3 函数使用5.3.1 upload5.3.2 使用 六、注意事…...

BMS电池管理系统带充放电控制过流过压保护

2.4G无线采集BMS开发板&#xff08;主从一体&#xff09; 全新升级 &#xff08;赠送上位机源码TTL 上位机&#xff0c;可以改成自己想要的界面&#xff09; 12串电池TTL上位机 CAN通信上位机源码有偿开源&#xff0c;供项目二次开发。 增加STM32平台 USB转TTL通信 CAN通信 增加…...

在Linux中以后台静默运行Java应用程序

在Linux系统上运行Java应用程序时&#xff0c;有时我们希望将其设置为后台运行&#xff0c;而关闭终端窗口时不会影响进程的执行。在本文中&#xff0c;我们将介绍几种实现这一目标的方法。 1. 使用nohup命令 nohup是一个用于在后台运行进程的命令&#xff0c;而且关闭终端窗…...

k8s---Pod的生命周期

Pod是什么&#xff1f; pod是k8s中最小的资源管理组件。 pod也是最小化运行容器化应用的资源管理对象。 pod是一个抽象的概念&#xff0c;可以理解为一个或者多个容器化应用的集合 在一个pod当中运行一个容器是最常用的方式 在一个pod当中可以同时运行多个容器&#xff0c…...

CSS animation动画和关键帧实现轮播图效果HTML

CSS animation动画和关键帧实现轮播图效果HTML 这轮播图效果使用h5和css3实现效果&#xff0c;不需要js控制&#xff0c;但是其中的缺点就是不能使用鼠标进行切换效果。 具有代码如下 <!DOCTYPE html> <html lang"en"><head><meta charset&quo…...

Unity之键盘鼠标的监控

小编最近在玩大表哥2&#xff0c;通过 W、A、S、D 来移动亚瑟&#xff0c;鼠标左键来不吃牛肉 我们都知道玩家通过按键鼠标来控制游戏人物做出相应的行为动作&#xff0c;那在Unity引擎里是怎么知道玩家是如何操作的呢&#xff1f;本篇来介绍Unity是怎样监控键盘和鼠标的。 首先…...

C# windows服务程序开机自启动exe程序

我们使用传统的Process.Start(".exe")启动进程会遇到无法打开UI界面的问题&#xff0c;尤其是我们需要进行开启自启动程序设置时出现诸多问题&#xff0c;于是我们就想到采用windows服务开机自启动来创建启动一个新的exe程序&#xff0c;并且是显式运行。 首先是打开…...

【SpringMVC】常用注解

什么是MVC&#xff1f; MVC是一种程序分层开发模式&#xff0c;分别是Model&#xff08;模型&#xff09;&#xff0c;View&#xff08;视图&#xff09;以及Controller&#xff08;控制器&#xff09;。这样做可以将程序的用户界面和业务逻辑分离&#xff0c;使得代码具有良好…...

关于曲率、曲率半径和曲率圆,看这几篇文章就够啦

关于曲率、曲率半径和曲率圆的内容&#xff0c;是考研数学数学一和数学二大纲中明确要求掌握的内容&#xff0c;但这部分内容在很多教材教辅以及练习题中较少涉及。在本文中&#xff0c;荒原之梦考研数学网就为大家整理了曲率、曲率半径和曲率圆方程相关的概念、基础知识以及练…...

java面试题-Spring常见的异常类有哪些?

远离八股文&#xff0c;面试大白话&#xff0c;通俗且易懂 看完后试着用自己的话复述出来。有问题请指出&#xff0c;有需要帮助理解的或者遇到的真实面试题不知道怎么总结的也请评论中写出来&#xff0c;大家一起解决。 java面试题汇总-目录-持续更新中 NullPointerException&…...

重庆比较好的广告公司/网站优化seo方案

本文目录 1.Yarn 基础架构2.Yarn工作机制Ⅰ.流程说明3.Yarn工作机制高清大图4.Yarn调度器和调度算法 (仅做了解即可)Ⅰ.FIFO调度器Ⅱ.容量调度器(Capacity Scheduler)1.特点2.资源分配算法Ⅲ.公平调度器(Fair Scheduler)1.缺额情况2.队列资源分配方式在大数据开发中,小则几…...

股票查询网站模板 wordpress/网络营销推广的渠道有哪些

在过去五个月中&#xff0c;Google 的 OSS-Fuzz 计划已经在 47 个开源软件项目中发掘了超过 1000 个 bug 。 OSS-Fuzz 是 Google 在去年12月推出的一个开源安全计划&#xff0c;针对开源软件进行持续的模糊测试&#xff0c;利用更新的模糊测试技术与可拓展的分布式执行相结合&a…...

南京网站建设小程序/长沙市云网站建设

所有题目均有四种语言实现。C++ 实现目录、Python实现目录、Java实现目录、JavaScript实现目录 题目 给定一个由纯数字组成以字符串表示的数值,现要求字符串中的每个数字最多只能出现2次,超过的需要进行删除; 删除某个重复的数字后,其它数字相对位置保持不变。 如”34533″…...

做网站接活犯法吗/收录优美图片

您的问题的最佳解决方案是使用池.使用队列并具有单独的“队列馈送”功能可能有点过分.这是一个稍微重新安排的程序版本,这次只有2个进程在池中.我认为这是最简单的方法,对原始代码的改动很小&#xff1a;import multiprocessingimport timedata ([a, 2], [b, 4], [c, 6], [d, …...

品牌建设网站公司/文案写作软件app

[ERR] Node 192.168.1.77:7000 is not empty. Either the node already knows other nodes (check with CLUSTER NODES) or contains some key in database 0. 解决方法&#xff1a; 1)、将需要新增的节点下aof、rdb、nodes.conf等本地备份文件删除&#xff1b; 2)、同时将新No…...

郑州市做网站公司a汉狮/b站推广入口2023mmm

文章目录路由搭建品牌管理静态组件列表展示添加品牌与修改品牌静态页面添加品牌动态路由搭建 首先把多余的路由组件删除 接下来修改router文件夹中的路由配置。 删除多余的路由配置&#xff0c;添加新的路由配置&#xff0c;如下所示。 品牌管理 静态组件 页面布局利用…...