洞悉细节!react 16.8.6源码分析-2 组件构造与获取调用栈
前言
作为一个前端页面仔和需求粉碎机,在日常的工作中重复雷同的业务需求,能够获得的提高是很有限的。要想跳出此山中,开阔新视野,笔者墙裂建议大家阅读市面上顶尖开源库的源码。这是学习和掌握js语言特性的绝佳机会(前端发展到现在,大型应用高度依赖框架,正常情况下普通开发者是没有机会接触底层的语言特性),同时也是深刻理解框架底层思维的契机。这里笔者选择react
第一个开刀,市面上不少关于react源码分析的文章要么过于老旧,要么只截取部分代码或者是伪代码,笔者这里将选取react的16.8.6版本作为示例,从第0行开始,不漏过任何一个源码细节,和大家分享笔者在源码阅读过程中的体会。希望和大家共同进步,本系列博文中涉及的源码本人会放在git仓库中,链接在文末。
正文
在这一篇中,我们将聚焦react虚拟DOM实现的核心,component
的定义。
- component和PureComponent定义
/*** Base class helpers for the updating state of a component.*/
// 组件的构造函数
function Component(props, context, updater) {this.props = props;this.context = context;// 如果组件使用字符串的refs,我们将会指定一个不同的对象// If a component has string refs, we will assign a different object later.this.refs = emptyObject;// 初始化默认的更新器,真实的更新器将会在渲染器内注入// We initialize the default updater but the real one gets injected by the// renderer.this.updater = updater || ReactNoopUpdateQueue;
}// 定义原型属性
Component.prototype.isReactComponent = {};// 设置状态的子集,始终使用this去改变状态,需要把this.sate当成正常状态下不可变的
// 并不保证this.state会马上更新,先设置再取值可能返回的是老值
// 并不保证setState的调用是同步的,因为多个调用最终会被合并,你可以提供一个可选的回调,在setStates事实上完成之后调用
// 当一个函数传递给setState时,它将在未来的某个时间点被调用,并且使用最新的参数(state,props,context等)这心值可能跟this.xxx不一样
// 因为你的函数是在receiveProps之后,shouldComponentUpdate之前调用的,在这个新阶段,props和context并没有赋值给this
/*** Sets a subset of the state. Always use this to mutate* state. You should treat `this.state` as immutable.** There is no guarantee that `this.state` will be immediately updated, so* accessing `this.state` after calling this method may return the old value.** There is no guarantee that calls to `setState` will run synchronously,* as they may eventually be batched together. You can provide an optional* callback that will be executed when the call to setState is actually* completed.** When a function is provided to setState, it will be called at some point in* the future (not synchronously). It will be called with the up to date* component arguments (state, props, context). These values can be different* from this.* because your function may be called after receiveProps but before* shouldComponentUpdate, and this new state, props, and context will not yet be* assigned to this.** @param {object|function} partialState Next partial state or function to* produce next partial state to be merged with current state.* @param {?function} callback Called after state is updated.* @final* @protected*/
Component.prototype.setState = function (partialState, callback) {// void 0 === undefined 省字节,同时防止undefined被注入// partialState需要是对象,函数或者null!(typeof partialState === 'object' || typeof partialState === 'function' || partialState == null) ? invariant(false, 'setState(...): takes an object of state variables to update or a function which returns an object of state variables.') : void 0;// 进入队列状态更新this.updater.enqueueSetState(this, partialState, callback, 'setState');
};// 强制刷新,该方法只能在非DOM转化态的时候调用
// 在一些深层状态改变但是setState没有被调用的时候使用,该方法不会调用shouldComponentUpdate,但componentWillUpdate和componentDidUpdate会被调用/*** Forces an update. This should only be invoked when it is known with* certainty that we are **not** in a DOM transaction.** You may want to call this when you know that some deeper aspect of the* component's state has changed but `setState` was not called.** This will not invoke `shouldComponentUpdate`, but it will invoke* `componentWillUpdate` and `componentDidUpdate`.** @param {?function} callback Called after update is complete.* @final* @protected*/
Component.prototype.forceUpdate = function (callback) {this.updater.enqueueForceUpdate(this, callback, 'forceUpdate');
};// 废弃的api,这些api只会在经典的类组件上存在,我们将会遗弃它们。我们并不会直接移除他们,而是定义getter,并抛错
/*** Deprecated APIs. These APIs used to exist on classic React classes but since* we would like to deprecate them, we're not going to move them over to this* modern base class. Instead, we define a getter that warns if it's accessed.*/
{var deprecatedAPIs = {isMounted: ['isMounted', 'Instead, make sure to clean up subscriptions and pending requests in ' + 'componentWillUnmount to prevent memory leaks.'],replaceState: ['replaceState', 'Refactor your code to use setState instead (see ' + 'https://github.com/facebook/react/issues/3236).']};// 定义遗弃api的告警函数var defineDeprecationWarning = function (methodName, info) {Object.defineProperty(Component.prototype, methodName, {get: function () {lowPriorityWarning$1(false, '%s(...) is deprecated in plain JavaScript React classes. %s', info[0], info[1]);return undefined;}});};// 依次注入getterfor (var fnName in deprecatedAPIs) {if (deprecatedAPIs.hasOwnProperty(fnName)) {defineDeprecationWarning(fnName, deprecatedAPIs[fnName]);}}
}// 假组件,原型是真组件的原型
function ComponentDummy() {}
ComponentDummy.prototype = Component.prototype;/*** Convenience component with default shallow equality check for sCU.*/
// 一个方便的组件,默认浅相等校验,其实是构造函数
function PureComponent(props, context, updater) {this.props = props;this.context = context;// 如果有字符串类型的ref,我们将在稍后指派一个不同的对象// If a component has string refs, we will assign a different object later.this.refs = emptyObject;this.updater = updater || ReactNoopUpdateQueue;
}// 关于原型和构造函数的相关内容可以参考https://blog.csdn.net/cc18868876837/article/details/81211729
// 纯粹的组件原型
var pureComponentPrototype = PureComponent.prototype = new ComponentDummy();
// 定义纯粹组件原型的构造函数
pureComponentPrototype.constructor = PureComponent;
// Avoid an extra prototype jump for these methods.
// 原型上再次注入Component的原型
_assign(pureComponentPrototype, Component.prototype);
// 标志位,判断是纯粹组件
pureComponentPrototype.isPureReactComponent = true;
这里定义了组件的构造函数Component
,然后定义了一系列IDE原型方法,比如setState
、forceUpdate
等等,然后针对一些已经废弃的api,给Component
的原型添加get
方法,以便在用户调用的时候抛错。接下来定义了一个过渡组件ComponentDummy
,其原型为Component
的原型,其实例为PureComponent
的原型
- createRet和组件调用堆栈
// an immutable object with a single mutable value
// 一个不可变的对象,一个不可变的值// 被封闭对象仍旧全等该对象本身
// 可以通过Object.isSealed来判断当前对象是否被封闭
// 不能为被封闭对象添加任何未知属性, 也不能为其已知属性添加访问者
// 可以修改已知的属性// https://www.jianshu.com/p/96220f921272
function createRef() {// 只有current一个属性var refObject = {current: null};{Object.seal(refObject);}return refObject;
}/*** Keeps track of the current dispatcher.*/
// 跟踪当前的分发者
var ReactCurrentDispatcher = {/*** @internal* @type {ReactComponent}*/current: null
};/*** Keeps track of the current owner.** The current owner is the component who should own any components that are* currently being constructed.*/
// 跟踪react当前的所有者,指的是所有正在构造的组件的父组件
var ReactCurrentOwner = {/*** @internal* @type {ReactComponent}*/current: null
};// 正则,匹配任意内容加正反斜杆
// 括号内的内容是分组 https://www.jianshu.com/p/f09508c14e65
// match如果是全局匹配,返回的是所有的匹配项,如果不是返回的是匹配字符串,位置,原始输入,如果有分组,第二项是匹配的分组
var BEFORE_SLASH_RE = /^(.*)[\\\/]/;
// 描述组件的引用位置
var describeComponentFrame = function (name, source, ownerName) {var sourceInfo = '';if (source) {var path = source.fileName;// 解析出文件名var fileName = path.replace(BEFORE_SLASH_RE, '');{// In DEV, include code for a common special case:// prefer "folder/index.js" instead of just "index.js".// 在开发环境下,如果文件名为index 输出带上一级路径的文件名if (/^index\./.test(fileName)) {// 解析出反斜杠前的文件名var match = path.match(BEFORE_SLASH_RE);if (match) {var pathBeforeSlash = match[1];if (pathBeforeSlash) {// 获得文件名前的文件夹的名字var folderName = pathBeforeSlash.replace(BEFORE_SLASH_RE, '');fileName = folderName + '/' + fileName;}}}}// 获取最近的文件夹名和文件名,拼上代码行数sourceInfo = ' (at ' + fileName + ':' + source.lineNumber + ')';} else if (ownerName) {sourceInfo = ' (created by ' + ownerName + ')';}return '\n in ' + (name || 'Unknown') + sourceInfo;
};var Resolved = 1;// 细化解析惰性组件
function refineResolvedLazyComponent(lazyComponent) {// 如果已经resolved,返回结果return lazyComponent._status === Resolved ? lazyComponent._result : null;
}// 获取外层组件的名字
function getWrappedName(outerType, innerType, wrapperName) {var functionName = innerType.displayName || innerType.name || '';// 优先是outerType的displayName,否则是wrapperName和functionName的组合return outerType.displayName || (functionName !== '' ? wrapperName + '(' + functionName + ')' : wrapperName);
}
这里首先定义了createRef
的实现,其次定义了ReactCurrentDispatcher
,react16.8.3版本后新增的hooks系列api,其机制类似于redux
中的dispatcher,这里的ReactCurrentDispatcher
在后续hooks api的定义中也会用到。接下来是
describeComponentFrame
方法,其核心是获得文件源的出处(主要是文件名和代码行数),接下来定义了获得组件父组件的组件名的方法getWrappedName
- 获取组件名称与react debug模式下当前组件调用堆栈详情
// 获取组件名
function getComponentName(type) {if (type == null) {// Host root, text node or just invalid type.// 如果是根,文字节点或不存在的类型,返回nullreturn null;}{// 如果type的tag是数字if (typeof type.tag === 'number') {// 告警:接收到了预料之外的对象,这可能是react内部的bug,请提issuewarningWithoutStack$1(false, 'Received an unexpected object in getComponentName(). ' + 'This is likely a bug in React. Please file an issue.');}}// 如果是构造函数,看他的静态属性displayName或者nameif (typeof type === 'function') {return type.displayName || type.name || null;}// 如果是字符串直接返回if (typeof type === 'string') {return type;}switch (type) {// 如果是react当前的节点,这些都是当初symbol定义的case REACT_CONCURRENT_MODE_TYPE:return 'ConcurrentMode';case REACT_FRAGMENT_TYPE:return 'Fragment';// 如果是入口case REACT_PORTAL_TYPE:return 'Portal';// 如果是分析器case REACT_PROFILER_TYPE:return 'Profiler';case REACT_STRICT_MODE_TYPE:return 'StrictMode';case REACT_SUSPENSE_TYPE:return 'Suspense';}// 如果type是对象if (typeof type === 'object') {// 按照$$typeof来判断switch (type.$$typeof) {case REACT_CONTEXT_TYPE:return 'Context.Consumer';case REACT_PROVIDER_TYPE:return 'Context.Provider';// 如果是前向refcase REACT_FORWARD_REF_TYPE:return getWrappedName(type, type.render, 'ForwardRef');// 如果是memo类型,递归调用自己case REACT_MEMO_TYPE:return getComponentName(type.type);// 如果是lazy类型case REACT_LAZY_TYPE:{var thenable = type;// 细化解析惰性组件var resolvedThenable = refineResolvedLazyComponent(thenable);if (resolvedThenable) {return getComponentName(resolvedThenable);}}}}// 最后返回nullreturn null;
}// react正在debug的frame,可以理解为一个对象里面有一些方法可供调取当前组件的调用栈
var ReactDebugCurrentFrame = {};// 当前正在验证的元素
var currentlyValidatingElement = null;// 设置当前正在验证的元素
function setCurrentlyValidatingElement(element) {{currentlyValidatingElement = element;}
}{// 堆栈的实现是通过当前的renderer注入的// Stack implementation injected by the current renderer.ReactDebugCurrentFrame.getCurrentStack = null;// 增加枚举的方法// 本质上是返回调用堆栈的附录ReactDebugCurrentFrame.getStackAddendum = function () {var stack = '';// Add an extra top frame while an element is being validated// 增加一个额外的顶层框架,如果当前有元素正在被验证if (currentlyValidatingElement) {// 获取元素的名字var name = getComponentName(currentlyValidatingElement.type);// 获取元素所有者var owner = currentlyValidatingElement._owner;// 获取源的目录位置stack += describeComponentFrame(name, currentlyValidatingElement._source, owner && getComponentName(owner.type));}// Delegate to the injected renderer-specific implementation// 转交给renderer中的特殊实现来获取堆栈// 如果getCurrentStack被复写,追加该方法提供的信息var impl = ReactDebugCurrentFrame.getCurrentStack;if (impl) {stack += impl() || '';}return stack;};
}
getComponentName
根据传入的react 元素(Element)的类型来获得组件的名称,通过判断type和type上的$$typeof
的值来判断返回的结果。$$typeof
是react Element内部定义的一个变量,负责记录元素的类型,后续的代码中会有提及。setCurrentlyValidatingElement
将在后续的一些validate的方法中被反复调用,设置当前正在校验的元素,以便后续输出抛错时的调用栈。
- 内部控制构件的定义、react元素属性保留字与hasValidXXX方法
// react内部共享的控制构件
var ReactSharedInternals = {// 当前的分发者ReactCurrentDispatcher: ReactCurrentDispatcher,// 当前的所有者ReactCurrentOwner: ReactCurrentOwner,// Object.assign避免在UMD下被打包两次// Used by renderers to avoid bundling object-assign twice in UMD bundles:assign: _assign
};{_assign(ReactSharedInternals, {// 在生产环境不应该有// These should not be included in production.ReactDebugCurrentFrame: ReactDebugCurrentFrame,// Shim for React DOM 16.0.0 which still destructured (but not used) this.// TODO: remove in React 17.0.// react树形钩子ReactComponentTreeHook: {}});
}// 类似于不变性的警告,只有在条件不满足的时候才打印
/*** Similar to invariant but only logs a warning if the condition is not met.* This can be used to log issues in development environments in critical* paths. Removing the logging code for production environments will keep the* same logic and follow the same code paths.*/// 首先赋值warningWithoutStack$1
var warning = warningWithoutStack$1;// 本质上是带调用栈的warning方法
{// 第二个条件是格式化warning = function (condition, format) {if (condition) {return;}// 获取当前的调用序列var ReactDebugCurrentFrame = ReactSharedInternals.ReactDebugCurrentFrame;var stack = ReactDebugCurrentFrame.getStackAddendum();// eslint-disable-next-line react-internal/warning-and-invariant-args// 拼装后面的参数for (var _len = arguments.length, args = Array(_len > 2 ? _len - 2 : 0), _key = 2; _key < _len; _key++) {args[_key - 2] = arguments[_key];}// 复用原来的warning方法,前面的内容照旧,后面的内容拼上调用序列的信息warningWithoutStack$1.apply(undefined, [false, format + '%s'].concat(args, [stack]));};
}var warning$1 = warning;// 定义hasOwnProperty方法
var hasOwnProperty = Object.prototype.hasOwnProperty;// 属性保留字
var RESERVED_PROPS = {key: true,ref: true,__self: true,__source: true
};// 特殊的属性key展示告警
// void 0 就是undefined
var specialPropKeyWarningShown = void 0;
var specialPropRefWarningShown = void 0;// 排除ref是warning的情况,判断是否存在ref
function hasValidRef(config) {{// 如果config有ref自有属性属性if (hasOwnProperty.call(config, 'ref')) {// 获取get方法var getter = Object.getOwnPropertyDescriptor(config, 'ref').get;// 如果这个getter是warning的,返回falseif (getter && getter.isReactWarning) {return false;}}}// 否则根据是否undefined来判断return config.ref !== undefined;
}// 是否具有可用属性
// 逻辑跟ref的很相似
function hasValidKey(config) {{if (hasOwnProperty.call(config, 'key')) {var getter = Object.getOwnPropertyDescriptor(config, 'key').get;if (getter && getter.isReactWarning) {return false;}}}return config.key !== undefined;
}// 定义key属性的warning Getter
function defineKeyPropWarningGetter(props, displayName) {// 关于访问key的告警var warnAboutAccessingKey = function () {if (!specialPropKeyWarningShown) {specialPropKeyWarningShown = true;// key不能作为参数获取,被react内部征用了// key不能作为参数,尝试去获取它只会返回undefined,如果你想获取子组件上的这个值,你应该传另一个名字的属性warningWithoutStack$1(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);}};// 这个函数定义为react warnginwarnAboutAccessingKey.isReactWarning = true;// 给入参的key属性定义getter,避免外界访问Object.defineProperty(props, 'key', {get: warnAboutAccessingKey,configurable: true});
}// 这部分内容跟key的非常类似
// 定义ref的获取方法
function defineRefPropWarningGetter(props, displayName) {var warnAboutAccessingRef = function () {if (!specialPropRefWarningShown) {specialPropRefWarningShown = true;warningWithoutStack$1(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});
}
接下来react内部定义了一个对象ReactSharedInternals
,其内部包含了一些方法获取全局公用的一些方法,比如ReactCurrentDispatcher
(hooks相关功能)等,接下来又定义了带有堆栈信息的warning方法,其实就是getStackAddendum
的结果拼装warningWithoutStack$1
。接下来通过一个常量定义了react Element(元素)属性的保留字:key
,ref
,__self
和__source
。接下来定义了验证是否有可用key或ref的方法。
未完待续…
结尾
出于篇幅考虑,本篇的源码分析就告一段落,下一篇出炉时链接将同步在这里。有什么错漏欢迎评论区讨论,关于官方注释的翻译有不妥之处也请指出~
仓库地址:
react16.8.3源码注释仓库
下一篇:
施工中
如若内容造成侵权/违法违规/事实不符,请联系编程学习网邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
相关文章
- LeetCode-Python-1461. 检查一个字符串是否包含所有长度为 K 的二进制子串 (字符串 + 数学)
给你一个二进制字符串 s 和一个整数 k 。如果所有长度为 k 的二进制字符串都是 s 的子串,请返回 True ,否则请返回 False 。示例 1:输入:s = "00110110", k = 2 输出:true 解释:长度为 2 的二进制串包括 "00","01","10" 和 &q…...
2024/4/29 1:17:02 - 基于Flask开发网站--利用复选框进行批量操作
由于近期有同事在工作中向我求助网页可视化怎么做,对于从来没有学过html/vue/javascript等框架开发的我来说,只能说我试试吧。所以针对他的诉求“通过复选框进行批量操作”,我自己就百度学习。然后写点东西记录下,或者对以后的同学有所帮助。效果展示知识串讲由于之前我写过…...
2024/5/2 9:06:53 - Linux 高级命令汇总
1. 从一个文件夹中随机拷贝一定数量的图片,放到另外一个文件夹中find img_path_one -name *.jpg | shuf -n1000 | xargs -i cp {} img_path_two注释:该命令从img_path_one中找到所有以.jpg结尾的文件,打乱后取出1000个文件,然后将这1000个文件存放在img_path_two中。...
2024/4/24 14:36:34 - xshell窗口标题、切换栏不见了、只能打开一个窗口的处理办法
【问题】xshell窗口切换栏不见了的处理办法【方法】xshell窗口标题没了,多个窗口不能切换。解决办法 ctrl + shift + t 【可能是不小心按到了ctrl + shift + t所以才不见的】 【结果】成功...
2024/4/24 14:36:37 - 5303—K3 Cloud 随笔
1—调取基础资料DynamicObject[] matBaseData=BusinessDataServiceHelper.Load(this.Context,new object[]{ materialId},(MetaDataServiceHelper.Load(this.Context, "BD_MATERIAL") as FormMetadata).BusinessInfo.GetDynamicObjectType());if(matBaseData==null …...
2024/4/24 14:36:33 - 浏览器中输入URL后,执行的全部过程。会用到哪些协议?(一次完整的HTTP请求过程)
一次完整的HTTP请求过程: 1.首先进行域名解析,域名解析具体过程讲一下:浏览器搜索自己的DNS缓存,缓存中维护一张域名与IP地址的对应表;若没有,则搜索操作系统的DNS缓存;若没有,则操作系统将域名发送至本地域名服务器(递归查询方式),本地域名服务器查询自己的DNS缓存…...
2024/4/24 14:36:31 - Spring —— java Mail的简单使用
Spring —— java Mail的简单使用在Maven项目pom文件添加依赖<dependencies><!--spring 依赖--><dependency><groupId>org.springframework</groupId><artifactId>spring-context</artifactId><version>4.3.12.RELEASE</ve…...
2024/4/24 14:36:30 - Matlab 生成C/C++代码,调用C/C++
matlab官方介绍页: https://ww2.mathworks.cn/help/simulink/ug/code-generation-readiness-tool.html coder.screener 确定函数是否适合代码生成 https://ww2.mathworks.cn/help/simulink/slref/coder.screener.html C/C++ 代码生成支持的函数和对象: https://ww2.mathworks.…...
2024/4/24 14:36:29 - 在Python中调用df.to_csv()出现中文乱码的解决办法
df = pd.DataFrame(data=total_info, columns=[‘公司全名’, ‘公司简称’, ‘公司规模’, ‘融资阶段’, ‘区域’, ‘职位名称’, ‘工作经验’, ‘学历要求’, ‘薪资’, ‘职位福利’, ‘经营范围’, ‘职位类型’, ‘公司福利’, ‘第二职位类型’, ‘城市’]) df.to_csv…...
2024/4/15 3:09:25 - 企业公众号增加对接h5页面底部菜单
登录微信公众号后台 如果自定义菜单可以直接用,就可以在这里创建我的方式:通过代码根据微信接口文档 https://developers.weixin.qq.com/doc/offiaccount/Custom_Menus/Creating_Custom-Defined_Menu.html需要直接跳转h5页面 已有对应 URL使用 创建菜单接口新建一个信任管理…...
2024/4/15 3:09:24 - 异步之事件
添加事件处理程序 有三种方式。html指定事件处理程序<body onclick="sayHi()">hello world<script>function sayHi(){console.log(hi~);}</script> </body>通过window.event访问事件对象DOM0级事件处理程序<body>hello world<scrip…...
2024/4/17 13:00:31 - UE4自定义资源编辑器开发-Slate语法
UE4自定义资源编辑器开发-Slate语法...
2024/4/15 3:09:22 - Prometheus 钉钉自定义告警模板实现
配置钉钉告警配置钉钉告警请参阅: https://blog.csdn.net/knight_zhou/article/details/105583741实现钉钉的模板配置:我们先来看看二进制包的命令行参数:$/opt/prometheus/server/ding/prometheus-webhook-dingtalk/prometheus-webhook-dingtalk -h usage: prometheus-web…...
2024/4/24 14:36:28 - Leetcode刷题-最长公共前缀
Leetcode刷题-最长公共前缀简介题目个人答案及结果学习一下官方的 简介 最近尝试下大家口口相传的神器 leetcode-cn.com,大家自己注册就可以选择题库进行使用了。我都会先自己出一个答案,然后再学习别人的标准答案,进行自我提升。 题目个人答案及结果 我直接把相关注释再代…...
2024/4/24 14:36:32 - 2个小时教会你“卷积神经网络:识别猫猫狗狗莺莺燕燕”!
进群申请请填写:”moCSDN“! ![](https://upload-images.jianshu.io/upload_images...
2024/4/24 14:36:26 - Go语言 etcd/clientv3报错: etcd undefined: resolver.BuildOptio 问题解决思路
故障描述 github.com/coreos/etcd/clientv3 ..\..\github.com\coreos\etcd\clientv3\auth.go:125:72: cannot use auth.callOpts (type []"github.com/coreos/etcd/vendor/google.golang.org/grpc".CallOption) as type []"go.etcd.io/etcd/vendor/google.golan…...
2024/4/24 14:36:28 - H分公司局域网服务搭建课设
H分公司局域网服务搭建一、项目设计意义及目的二、项目需求分析三、项目基本功能四、关键技术分析(见我上传的资源)五、总体设计方案六、项目脚本 一、项目设计意义及目的 本项目研究的开发环境基于Windows10操作系统,并安装由思科公司于2008年发布的虚拟网络软件Graphical …...
2024/4/24 14:36:24 - 量化交易基础知识
量化交易现代统计学和机器学习的结合 计算机技术 用于进行证券投资的方式 主要利用一些数学模型来固化投资规律需要掌握的技能: 计算机技术 金融基础知识 数据挖掘技术分类:我们做的主要是第二步的市场中性趋势性交易主要适用于主观交易的高手,适用于价值投资,著名代表就是…...
2024/4/24 14:36:26 - Python编程:从入门到实践(超清完整版)带书签全书源代码.pdf
书籍目录 第一部分 基础知识第1章 起步 1.1 搭建编程环境 1.1.1 Python 2和Python 3 1.1.2 运行Python代码片段 1.1.3 Hello World程序 1.2 在不同操作系统中搭建Python编程环境 1.2.1 在Linux系统中搭建Python编程环境 1.2.2 在OS X系统中搭建Python编程…...
2024/4/24 14:36:23 - YUV 420P / YUV 444P 转 JPEG
最近整理之前代码,发现之前写过一个利用jpeg库将 yuv420p/yuv444p转为指定大小的jpeg格式图片的代码,共享出来供小伙伴们参考。JmJpegHelper.h// //Created by Jimmy.Wei on 2018-02-13 // #ifndef _JPEG_HELPER_H_ #define _JPEG_HELPER_H_#include <stdlib.h> // //C…...
2024/4/24 14:36:24
最新文章
- 【yolov8】yolov8剪枝训练流程
yolov8剪枝训练流程 流程: 约束剪枝微调 一、正常训练 yolo train model./weights/yolov8s.pt datayolo_bvn.yaml epochs100 ampFalse projectprun nametrain二、约束训练 2.1 修改YOLOv8代码: ultralytics/yolo/engine/trainer.py 添加内容&#…...
2024/5/2 11:25:35 - 梯度消失和梯度爆炸的一些处理方法
在这里是记录一下梯度消失或梯度爆炸的一些处理技巧。全当学习总结了如有错误还请留言,在此感激不尽。 权重和梯度的更新公式如下: w w − η ⋅ ∇ w w w - \eta \cdot \nabla w ww−η⋅∇w 个人通俗的理解梯度消失就是网络模型在反向求导的时候出…...
2024/3/20 10:50:27 - 汽车疲劳测试试验平台技术要求(北重厂家)
汽车疲劳测试试验平台技术要求通常包括以下几个方面: 车辆加载能力:测试平台需要具备足够的承载能力,能够同时测试多种车型和不同重量的车辆。 动力系统:测试平台需要具备稳定可靠的动力系统,能够提供足够的力和速度来…...
2024/5/1 13:14:16 - Nginx配置文件修改结合内网穿透实现公网访问多个本地web站点
文章目录 1. 下载windows版Nginx2. 配置Nginx3. 测试局域网访问4. cpolar内网穿透5. 测试公网访问6. 配置固定二级子域名7. 测试访问公网固定二级子域名 1. 下载windows版Nginx 进入官方网站(http://nginx.org/en/download.html)下载windows版的nginx 下载好后解压进入nginx目…...
2024/5/1 13:14:34 - 【外汇早评】美通胀数据走低,美元调整
原标题:【外汇早评】美通胀数据走低,美元调整昨日美国方面公布了新一期的核心PCE物价指数数据,同比增长1.6%,低于前值和预期值的1.7%,距离美联储的通胀目标2%继续走低,通胀压力较低,且此前美国一季度GDP初值中的消费部分下滑明显,因此市场对美联储后续更可能降息的政策…...
2024/5/1 17:30:59 - 【原油贵金属周评】原油多头拥挤,价格调整
原标题:【原油贵金属周评】原油多头拥挤,价格调整本周国际劳动节,我们喜迎四天假期,但是整个金融市场确实流动性充沛,大事频发,各个商品波动剧烈。美国方面,在本周四凌晨公布5月份的利率决议和新闻发布会,维持联邦基金利率在2.25%-2.50%不变,符合市场预期。同时美联储…...
2024/4/30 18:14:14 - 【外汇周评】靓丽非农不及疲软通胀影响
原标题:【外汇周评】靓丽非农不及疲软通胀影响在刚结束的周五,美国方面公布了新一期的非农就业数据,大幅好于前值和预期,新增就业重新回到20万以上。具体数据: 美国4月非农就业人口变动 26.3万人,预期 19万人,前值 19.6万人。 美国4月失业率 3.6%,预期 3.8%,前值 3…...
2024/4/29 2:29:43 - 【原油贵金属早评】库存继续增加,油价收跌
原标题:【原油贵金属早评】库存继续增加,油价收跌周三清晨公布美国当周API原油库存数据,上周原油库存增加281万桶至4.692亿桶,增幅超过预期的74.4万桶。且有消息人士称,沙特阿美据悉将于6月向亚洲炼油厂额外出售更多原油,印度炼油商预计将每日获得至多20万桶的额外原油供…...
2024/5/2 9:28:15 - 【外汇早评】日本央行会议纪要不改日元强势
原标题:【外汇早评】日本央行会议纪要不改日元强势近两日日元大幅走强与近期市场风险情绪上升,避险资金回流日元有关,也与前一段时间的美日贸易谈判给日本缓冲期,日本方面对汇率问题也避免继续贬值有关。虽然今日早间日本央行公布的利率会议纪要仍然是支持宽松政策,但这符…...
2024/4/27 17:58:04 - 【原油贵金属早评】欧佩克稳定市场,填补伊朗问题的影响
原标题:【原油贵金属早评】欧佩克稳定市场,填补伊朗问题的影响近日伊朗局势升温,导致市场担忧影响原油供给,油价试图反弹。此时OPEC表态稳定市场。据消息人士透露,沙特6月石油出口料将低于700万桶/日,沙特已经收到石油消费国提出的6月份扩大出口的“适度要求”,沙特将满…...
2024/4/27 14:22:49 - 【外汇早评】美欲与伊朗重谈协议
原标题:【外汇早评】美欲与伊朗重谈协议美国对伊朗的制裁遭到伊朗的抗议,昨日伊朗方面提出将部分退出伊核协议。而此行为又遭到欧洲方面对伊朗的谴责和警告,伊朗外长昨日回应称,欧洲国家履行它们的义务,伊核协议就能保证存续。据传闻伊朗的导弹已经对准了以色列和美国的航…...
2024/4/28 1:28:33 - 【原油贵金属早评】波动率飙升,市场情绪动荡
原标题:【原油贵金属早评】波动率飙升,市场情绪动荡因中美贸易谈判不安情绪影响,金融市场各资产品种出现明显的波动。随着美国与中方开启第十一轮谈判之际,美国按照既定计划向中国2000亿商品征收25%的关税,市场情绪有所平复,已经开始接受这一事实。虽然波动率-恐慌指数VI…...
2024/4/30 9:43:09 - 【原油贵金属周评】伊朗局势升温,黄金多头跃跃欲试
原标题:【原油贵金属周评】伊朗局势升温,黄金多头跃跃欲试美国和伊朗的局势继续升温,市场风险情绪上升,避险黄金有向上突破阻力的迹象。原油方面稍显平稳,近期美国和OPEC加大供给及市场需求回落的影响,伊朗局势并未推升油价走强。近期中美贸易谈判摩擦再度升级,美国对中…...
2024/4/27 17:59:30 - 【原油贵金属早评】市场情绪继续恶化,黄金上破
原标题:【原油贵金属早评】市场情绪继续恶化,黄金上破周初中国针对于美国加征关税的进行的反制措施引发市场情绪的大幅波动,人民币汇率出现大幅的贬值动能,金融市场受到非常明显的冲击。尤其是波动率起来之后,对于股市的表现尤其不安。隔夜美国股市出现明显的下行走势,这…...
2024/4/25 18:39:16 - 【外汇早评】美伊僵持,风险情绪继续升温
原标题:【外汇早评】美伊僵持,风险情绪继续升温昨日沙特两艘油轮再次发生爆炸事件,导致波斯湾局势进一步恶化,市场担忧美伊可能会出现摩擦生火,避险品种获得支撑,黄金和日元大幅走强。美指受中美贸易问题影响而在低位震荡。继5月12日,四艘商船在阿联酋领海附近的阿曼湾、…...
2024/4/28 1:34:08 - 【原油贵金属早评】贸易冲突导致需求低迷,油价弱势
原标题:【原油贵金属早评】贸易冲突导致需求低迷,油价弱势近日虽然伊朗局势升温,中东地区几起油船被袭击事件影响,但油价并未走高,而是出于调整结构中。由于市场预期局势失控的可能性较低,而中美贸易问题导致的全球经济衰退风险更大,需求会持续低迷,因此油价调整压力较…...
2024/4/26 19:03:37 - 氧生福地 玩美北湖(上)——为时光守候两千年
原标题:氧生福地 玩美北湖(上)——为时光守候两千年一次说走就走的旅行,只有一张高铁票的距离~ 所以,湖南郴州,我来了~ 从广州南站出发,一个半小时就到达郴州西站了。在动车上,同时改票的南风兄和我居然被分到了一个车厢,所以一路非常愉快地聊了过来。 挺好,最起…...
2024/4/29 20:46:55 - 氧生福地 玩美北湖(中)——永春梯田里的美与鲜
原标题:氧生福地 玩美北湖(中)——永春梯田里的美与鲜一觉醒来,因为大家太爱“美”照,在柳毅山庄去寻找龙女而错过了早餐时间。近十点,向导坏坏还是带着饥肠辘辘的我们去吃郴州最富有盛名的“鱼头粉”。说这是“十二分推荐”,到郴州必吃的美食之一。 哇塞!那个味美香甜…...
2024/4/30 22:21:04 - 氧生福地 玩美北湖(下)——奔跑吧骚年!
原标题:氧生福地 玩美北湖(下)——奔跑吧骚年!让我们红尘做伴 活得潇潇洒洒 策马奔腾共享人世繁华 对酒当歌唱出心中喜悦 轰轰烈烈把握青春年华 让我们红尘做伴 活得潇潇洒洒 策马奔腾共享人世繁华 对酒当歌唱出心中喜悦 轰轰烈烈把握青春年华 啊……啊……啊 两…...
2024/5/1 4:32:01 - 扒开伪装医用面膜,翻六倍价格宰客,小姐姐注意了!
原标题:扒开伪装医用面膜,翻六倍价格宰客,小姐姐注意了!扒开伪装医用面膜,翻六倍价格宰客!当行业里的某一品项火爆了,就会有很多商家蹭热度,装逼忽悠,最近火爆朋友圈的医用面膜,被沾上了污点,到底怎么回事呢? “比普通面膜安全、效果好!痘痘、痘印、敏感肌都能用…...
2024/4/27 23:24:42 - 「发现」铁皮石斛仙草之神奇功效用于医用面膜
原标题:「发现」铁皮石斛仙草之神奇功效用于医用面膜丽彦妆铁皮石斛医用面膜|石斛多糖无菌修护补水贴19大优势: 1、铁皮石斛:自唐宋以来,一直被列为皇室贡品,铁皮石斛生于海拔1600米的悬崖峭壁之上,繁殖力差,产量极低,所以古代仅供皇室、贵族享用 2、铁皮石斛自古民间…...
2024/4/28 5:48:52 - 丽彦妆\医用面膜\冷敷贴轻奢医学护肤引导者
原标题:丽彦妆\医用面膜\冷敷贴轻奢医学护肤引导者【公司简介】 广州华彬企业隶属香港华彬集团有限公司,专注美业21年,其旗下品牌: 「圣茵美」私密荷尔蒙抗衰,产后修复 「圣仪轩」私密荷尔蒙抗衰,产后修复 「花茵莳」私密荷尔蒙抗衰,产后修复 「丽彦妆」专注医学护…...
2024/4/30 9:42:22 - 广州械字号面膜生产厂家OEM/ODM4项须知!
原标题:广州械字号面膜生产厂家OEM/ODM4项须知!广州械字号面膜生产厂家OEM/ODM流程及注意事项解读: 械字号医用面膜,其实在我国并没有严格的定义,通常我们说的医美面膜指的应该是一种「医用敷料」,也就是说,医用面膜其实算作「医疗器械」的一种,又称「医用冷敷贴」。 …...
2024/5/2 9:07:46 - 械字号医用眼膜缓解用眼过度到底有无作用?
原标题:械字号医用眼膜缓解用眼过度到底有无作用?医用眼膜/械字号眼膜/医用冷敷眼贴 凝胶层为亲水高分子材料,含70%以上的水分。体表皮肤温度传导到本产品的凝胶层,热量被凝胶内水分子吸收,通过水分的蒸发带走大量的热量,可迅速地降低体表皮肤局部温度,减轻局部皮肤的灼…...
2024/4/30 9:42:49 - 配置失败还原请勿关闭计算机,电脑开机屏幕上面显示,配置失败还原更改 请勿关闭计算机 开不了机 这个问题怎么办...
解析如下:1、长按电脑电源键直至关机,然后再按一次电源健重启电脑,按F8健进入安全模式2、安全模式下进入Windows系统桌面后,按住“winR”打开运行窗口,输入“services.msc”打开服务设置3、在服务界面,选中…...
2022/11/19 21:17:18 - 错误使用 reshape要执行 RESHAPE,请勿更改元素数目。
%读入6幅图像(每一幅图像的大小是564*564) f1 imread(WashingtonDC_Band1_564.tif); subplot(3,2,1),imshow(f1); f2 imread(WashingtonDC_Band2_564.tif); subplot(3,2,2),imshow(f2); f3 imread(WashingtonDC_Band3_564.tif); subplot(3,2,3),imsho…...
2022/11/19 21:17:16 - 配置 已完成 请勿关闭计算机,win7系统关机提示“配置Windows Update已完成30%请勿关闭计算机...
win7系统关机提示“配置Windows Update已完成30%请勿关闭计算机”问题的解决方法在win7系统关机时如果有升级系统的或者其他需要会直接进入一个 等待界面,在等待界面中我们需要等待操作结束才能关机,虽然这比较麻烦,但是对系统进行配置和升级…...
2022/11/19 21:17:15 - 台式电脑显示配置100%请勿关闭计算机,“准备配置windows 请勿关闭计算机”的解决方法...
有不少用户在重装Win7系统或更新系统后会遇到“准备配置windows,请勿关闭计算机”的提示,要过很久才能进入系统,有的用户甚至几个小时也无法进入,下面就教大家这个问题的解决方法。第一种方法:我们首先在左下角的“开始…...
2022/11/19 21:17:14 - win7 正在配置 请勿关闭计算机,怎么办Win7开机显示正在配置Windows Update请勿关机...
置信有很多用户都跟小编一样遇到过这样的问题,电脑时发现开机屏幕显现“正在配置Windows Update,请勿关机”(如下图所示),而且还需求等大约5分钟才干进入系统。这是怎样回事呢?一切都是正常操作的,为什么开时机呈现“正…...
2022/11/19 21:17:13 - 准备配置windows 请勿关闭计算机 蓝屏,Win7开机总是出现提示“配置Windows请勿关机”...
Win7系统开机启动时总是出现“配置Windows请勿关机”的提示,没过几秒后电脑自动重启,每次开机都这样无法进入系统,此时碰到这种现象的用户就可以使用以下5种方法解决问题。方法一:开机按下F8,在出现的Windows高级启动选…...
2022/11/19 21:17:12 - 准备windows请勿关闭计算机要多久,windows10系统提示正在准备windows请勿关闭计算机怎么办...
有不少windows10系统用户反映说碰到这样一个情况,就是电脑提示正在准备windows请勿关闭计算机,碰到这样的问题该怎么解决呢,现在小编就给大家分享一下windows10系统提示正在准备windows请勿关闭计算机的具体第一种方法:1、2、依次…...
2022/11/19 21:17:11 - 配置 已完成 请勿关闭计算机,win7系统关机提示“配置Windows Update已完成30%请勿关闭计算机”的解决方法...
今天和大家分享一下win7系统重装了Win7旗舰版系统后,每次关机的时候桌面上都会显示一个“配置Windows Update的界面,提示请勿关闭计算机”,每次停留好几分钟才能正常关机,导致什么情况引起的呢?出现配置Windows Update…...
2022/11/19 21:17:10 - 电脑桌面一直是清理请关闭计算机,windows7一直卡在清理 请勿关闭计算机-win7清理请勿关机,win7配置更新35%不动...
只能是等着,别无他法。说是卡着如果你看硬盘灯应该在读写。如果从 Win 10 无法正常回滚,只能是考虑备份数据后重装系统了。解决来方案一:管理员运行cmd:net stop WuAuServcd %windir%ren SoftwareDistribution SDoldnet start WuA…...
2022/11/19 21:17:09 - 计算机配置更新不起,电脑提示“配置Windows Update请勿关闭计算机”怎么办?
原标题:电脑提示“配置Windows Update请勿关闭计算机”怎么办?win7系统中在开机与关闭的时候总是显示“配置windows update请勿关闭计算机”相信有不少朋友都曾遇到过一次两次还能忍但经常遇到就叫人感到心烦了遇到这种问题怎么办呢?一般的方…...
2022/11/19 21:17:08 - 计算机正在配置无法关机,关机提示 windows7 正在配置windows 请勿关闭计算机 ,然后等了一晚上也没有关掉。现在电脑无法正常关机...
关机提示 windows7 正在配置windows 请勿关闭计算机 ,然后等了一晚上也没有关掉。现在电脑无法正常关机以下文字资料是由(历史新知网www.lishixinzhi.com)小编为大家搜集整理后发布的内容,让我们赶快一起来看一下吧!关机提示 windows7 正在配…...
2022/11/19 21:17:05 - 钉钉提示请勿通过开发者调试模式_钉钉请勿通过开发者调试模式是真的吗好不好用...
钉钉请勿通过开发者调试模式是真的吗好不好用 更新时间:2020-04-20 22:24:19 浏览次数:729次 区域: 南阳 > 卧龙 列举网提醒您:为保障您的权益,请不要提前支付任何费用! 虚拟位置外设器!!轨迹模拟&虚拟位置外设神器 专业用于:钉钉,外勤365,红圈通,企业微信和…...
2022/11/19 21:17:05 - 配置失败还原请勿关闭计算机怎么办,win7系统出现“配置windows update失败 还原更改 请勿关闭计算机”,长时间没反应,无法进入系统的解决方案...
前几天班里有位学生电脑(windows 7系统)出问题了,具体表现是开机时一直停留在“配置windows update失败 还原更改 请勿关闭计算机”这个界面,长时间没反应,无法进入系统。这个问题原来帮其他同学也解决过,网上搜了不少资料&#x…...
2022/11/19 21:17:04 - 一个电脑无法关闭计算机你应该怎么办,电脑显示“清理请勿关闭计算机”怎么办?...
本文为你提供了3个有效解决电脑显示“清理请勿关闭计算机”问题的方法,并在最后教给你1种保护系统安全的好方法,一起来看看!电脑出现“清理请勿关闭计算机”在Windows 7(SP1)和Windows Server 2008 R2 SP1中,添加了1个新功能在“磁…...
2022/11/19 21:17:03 - 请勿关闭计算机还原更改要多久,电脑显示:配置windows更新失败,正在还原更改,请勿关闭计算机怎么办...
许多用户在长期不使用电脑的时候,开启电脑发现电脑显示:配置windows更新失败,正在还原更改,请勿关闭计算机。。.这要怎么办呢?下面小编就带着大家一起看看吧!如果能够正常进入系统,建议您暂时移…...
2022/11/19 21:17:02 - 还原更改请勿关闭计算机 要多久,配置windows update失败 还原更改 请勿关闭计算机,电脑开机后一直显示以...
配置windows update失败 还原更改 请勿关闭计算机,电脑开机后一直显示以以下文字资料是由(历史新知网www.lishixinzhi.com)小编为大家搜集整理后发布的内容,让我们赶快一起来看一下吧!配置windows update失败 还原更改 请勿关闭计算机&#x…...
2022/11/19 21:17:01 - 电脑配置中请勿关闭计算机怎么办,准备配置windows请勿关闭计算机一直显示怎么办【图解】...
不知道大家有没有遇到过这样的一个问题,就是我们的win7系统在关机的时候,总是喜欢显示“准备配置windows,请勿关机”这样的一个页面,没有什么大碍,但是如果一直等着的话就要两个小时甚至更久都关不了机,非常…...
2022/11/19 21:17:00 - 正在准备配置请勿关闭计算机,正在准备配置windows请勿关闭计算机时间长了解决教程...
当电脑出现正在准备配置windows请勿关闭计算机时,一般是您正对windows进行升级,但是这个要是长时间没有反应,我们不能再傻等下去了。可能是电脑出了别的问题了,来看看教程的说法。正在准备配置windows请勿关闭计算机时间长了方法一…...
2022/11/19 21:16:59 - 配置失败还原请勿关闭计算机,配置Windows Update失败,还原更改请勿关闭计算机...
我们使用电脑的过程中有时会遇到这种情况,当我们打开电脑之后,发现一直停留在一个界面:“配置Windows Update失败,还原更改请勿关闭计算机”,等了许久还是无法进入系统。如果我们遇到此类问题应该如何解决呢࿰…...
2022/11/19 21:16:58 - 如何在iPhone上关闭“请勿打扰”
Apple’s “Do Not Disturb While Driving” is a potentially lifesaving iPhone feature, but it doesn’t always turn on automatically at the appropriate time. For example, you might be a passenger in a moving car, but your iPhone may think you’re the one dri…...
2022/11/19 21:16:57