React16源码: JSX2JS及React.createElement源码实现
JSX 到 Javascript 的转换
- React中的 JSX 类似于 Vue中的template模板文件,Vue是基于编译时将template模板转换成render函数
- 在React中,JSX是类似于html和javascript混编的语法,而javascript是真的javascript, html并非真的html
- 它的可阅读性可维护性都是要高很多的
1 )JSX2JS 原理
- JSX 通过 babel 进行转换之后,生成了纯JS
- JSX相对于JS来讲,它唯一的一个区别,就是它可以写类似于HTML的一个标签
- 比如说我们通过写div 然后在 div 这种方式去声明HML的标签
- 然后它会给我们返回在React当中需要使用的对象
- 这就是JSX到JS的一个转化过程
2 ) 工具演示
- 这个工具是 babel playground
- babeljs.io/repl
- 要做一些代码转化的一个测试,可以直接到这个playground上面来
- 它会实时在为我们展现出我们写的代码转化出来的是什么样的样子
- 下面的示例是使用较低版本的 babel 来配合 React 16.6 版本
示例1
jsx
<div></div>
js
React.createElement("div", null);
示例2
jsx
<div class="test"></div>
js
React.createElement("div", {class: "test"
});
示例3
jsx
<div id="div" key="key" class="test"><span>1</span><span>1</span>
</div>
js
React.createElement("div", {id: "div",key: "key",class: "test"
}, React.createElement("span", null, "1"), React.createElement("span", null, "1"));
示例4
jsx
function Comp() {return <a>123</a>
}<Comp id="div" key="key"><span>1</span><span>1</span><div id="box"><span class='inner'>2</span></div>
</Comp>
js
function Comp() {return React.createElement("a", null, "123");
}React.createElement(Comp, {id: "div",key: "key"
}, React.createElement("span", null, "1"),React.createElement("span", null, "1"),React.createElement("div", {id: "box"}, React.createElement("span", {class: "inner"}, "2"))
);
3 )说明
- 从上面我们可以看出来我们的一个类似html的标签,或者是组件的一个标签
- 通过这种尖括号的方式来写的,它最终都会转换成
React.createElement
- 我们写的这些标签或者一些props,或者它的 children 都会作为一个参数
- props 是一个 key-value 形式的一个对象
- 它可以支持多层,无限层的嵌套,也就是一个树形结构
- 如果是一个函数式的组件作为参数
- 这里要分两种情况
- 1 ) 组件是大写的,这样会直接转换成变量(对象)
- 2 ) 组件是小写的,这样会直接变成字符串类型的标记(组件将失效)
- 注意
- 如果变成字符串,那么在React中,它是会认为这是一个原生的dom节点的
- 如果不存在这么一个dom节点,那么后续在运行的时候,可能就报错了
- 所以自定义的组件必须使用大写的开头,这是一个规范
- 这里要分两种情况
- 综上,我们现在问题的重点就在
createElement
之上了
React.createElement 源码解析
- 在上一步的 JSX2JS中,我们的标签,标签里的属性,标签的内容,都会变成各种类型的参数
- 传到我们调用的
createElement
这个方法里面,这个方法内部如何实现的 - 在 createElement 函数的内部,返回了一个
React Element
, 我们来看看它具体的作用 - 看源码肯定要从它的入口文件开始看,因为入口文件会给我们很多的信息告诉我们
- 常用的使用这个包的时候的这些API它都来自于哪里,以及它是如何
export
出来的
1 )React 入口文件 packages/react/src/React.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 ReactVersion from 'shared/ReactVersion';
import {REACT_CONCURRENT_MODE_TYPE,REACT_FRAGMENT_TYPE,REACT_PROFILER_TYPE,REACT_STRICT_MODE_TYPE,REACT_SUSPENSE_TYPE,
} from 'shared/ReactSymbols';import {Component, PureComponent} from './ReactBaseClasses';
import {createRef} from './ReactCreateRef';
import {forEach, map, count, toArray, only} from './ReactChildren';
import {createElement,createFactory,cloneElement,isValidElement,
} from './ReactElement';
import {createContext} from './ReactContext';
import {lazy} from './ReactLazy';
import forwardRef from './forwardRef';
import memo from './memo';
import {createElementWithValidation,createFactoryWithValidation,cloneElementWithValidation,
} from './ReactElementValidator';
import ReactSharedInternals from './ReactSharedInternals';
import {enableStableConcurrentModeAPIs} from 'shared/ReactFeatureFlags';const React = {Children: {map,forEach,count,toArray,only,},createRef,Component,PureComponent,createContext,forwardRef,lazy,memo,Fragment: REACT_FRAGMENT_TYPE,StrictMode: REACT_STRICT_MODE_TYPE,Suspense: REACT_SUSPENSE_TYPE,createElement: __DEV__ ? createElementWithValidation : createElement,cloneElement: __DEV__ ? cloneElementWithValidation : cloneElement,createFactory: __DEV__ ? createFactoryWithValidation : createFactory,isValidElement: isValidElement,version: ReactVersion,__SECRET_INTERNALS_DO_NOT_USE_OR_YOU_WILL_BE_FIRED: ReactSharedInternals,
};if (enableStableConcurrentModeAPIs) {React.ConcurrentMode = REACT_CONCURRENT_MODE_TYPE;React.Profiler = REACT_PROFILER_TYPE;
} else {React.unstable_ConcurrentMode = REACT_CONCURRENT_MODE_TYPE;React.unstable_Profiler = REACT_PROFILER_TYPE;
}export default React;
- 上面全是 import 其他一些东西,import 进来之后, 它声明了 React 对象
- 这个对象就是我们在外部去用 React 的时候,给我们提供的API
- 然后最终它
export default React
把这个对象给它 export 出来 - 这样的话我们就可以在外部使用
- 我们回到
createElement
上面来,从上面可知,跟Element相关的一些代码 - 都放在了 ./ReactElement 这个文件下面
2 )定位到 ReactElement.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 warningWithoutStack from 'shared/warningWithoutStack';
import {REACT_ELEMENT_TYPE} from 'shared/ReactSymbols';import ReactCurrentOwner from './ReactCurrentOwner';const hasOwnProperty = Object.prototype.hasOwnProperty;const RESERVED_PROPS = {key: true,ref: true,__self: true,__source: true,
};let specialPropKeyWarningShown, specialPropRefWarningShown;function hasValidRef(config) {if (__DEV__) {if (hasOwnProperty.call(config, 'ref')) {const getter = Object.getOwnPropertyDescriptor(config, 'ref').get;if (getter && getter.isReactWarning) {return false;}}}return config.ref !== undefined;
}function hasValidKey(config) {if (__DEV__) {if (hasOwnProperty.call(config, 'key')) {const getter = Object.getOwnPropertyDescriptor(config, 'key').get;if (getter && getter.isReactWarning) {return false;}}}return config.key !== undefined;
}function defineKeyPropWarningGetter(props, displayName) {const warnAboutAccessingKey = function() {if (!specialPropKeyWarningShown) {specialPropKeyWarningShown = true;warningWithoutStack(false,'%s: `key` is not a prop. Trying to access it will result ' +'in `undefined` being returned. If you need to access the same ' +'value within the child component, you should pass it as a different ' +'prop. (https://fb.me/react-special-props)',displayName,);}};warnAboutAccessingKey.isReactWarning = true;Object.defineProperty(props, 'key', {get: warnAboutAccessingKey,configurable: true,});
}function defineRefPropWarningGetter(props, displayName) {const warnAboutAccessingRef = function() {if (!specialPropRefWarningShown) {specialPropRefWarningShown = true;warningWithoutStack(false,'%s: `ref` is not a prop. Trying to access it will result ' +'in `undefined` being returned. If you need to access the same ' +'value within the child component, you should pass it as a different ' +'prop. (https://fb.me/react-special-props)',displayName,);}};warnAboutAccessingRef.isReactWarning = true;Object.defineProperty(props, 'ref', {get: warnAboutAccessingRef,configurable: true,});
}/*** Factory method to create a new React element. This no longer adheres to* the class pattern, so do not use new to call it. Also, no instanceof check* will work. Instead test $$typeof field against Symbol.for('react.element') to check* if something is a React Element.** @param {*} type* @param {*} key* @param {string|object} ref* @param {*} self A *temporary* helper to detect places where `this` is* different from the `owner` when React.createElement is called, so that we* can warn. We want to get rid of owner and replace string `ref`s with arrow* functions, and as long as `this` and owner are the same, there will be no* change in behavior.* @param {*} source An annotation object (added by a transpiler or otherwise)* indicating filename, line number, and/or other information.* @param {*} owner* @param {*} props* @internal*/
const ReactElement = function(type, key, ref, self, source, owner, props) {const element = {// This tag allows us to uniquely identify this as a React Element$$typeof: REACT_ELEMENT_TYPE,// Built-in properties that belong on the elementtype: type,key: key,ref: ref,props: props,// Record the component responsible for creating this element._owner: owner,};if (__DEV__) {// The validation flag is currently mutative. We put it on// an external backing store so that we can freeze the whole object.// This can be replaced with a WeakMap once they are implemented in// commonly used development environments.element._store = {};// To make comparing ReactElements easier for testing purposes, we make// the validation flag non-enumerable (where possible, which should// include every environment we run tests in), so the test framework// ignores it.Object.defineProperty(element._store, 'validated', {configurable: false,enumerable: false,writable: true,value: false,});// self and source are DEV only properties.Object.defineProperty(element, '_self', {configurable: false,enumerable: false,writable: false,value: self,});// Two elements created in two different places should be considered// equal for testing purposes and therefore we hide it from enumeration.Object.defineProperty(element, '_source', {configurable: false,enumerable: false,writable: false,value: source,});if (Object.freeze) {Object.freeze(element.props);Object.freeze(element);}}return element;
};/*** Create and return a new ReactElement of the given type.* See https://reactjs.org/docs/react-api.html#createelement*/
export function createElement(type, config, children) {let propName;// Reserved names are extractedconst props = {};let key = null;let ref = null;let self = null;let source = null;if (config != null) {if (hasValidRef(config)) {ref = config.ref;}if (hasValidKey(config)) {key = '' + config.key;}self = config.__self === undefined ? null : config.__self;source = config.__source === undefined ? null : config.__source;// Remaining properties are added to a new props objectfor (propName in config) {if (hasOwnProperty.call(config, propName) &&!RESERVED_PROPS.hasOwnProperty(propName)) {props[propName] = config[propName];}}}// Children can be more than one argument, and those are transferred onto// the newly allocated props object.const childrenLength = arguments.length - 2;if (childrenLength === 1) {props.children = children;} else if (childrenLength > 1) {const childArray = Array(childrenLength);for (let i = 0; i < childrenLength; i++) {childArray[i] = arguments[i + 2];}if (__DEV__) {if (Object.freeze) {Object.freeze(childArray);}}props.children = childArray;}// Resolve default propsif (type && type.defaultProps) {const defaultProps = type.defaultProps;for (propName in defaultProps) {if (props[propName] === undefined) {props[propName] = defaultProps[propName];}}}if (__DEV__) {if (key || ref) {const displayName =typeof type === 'function'? type.displayName || type.name || 'Unknown': type;if (key) {defineKeyPropWarningGetter(props, displayName);}if (ref) {defineRefPropWarningGetter(props, displayName);}}}return ReactElement(type,key,ref,self,source,ReactCurrentOwner.current,props,);
}/*** Return a function that produces ReactElements of a given type.* See https://reactjs.org/docs/react-api.html#createfactory*/
export function createFactory(type) {const factory = createElement.bind(null, type);// Expose the type on the factory and the prototype so that it can be// easily accessed on elements. E.g. `<Foo />.type === Foo`.// This should not be named `constructor` since this may not be the function// that created the element, and it may not even be a constructor.// Legacy hook: remove itfactory.type = type;return factory;
}export function cloneAndReplaceKey(oldElement, newKey) {const newElement = ReactElement(oldElement.type,newKey,oldElement.ref,oldElement._self,oldElement._source,oldElement._owner,oldElement.props,);return newElement;
}/*** Clone and return a new ReactElement using element as the starting point.* See https://reactjs.org/docs/react-api.html#cloneelement*/
export function cloneElement(element, config, children) {invariant(!(element === null || element === undefined),'React.cloneElement(...): The argument must be a React element, but you passed %s.',element,);let propName;// Original props are copiedconst props = Object.assign({}, element.props);// Reserved names are extractedlet key = element.key;let ref = element.ref;// Self is preserved since the owner is preserved.const self = element._self;// Source is preserved since cloneElement is unlikely to be targeted by a// transpiler, and the original source is probably a better indicator of the// true owner.const source = element._source;// Owner will be preserved, unless ref is overriddenlet owner = element._owner;if (config != null) {if (hasValidRef(config)) {// Silently steal the ref from the parent.ref = config.ref;owner = ReactCurrentOwner.current;}if (hasValidKey(config)) {key = '' + config.key;}// Remaining properties override existing propslet defaultProps;if (element.type && element.type.defaultProps) {defaultProps = element.type.defaultProps;}for (propName in config) {if (hasOwnProperty.call(config, propName) &&!RESERVED_PROPS.hasOwnProperty(propName)) {if (config[propName] === undefined && defaultProps !== undefined) {// Resolve default propsprops[propName] = defaultProps[propName];} else {props[propName] = config[propName];}}}}// Children can be more than one argument, and those are transferred onto// the newly allocated props object.const childrenLength = arguments.length - 2;if (childrenLength === 1) {props.children = children;} else if (childrenLength > 1) {const childArray = Array(childrenLength);for (let i = 0; i < childrenLength; i++) {childArray[i] = arguments[i + 2];}props.children = childArray;}return ReactElement(element.type, key, ref, self, source, owner, props);
}/*** Verifies the object is a ReactElement.* See https://reactjs.org/docs/react-api.html#isvalidelement* @param {?object} object* @return {boolean} True if `object` is a ReactElement.* @final*/
export function isValidElement(object) {return (typeof object === 'object' &&object !== null &&object.$$typeof === REACT_ELEMENT_TYPE);
}
- 在这个文件里面先找到
createElement
这个方法,我们可以看到它接收的三个参数type
- 就是我们的节点类型,如果是原生的节点,那么它是一个字符串
- 那如果是我们自己声明的组件,它就是一个class component 或者是一个 functional component
- 还会有其他的一些情况。比如 使用 React 原生的一些组件
- 比如说 Fragment、 StrictMode、 Suspense
- 这些都是 React 提供我们的一些原生组件,
- 其实,上面三个它们默认就只是一个
Symbol
- 它没有任何其他的功能,就仅仅是一个标志
config
- 是我们写在这个JSX标签上面的所有的 attributes
- 它们都会变成key value的形式存到这个config对象里面
- 我们要从这个对象里面筛选出真正的props的内容
- 还有特殊的,比如说 key,ref 这些属性
children
- 就是我们标签中间我们放的一些内容
- 它可能是一个子标签,或者它直接是文字 text
- 我们来看一下它如何去创建一个
ReactElement
, 还是回到createElement
这个方法- 内部声明了一堆变量,找到有没有合理的REF,有没有合理的key
- 我们把这些都给它读到一个单独的变量里面
- 忽略 self 和 source 这两个东西,不是特别的重要
- 接下去,要对剩下的config下面的 props 进行一个处理
- 判断一下它是否是内建的 props,如果不是的话,就放到一个新建的 props 对象里面
- 如果是内建的 props,就不放进去了,因为它不属于正常的 props 的范畴
- 看一下这个内建的 props,它是什么东西
const RESERVED_PROPS = {key: true,ref: true,__self: true,__source: true, };
key
,ref
,__self
,__source
, 这些都不会出现在我们使用class component 的场景下- 比如说我们的 this.props里面
- 因为在处理props的过程当中,就已经把它处理掉了
- 这边把 props 的属性全部拿出来,放到一个新的对象里面之后
- 接下去要处理children
- children 是可以有多个的,在一个节点下面
- 它的 children 可能有很多的兄弟节点存在
- 它是作为后续的参数传进来的,虽然在声明
createElement
的时候只有三个参数 - 但是它是可以传 3,4,5,6,7,8,9, … 多个参数的
- 后续第三个参数之后的参数,我们都认为它们是 children
- 在react当中把后续
arguments.length - 2
代表剩下的这个长度都是children - 然后会一个一个把它读出来,然后变成一个数组
- 声明一个数组, 存放后续所有的 children 节点对象, 最终再把它放到 props.children
- 通过
this.props.children
拿到的就是这部分的内容
- 接下来,就是
defaultProps
的处理- 在声明 class Comp 的时候,比如说我们
extends React.Component
- 我们可以通过
Comp.defaultProps
一个对象,给接收的这些props去设置一些默认值 - 比如说, 这边它的默认值是
{value:1}
,当组件在被使用的时候,没有传value这个props - 在这里面就会使用 1 作为我们在组件内部
this.props.value
去拿到的这个值 - 它就是把我们刚才上面处理过的那个props对象上面去读取对应的defaultProps里面的每一个key的值
- 如果值是
undefined
,就把它设置为 defaultProps 里面的属性 - 如果它是有值的, 我们就不设置了
- 注意
- 它的判断条件是
undefined
- 也就是说 null 也是一个不需要使用默认值的情况
- 它的判断条件是
- 在声明 class Comp 的时候,比如说我们
- 接着,下面 DEV 判断的代码,进行忽略
- 最终 return了一个
ReactElement
- 传入刚才处理过的这些内容
- 关于
ReactElement
- 它不是一个 class Comp, 而是一个 function
- 最终会return一个Object, 这个Object也就几个主要的属性
$$typeof
是REACT_ELEMENT_TYPE
- 是用来标识我们的 element 是什么类型的
- 在写JSX代码的时候,所有的节点都是通过 createElement 进行创建的
- 那么,它的
$$typeof
永远都是REACT_ELEMENT_TYPE
- 在后续React的更新渲染dom的过程中是经常被用到的
- 大部分情况下,我们拿到的
$$typeof
都是REACT_ELEMENT_TYPE
- 有一些特殊情况是和平台相关
- 在react-dom里面,它有一个API叫做
React.createPortal
, 它返回的对象和这里的类似 - 但是它的
$$typeof
是REACT_PORTAL_TYPE
- 在react-dom里面,它有一个API叫做
type
是之前传进来的那个 type- 是在
createElement
的时候接收的那个 type - 用于记录节点的类型,是原生组件,还是 class Comp
- 是在
key
就是上面处理过的 keyref
就是 refprops
就是 props
- 综上,就是一个 ReactElement, 具体的方法,如何去操作,以及最终返回的类型
相关文章:
React16源码: JSX2JS及React.createElement源码实现
JSX 到 Javascript 的转换 React中的 JSX 类似于 Vue中的template模板文件,Vue是基于编译时将template模板转换成render函数在React中,JSX是类似于html和javascript混编的语法,而javascript是真的javascript, html并非真的html它的可阅读性可…...
整理composer安装版本的python脚本
整理composer安装版本的python脚本 脚本实现的功能是去除composer安装命令后的版本号 def remove_version_numbers(commands):"""Remove version numbers from composer require commands.Args:commands (list of str): List of composer require commands.Retu…...

十、基本对话框大集合(Qt5 GUI系列)
目录 一、设计需求 二、实现代码 三、代码解析 四、总结 一、设计需求 Qt提供了很多标准的对话框。例如标准文件对话框(QFileDialog)、标准颜色对话框(QColorDialog)、标准字体对话框 (QFontDialog)、标准输入对话框 (QInputDialog) 及消息对话框 (QMessageBox)。本文展示各…...
大A又跌了
才开盘几天,又开始下跌了。生活更加苦难。期待高深算法。...

This error originates from a subprocess, and is likely not a problem with pip
我遇这个问题是的原因是包名错误 注意检查包名...

数据库基础知识1
关系模型的程序员不需熟悉数据库的存取路径 在3层模式结构中,___I___是数据库的核心和关键,___Ⅱ___通常是模式的子集,数据库模式的描述提供给用户,____Ⅲ__的描述存储在硬盘上。Ⅰ.模式Ⅱ. 外模式Ⅲ. 内模式 数据库中,数据的物理独立性是指用户的应用程序与存储在磁盘上数据库…...

【GO语言卵细胞级别教程】01.GO基础知识
01.GO基础知识 目录 01.GO基础知识1.GO语言的发展历程2.发展历程3.Windowns安装4.VSCode配置5.基础语法5.1 第一段代码5.2 GO执行的流程5.3 语法规则5.4 代码风格5.5 学习网址 1.GO语言的发展历程 Go语言是谷歌公司于2007年开始开发的一种编程语言,由Robert Griese…...
215.【2023年华为OD机试真题(C卷)】按身高和体重排排队(排序题-JavaPythonC++JS实现)
🚀点击这里可直接跳转到本专栏,可查阅顶置最新的华为OD机试宝典~ 本专栏所有题目均包含优质解题思路,高质量解题代码(Java&Python&C++&JS分别实现),详细代码讲解,助你深入学习,深度掌握! 文章目录 一. 题目-按身高和体重排排队二.解题思路三.题解代码Pyt…...
虚函数(C++)
四、多态4.1 虚函数 四、多态 多态性是面向对象程序设计语言的又一重要特征,多态(polymorphism)通俗的讲,就是用一个相同的名字定义许多不同的函数,这些函数可以针对不同数据类型实现相同或类似的功能,即所…...
力扣25题: K 个一组翻转链表
【题目链接】力扣(LeetCode)官网 - 全球极客挚爱的技术成长平台,解题代码如下: class Solution {public ListNode reverseKGroup(ListNode head, int k) {ListNode curNode head;ListNode groupHead, groupTail head, lastGrou…...

网络安全应急响应工具之-流量安全取证NetworkMiner
在前面的一些文章中,用了很多的章节介绍流量分析和捕获工具wireshark。Wireshark是一款通用的网络协议分析工具,非常强大,关于wireshark的更多介绍,请关注专栏,wireshark从入门到精通。本文将介绍一个专注于网络流量取…...
http 401 错误
HTTP 401 错误表示未被授权,指客户端通过请求头中的身份验证数据进行身份验证,服务器返回401状态码表示身份验证失败。HTTP 401 错误通常与身份验证和授权相关的 Web 请求有关。 一、HTTP 401错误的定义 HTTP 401 错误是 HTTP 状态码的一种。由于服务器…...

Docker-Compose部署Redis(v7.2)哨兵模式
文章目录 一、前提准备1. 主从集群2. 文件夹结构 二、配置文件1. redis server配置文件2. redis sentinel配置文件3. docker compose文件 三、运行四、测试 环境 docker desktop for windows 4.23.0redis 7.2 一、前提准备 1. 主从集群 首先需要有一个redis主从集群&#x…...

解决问题:PPT中插入视频编辑模式可以播放,幻灯片放映后播放不了
目录 一、原因分析二、解决办法三、其它问题 一、原因分析 这可能是由于PowerPoint的硬件图形加速功能导致的。 二、解决办法 禁用硬件图形加速。 (1)点击《文件》选项卡 (2)点击《选项》 (3)在《高级》…...

使用react+vite开发项目时候,部署上线后刷新页面无法访问解决办法
说一下我这边的环境和使用的路由模式:vitereactBrowserRouter路由模式,所以如果你和我一样的话,可以试试我的这种解决办法,我是将项目打包后直接丢到服务器上的目录里面,然后配置nginx直接访问根目录。 我的nginx配置…...
45. 跳跃游戏 II(Java)
题目描述: 给定一个长度为 n 的 0 索引整数数组 nums。初始位置为 nums[0]。 每个元素 nums[i] 表示从索引 i 向前跳转的最大长度。换句话说,如果你在 nums[i] 处,你可以跳转到任意 nums[i j] 处: 0 < j < nums[i] i j < n 返回到…...

[足式机器人]Part4 南科大高等机器人控制课 CH12 Robotic Motion Control
本文仅供学习使用 本文参考: B站:CLEAR_LAB 笔者带更新-运动学 课程主讲教师: Prof. Wei Zhang 课程链接 : https://www.wzhanglab.site/teaching/mee-5114-advanced-control-for-robotics/ 南科大高等机器人控制课 Ch12 Robotic …...
【C++】知识点汇总(上)
C知识点复习上 一、C 概述1. 基本数据类型2. 变量定义和访问3. 常量与约束访问 二、程序控制结构详解与示例1. 表达式2. 选择控制2.1 if 语句2.2 switch 语句 3. 循环控制3.1 for 循环3.2 while 循环3.3 do-while 循环 4. goto 语句5. 控制语句的嵌套 三、函数1. 函数的定义和调…...

解决docker容器内无法连接宿主redis
背景 小程序的发短信服务挂了,随查看日志,该报错日志如下 Error 111 connecting to 127.0.0.1:6379. Connection refused. 6379是监听redis服务的端口,那大概是redis出错了。 首先查看了redis是否正常启动,检查出服务正常。 由于小…...

43 tmpfs/devtmpfs 文件系统
前言 在 linux 中常见的文件系统 有很多, 如下 基于磁盘的文件系统, ext2, ext3, ext4, xfs, btrfs, jfs, ntfs 内存文件系统, procfs, sysfs, tmpfs, squashfs, debugfs 闪存文件系统, ubifs, jffs2, yaffs 文件系统这一套体系在 linux 有一层 vfs 抽象, 用户程序不用…...

如何在看板中体现优先级变化
在看板中有效体现优先级变化的关键措施包括:采用颜色或标签标识优先级、设置任务排序规则、使用独立的优先级列或泳道、结合自动化规则同步优先级变化、建立定期的优先级审查流程。其中,设置任务排序规则尤其重要,因为它让看板视觉上直观地体…...
【Go】3、Go语言进阶与依赖管理
前言 本系列文章参考自稀土掘金上的 【字节内部课】公开课,做自我学习总结整理。 Go语言并发编程 Go语言原生支持并发编程,它的核心机制是 Goroutine 协程、Channel 通道,并基于CSP(Communicating Sequential Processes࿰…...
鸿蒙中用HarmonyOS SDK应用服务 HarmonyOS5开发一个医院查看报告小程序
一、开发环境准备 工具安装: 下载安装DevEco Studio 4.0(支持HarmonyOS 5)配置HarmonyOS SDK 5.0确保Node.js版本≥14 项目初始化: ohpm init harmony/hospital-report-app 二、核心功能模块实现 1. 报告列表…...
【Go语言基础【12】】指针:声明、取地址、解引用
文章目录 零、概述:指针 vs. 引用(类比其他语言)一、指针基础概念二、指针声明与初始化三、指针操作符1. &:取地址(拿到内存地址)2. *:解引用(拿到值) 四、空指针&am…...

【C++特殊工具与技术】优化内存分配(一):C++中的内存分配
目录 一、C 内存的基本概念 1.1 内存的物理与逻辑结构 1.2 C 程序的内存区域划分 二、栈内存分配 2.1 栈内存的特点 2.2 栈内存分配示例 三、堆内存分配 3.1 new和delete操作符 4.2 内存泄漏与悬空指针问题 4.3 new和delete的重载 四、智能指针…...

2025年渗透测试面试题总结-腾讯[实习]科恩实验室-安全工程师(题目+回答)
安全领域各种资源,学习文档,以及工具分享、前沿信息分享、POC、EXP分享。不定期分享各种好玩的项目及好用的工具,欢迎关注。 目录 腾讯[实习]科恩实验室-安全工程师 一、网络与协议 1. TCP三次握手 2. SYN扫描原理 3. HTTPS证书机制 二…...

毫米波雷达基础理论(3D+4D)
3D、4D毫米波雷达基础知识及厂商选型 PreView : https://mp.weixin.qq.com/s/bQkju4r6med7I3TBGJI_bQ 1. FMCW毫米波雷达基础知识 主要参考博文: 一文入门汽车毫米波雷达基本原理 :https://mp.weixin.qq.com/s/_EN7A5lKcz2Eh8dLnjE19w 毫米波雷达基础…...

Cilium动手实验室: 精通之旅---13.Cilium LoadBalancer IPAM and L2 Service Announcement
Cilium动手实验室: 精通之旅---13.Cilium LoadBalancer IPAM and L2 Service Announcement 1. LAB环境2. L2公告策略2.1 部署Death Star2.2 访问服务2.3 部署L2公告策略2.4 服务宣告 3. 可视化 ARP 流量3.1 部署新服务3.2 准备可视化3.3 再次请求 4. 自动IPAM4.1 IPAM Pool4.2 …...

Linux中《基础IO》详细介绍
目录 理解"文件"狭义理解广义理解文件操作的归类认知系统角度文件类别 回顾C文件接口打开文件写文件读文件稍作修改,实现简单cat命令 输出信息到显示器,你有哪些方法stdin & stdout & stderr打开文件的方式 系统⽂件I/O⼀种传递标志位…...
stm32进入Infinite_Loop原因(因为有系统中断函数未自定义实现)
这是系统中断服务程序的默认处理汇编函数,如果我们没有定义实现某个中断函数,那么当stm32产生了该中断时,就会默认跑这里来了,所以我们打开了什么中断,一定要记得实现对应的系统中断函数,否则会进来一直循环…...