从0到1建立前端规范

本文适合打算建立前端规范的小伙伴阅读
一、为什么需要规范

规范能给我们带来什么好处,如果没有规范会造成什么后果?这里主要拿代码规范来说。

统一代码规范的好处:

  1. 提高代码整体的可读性、可维护性、可复用性、可移植性和可靠性,这会从根本上降低开发成本,也是最重要的一点。
  2. 保证代码的一致性:软件系统中最重要的因素之一就是编码的一致性。如果编码风格一致,也更加易于维护,因为团队内任何人都可以快速理解并修改。
  3. 提升团队整体效率:开发人员通常需要花费大量的时间来解决代码质量问题,如果都按照规范编写,也有助于团队尽早发现问题,甚至完全预防问题,这将提高整个交付过程的效率。
  4. 减少code review期间一系列的争议,因为缺乏标准,在争议过程中双方很难妥协(没少因为这事争论过😕)。

若不统一代码规范,可能会造成的后果:

  1. 由于缺乏规范,导致代码风格不一,增加团队成员间的心理负担,极端情况下,某段代码只有某个人能修改(俗称屎山💩)。
  2. 团队间协作更加困难:因为开发人员得适应不同的风格,会导致效率低下(阅读代码是我们花费时间最多的地方)。
  3. 在code review期间可能经常为类似的事情做过多的讨论。
  4. 影响团队的生产力和质量,严重的甚至会影响团队和谐。

二、为什么依然有很多团队缺乏规范

在这件事上,很难达成一致是我认为最重要的原因。并且,仅仅只是拥有规范也是不够的:

  • 当开发人员被要求在短时间内完成任务时,通常会回避质量标准。
  • 团队中总是有一些有个性的人不会为了团队去改变自己的习惯。
  • 有些人在会议上就约定达成了一致,在会下依旧我行我素。

三、如何保持规范

我曾想通过会议讨论的方式来制定规范,但效果却差强人意。将失败的原因总结为大致几点:

  1. 在会议中,思维很容易发散,经常出现的情况是讨论了很多,却很难有实际性的成效,在开发中依然有不少人选择无视规则
  2. 正式的会议往往很难组织,大家很难一起有空闲的时间来讨论,一次/两周 都很困难。
  3. 会议中对实际案例分析,提出若干点优化建议后,没有对问题的优先级和侧重点进行划分,导致实际效果并不好。
  4. 还有一点也是我自己的原因,组织会议的能力有待提升…😭

经历了上述的挫败之后,经过反复复盘总结,决定换一种方式来执行:

  1. 对规范问题进行归纳分析并通过文档记录(wiki等),在团队内进行统一。
  2. 采用小步快跑的方式,有问题就解决问题,按照优先级和重要性进行排序划分,依次将问题纳入迭代,每个迭代重点解决其中几个即好。
  3. 本迭代的规范问题绝不留到下个迭代,防止堆积(当然,有时候还是得向项目经理妥协😮‍💨)。
  4. 在code review过程中严格把关,拒绝睁一只眼👀闭一只眼🧐。
  5. 当团队成员对具体某个规范有争议时,及时讨论并定出结论。
  6. 没有规则只是为了规则,制定规范的目的并不是一定要按照某某标准来执行,更多的是团队成员达成一致即可。
  7. 鼓励大家大胆的质疑规则,若不能提高代码的可读性,可维护性,可复用性,可移植性和可靠性的规则都应该被受到质疑。

四、开发者需要建立和遵守的规范

大致可以划分成这几个方向:

  • 开发流程规范
  • 代码规范
  • git commit规范
  • 项目文件结构规范
  • UI设计规范
开发流程规范

这里可能有小伙伴有疑问了,开发流程规范不是项目经理定的吗🤔️,跟我有什么关系?

这里想告诉大家的是,开发流程在一定程度上应该是由我们自己来掌控。不管是传统开发的模式还是敏捷开发的模式,对于开发者来说核心依旧是高质高效的完成用户提出的需求

笔者曾见过不少开发者在拿到产品经理的需求后就开始急匆匆的写代码,以此来体现他们的高效,但往往却因为需求理解不到位和前期代码欠缺设计导致bug率高和返工。

如何找到适合自己的开发流程是需要依靠经验来支撑的,需要反复总结和思考,最终达到高质高效完成的目的。

说一说笔者自己比较喜欢的开发流程:

在这里插入图片描述

在接收到需求后应第一时间去了解这个需求的背景是什么?这么做到底有没有解决用户的痛点?或者说用户更深层次的需求是什么?如果团队的产品经理经验不丰富,往往可以在这个阶段砍掉很多不合理的需求(这一点真的很重要)

对于复杂大功能往往还需要进行技术方案调研技术方案设计,并输出详细的设计文档。涉及到细节上,则需要将数据流走向、组件设计等通过脑图的形式呈现出来。

代码规范之格式化规范

由于每个开发者的IDE( 集成开发环境: 用于提供程序开发环境的应用程序,是集成了代码编写功能、分析功能、编译功能、调试功能等一体化的开发软件服务套)不同,即使IDE相同也会因为每个人的配置不一样导致格式化的结果不一样。如何确保团队内开发人员采用统一的格式化配置呢?

这里给推荐大家使用 prettier,它内置了一套格式化的规则,具体配置:

  1. 安装依赖:
npm install --save-dev --save-exact prettier 
// or
yarn add --dev --exact prettie
  1. 创建一个空配置文件,让编辑器和其他工具知道你正在使用 Prettier:
echo {}> .prettierrc.jso
  1. 创建一个.prettierignore文件,让 Prettier CLI 和编辑器知道哪些文件不能格式化,example:
# Ignore artifacts:
dist
build
coverag
  1. 配置编辑器(VScode为例)

    IDE中安装 Prettier-Code Formater 插件:

在这里插入图片描述

找到IDE中设置模块,搜索format On Save,勾上这个就可以了。
在这里插入图片描述

现在当我们 Ctrl + S 保存代码时,插件就会帮助我们自动格式化了

这里有小伙伴要问了,要是有人将没有格式化的代码提交上去怎么办?

这时候就需要在 git commit 的阶段自动将提交的代码进行格式化,这里我们借助工具 husky,它主要可以帮助我们在 git 阶段检查提交消息、运行测试、检查代码等。没接触过的小伙伴可以去官网了解一下,配置如下:

  • 安装 husky 和 lint-staged:
 ```jsnpm install --save-dev husky lint-stagednpx husky installnpm set-script prepare "husky install"npx husky add .husky/pre-commit "npx lint-staged"// oryarn add --dev husky lint-stagednpx husky installnpm set-script prepare "husky install"npx husky add .husky/pre-commit "npx lint-staged```
  • 然后将以下内容添加到package.json中:
 ```js{"lint-staged": {"**/*": "prettier --write --ignore-unknown"}}```

​ 这段配置的意思是:当执行 git commit 阶段前,先执行lint-stagedlint-staged中的内容就是对暂存区的文件执行格式化的命令。

其他:若使用的是脚手架工具搭建的项目,会自带eslint配置(`eslintConfig`)。`prettier 和 eslint 会有一些配置上的冲突`,这个时候需要安装eslint-config-prettier 以使 ESLint 和 Prettier 相互配合,安装完后在`.eslintrc`中配置(以Create-React-App为例): 
"eslintConfig": {"extends": ["react-app","react-app/jest","prettier"]}
这样就可以用`"prettier"`的部分规则覆盖前面的规则,让它们都能正常工作。 

代码规范之JS/TS规范

JS/TS主流的大致有这几种:

  • Airbnb JavaScript Style Guide
  • Google JavaScript Style Guide
  • Idiomatic JavaScript Style Guide
  • JavaScript Standard Style Guide
  • jQuery JavaScript Style Guide

比较推荐使用 Airbnb JavaScript Style Guide,它在 Github 上足有 12万 star,几乎覆盖了 JavaScript 的每一项特性。

具体配置:

  • 安装依赖
npm install eslint --save-dev
// or
yarn add eslint --dev
  • 生成配置文件
npm init @eslint/config
// or
yarn create @eslint/config

跟着终端中的提示,按照自身需求一步步选择即可。

有了具体的规范后,我们同样需要使用工具去约束:还是通过在git commit阶段校验,若不通过则取消提交。

配置(还是在 package.json 中的 lint-staged

 "lint-staged": {"**/*": "prettier --write --ignore-unknown", //格式化"src/*": "eslint --ext .js,.ts,.tsx"  //进行eslint校验}

注意:这里如果选用的Typescript,则会默认使用@typescript-eslint/parser解析器,官方为了追求更快的解析速度,并不会对.ts文件中的类型进行检查,只会做语法检测。

如果需要对类型也进行检测,需要在extends中加上plugin:@typescript-eslint/recommended-requiring-type-checking。

索性这里换了另一种方式:在pre commit 中执行yarn run tsc,这里的意思是对项目中ts文件进行类型检测,默认会读取根目录中的tsconfig.json配置。

这种方式并不完美,它的弊端就在于全量检测,如果项目不大还好,若是项目代码量够多,检测10-20s也是常有的事。

代码规范之CSS规范

CSS检查代码规范使用 stylelint 插件,规范则推荐使用 stylelint-config-standard:

  • 安装
```js
npm install --save-dev stylelint stylelint-config-standar
```
  • 在项目的根目录中创建一个配置文件.stylelintrc.json,内容如下:
```js
{"extends": "stylelint-config-standard"
}
```
  • 解决与prettier配置的冲突:
```js
npm install --save-dev stylelint-config-prettier
```
  • 将下面配置复制到.stylelintrc.json中:

    {"extends": ["stylelint-config-standard", "stylelint-config-prettier"]
    }
    
  • 在 git commitv阶段进行检测:

```js
"lint-staged": {"**/*": "prettier --write --ignore-unknown", //格式化"src/**.{js,jsx,ts,tsx}": "eslint --ext .js,.jsx,.ts,.tsx", //对js文件检测"**/*.{less,css}": "stylelint --fix" //对css文件进行检测},
```

代码规范之自定义其他规范

下面列一些团队内定的其他规范:

  1. 命名规范

    变量的命名中应尽量减少缩写的情况发生,做到见名知意。

 ```js// 👎 自我感觉良好的缩写:let rContent = 'willen'; // 👍 无需对每个变量都写注释,从名字上就看懂let firstName = 'jackie'; // 👎 从命名无法知道返回值类型function showFriendsList() {....} // // 无法辨别函数意图,返回的是一个数组,还是一个对象,还是true or false?// 👍 明确函数意图,对于返回true or false的函数,最好以should/is/can/has开头function shouldShowFriendsList() {...}function isEmpty() {...}function canCreateDocuments() {...}function hasLicense() {...}function sendEmailToUser(user) {.... } //动词开头,函数意图就很明```
  1. 写注释

    在每个文件的顶部明确说明该组件做什么,有没有业务理解难点等等,对业务特殊函数/变量也需要写注释

 ```js/*** 导航页面-右边区域*/const Content=>()=>xxxconst MAX_INPUT_LENGTH = 8; //用于限制密码输入框function Component(props) {return (<>{/* 如果用户没有订阅则不展示广告 */}{user.subscribed ? null : <SubscriptionPlans />}</>)}```
  1. 变量兜底
 ```js// 👎 对于求值获取的变量,没有兜底const { data } = getApiRequest();data.map((s) => s.id); //没有考虑data异常的情况,代码一跑就爆炸// 👍 对于求值变量,做好兜底const { data = [] } = getApiRequest();data.map((s) => s?.id); //没有考虑data异常的情况,代码一跑就爆炸```
  1. 辅助函数必须是纯函数
 ```js// 👎 不要让功能函数的输出变化无常function plusAbc(a, b, c) {  // 这个函数的输出将变化无常,因为api返回的值一旦改变,同样输入函数的a,b,c的值,但函数返回的结果却不一定相同。var c = fetch('../api');return a+b+c;}// 👍 功能函数使用纯函数,输入一致,输出结果永远唯一function plusAbc(a, b, c) {  // 同样输入函数的a,b,c的值,但函数返回的结果永远相同。return a+b+c;}```
  1. 优先使用函数式编程
 ```js// 👎 使用for循环编程for(i = 1; i <= 10; i++) {a[i] = a[i] +1;}// 👍 使用函数式编程let b = a.map(item => ++item```
  1. 优先使用函数式组件

    除非需要用到错误边界,否则函数式组件应该是首选方法。

  2. 组件复杂度

 如果一个组件做的事情太多,应适当提取一些逻辑,将其拆分为更小的组件。如果提取的组件很复杂,则需要依照一定的规则和条件一一提取它。代码行数并不是一个客观的衡量标准,更多是需要考虑责任划分和抽象。
  1. 用错误边界

    当需要对大量数据进行渲染处理时,需要通过错误边界组件对其进行降级处理。

 ```jsfunction Component() {return (<Layout><ErrorBoundary><CardWidget /></ErrorBoundary><ErrorBoundary><FiltersWidget /></ErrorBoundary><div><ErrorBoundary><ProductList /></ErrorBoundary></div></Layout>)}```
  1. props参数传递

    props一层层传递一直是我们很头疼的一个问题,最核心的问题是不清楚props是从哪个初始组件传来的,以及props中到底有哪些东西,上下文是什么?

    因此对于传递较深的场景我推荐直接使用 context,对于 props 中的内容和上下文通过 TS 来解决。

 ```js// A.tsxinterface AProps {param: string;}const A = ({ param }: AProps) => {return <B param = {param} />;};// 👍 上下文清晰// B.tsxconst B = ({ param }: { param: AProps['param'] }) => {return <div>hello world</div>;};```
  1. props传参数量

    如果超过 5 个props,就该考虑是否拆分该组件。在某些情况下,这是需要对组件进行重构的标志。

    注意:组件使用的props越多,重新渲染的理由就越多。

  2. 避免嵌套三元运算符

    三元运算符在第一级之后变得难以阅读,虽然看起来节省了代码空间,但最好在代码中明确意图,保持良好的阅读性。

  ```js// 👎 不够清晰,要是再嵌套一层两层呢isSubscribed ? (<ArticleRecommendations />) : isRegistered ? (<SubscribeCallToAction />) : (<RegisterCallToAction />)// 👍 将判断逻辑进行拆分function CallToActionWidget({ subscribed, registered }) {if (subscribed) {return <ArticleRecommendations />}if (registered) {return <SubscribeCallToAction />}return <RegisterCallToAction />}function Component() {return (<CallToActionWidgetsubscribed={subscribed}registered={registered}/>)}```
  1. 将列表组件封装成独立组件
  ```js// 👎 列表渲染和其他逻辑杂糅在一起function Component({ topic, page, articles, onNextPage }) {return (<div><h1>{topic}</h1>{articles.map(article => (<div><h3>{article.title}</h3><p>{article.teaser}</p><img src={article.image} /></div>))}<div>You are on page {page}</div><button onClick={onNextPage}>Next</button></div>)}// 👍 将列表组件提取出来,一目了然function Component({ topic, page, articles, onNextPage }) {return (<div><h1>{topic}</h1><ArticlesList articles={articles} /><div>You are on page {page}</div><button onClick={onNextPage}>Next</button></div>)}```
  1. 避免嵌套渲染函数
  ```js// 👎 不要将其定义在渲染函数组件中function Component() {function renderHeader() {return <header>...</header>}return <div>{renderHeader()}</div>}// 👍 将其抽离到独立的组件中去import Header from '@modules/common/components/Header'function Component() {return (<div><Header /></div>)}```
  1. 组件/函数导入导出
  ```js// 👍 在文件头部导入,顺序依次为: 第三方库 > 公共组件/方法 > 非公共部分组件/方法import React from 'react'import _ from 'loadsh'import Header from '@components/header'import Content from './Content'// 👍 在底部导出export { Content, Header }export default Componen```

项目文件结构规范

在项目初期若不重视,到了后期就是到处天马行空,你很难在期望的目录下找到你想要的文件。

文件夹名称全部采用小写 + “-” 来隔开,index.ts更多是用来做导出作用,要不然最后编辑器中满屏的index.tsx,很难区分。

 - src 开发目录- pages 视图- module-a 模块A- components 私有组件- ComA.tsx- ComB.tsx- index.module.less- index.tsx- Content.tsx- module-b 模块B- components 公共组件- index.ts 导出所有组件- header- index.tsx- index.module.less- User.tsx- useGetBaseInfo.hooks.ts- routers 路由文件- store redux中的数据- utils 这里是以utils为后缀- index.ts- a.utils.ts- b.utils.ts- hooks 这里是以hooks为后缀- index.ts- a.hooks.ts- b.hooks.ts- styles 静态资源文件- service api请求,这里是以api为后缀- a.api.ts 按照后端微服务进行划分- b.api.ts- constans 常量

通过对工具函数、hooks、api 等加上后缀,更加容易区分引入的文件。

Git commit规范

git commit 规范主要可以帮助开发人员在 code review 期间更容易理解提交的内容,现在大部分主流 commit 规范都是基于Angular 团队的规范而衍生出来的,它的 message 格式如下:

<type>(<scope>): <subject>
<BLANK LINE>
<body>
<BLANK LINE>
<footer

每个提交消息都包含一个subject、一个body和一个footer (中间使用空行分割),提交信息的任何一行不能超过 100 个字符。

👉 type主要有以下几种类型:

  • feat: 一个新特性
  • fix: 修复bug
  • docs: 文档修改
  • style: 不影响代码含义的更改(空格、格式、缺少分号等)
  • refactor: 代码重构
  • perf: 优化性能
  • test: 测试用例修改
  • chore: 对构建过程或辅助工具和库的更改,例如文档生成

👉 scope:可以是影响范围的任何内容。

👉 subject:包含对更改的简洁描述,规则:

  • 使用陈述语句
  • 第一个字母不要大写
  • 末尾没有点 (.)

👉 body:commit 具体修改内容, 可以分为多行,应该包括改变的动机,并与以前的行为进行对比。

👉 footer: 一些备注, 通常是修复的 bug 的链接。

截取一张开源库的 commit,example:
在这里插入图片描述

有了规范后,我们需要通过工具去约束:commitlint。它要做的就是在我们每次提交 git commit 的时候,都会帮我们检查 commit message 是否符合一定的规范,如果不符合,就让这次提交失败。

具体配置:

# 安装 commitlint cli 和 conventional config
npm install --save-dev @commitlint/{config-conventional,cli}
# Windows:
npm install --save-dev @commitlint/config-conventional @commitlint/cli配置要使用的 commitlint 规则
echo "module.exports = {extends: ['@commitlint/config-conventional']}" > commitlint.config.js加入到husky中:
npx husky add .husky/commit-msg 'npx --no -- commitlint --edit "$1"'
or
yarn husky add .husky/commit-msg 'yarn commitlint --edit $1

UI设计规范

优秀的开发者应该反向推动UI的规范,并且能够支撑UI规范的落地。

UI 规范的最大好处就是能够提质提效:

  • 在开发者的角度,与设计规范同步形成研发资产,避免重复造轮子;
  • 在测试的角度,能够避免重复的无意义走查;
  • 在UI设计师的角度,减少设计成本,提高设计效率,可以快速承接新需求;
  • 站在产品角度,提高产品迭代与优化效率,降低试错成本;
  • 站在用户角度,解决用户体验一致性。

那到底应该怎么去推动UI规范?我的做法是先让设计师去给出一系列的规范,没有相关规范就拉上产品经理一起制定规范。然后前端建立一套自己的组件库,再将组件库提供给UI设计师,以此来相互监督是否达成了规范协议。

五、总结

统一规范的最根本目的是为了保证团队成员的一致性,从而减少沟通成本,提高开发效率。

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

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

相关文章

Ubuntu 22.04.3编译AOSP13刷机

文章目录 设备信息下载AOSP并切换分支获取设备驱动编译系统编译遇到的问题Cannot allocate memoryUbuntu设置USB调试刷机参考链接 设备信息 手机&#xff1a;Pixel 4XL 下载AOSP并切换分支 在清华大学开源软件镜像站下载初始化包aosp-latest.tar。 解压缩&#xff0c;切换到…

Hexo 还是 Hugo?Typecho 还是 Wordpress?读完这篇或许你就有答案了!

Hexo 首先介绍的是 Hexo,这也是咕咕没买服务器之前折腾的第一个博客。 演示站点:https://yirenliu.cn 用的主题是 butterfly,想当年刚用的时候,作者还没建群,现在 qq 群都有上千人了,GitHub 上的星星数量也有 2.7k 了。 优点 如果你不想买服务器,但也想折腾一个博客,…

【Web-Note】 JavaScript概述

JavaSript基本语法 JavaSript程序不能独立运行&#xff0c;必须依赖于HTML文件。 <script type "text/javascript" [src "外部文件"]> JS语句块; </script> script标记是成对标记。 type属性&#xff1a;说明脚本的类型。 "text/jav…

【全栈开发】RedwoodJS与BlitzJS:全栈JavaScript元框架的未来

Redwood和Blitz是两个即将出现的全栈元框架&#xff0c;它们提供了创建SPAs、服务器端渲染页面和静态生成内容的工具&#xff0c;并提供了生成端到端支架的CLI。我一直在等待一个有价值的Rails JavaScript替代品&#xff0c;谁知道什么时候。这篇文章是对两者的概述&#xff0c…

【C++】:拷贝构造函数与赋值运算符重载的实例应用之日期类的实现

C实现日期类 ├─属性&#xff1a; │ ├─年份 │ ├─月份 │ └─日期 ├─方法&#xff1a; │ ├─构造函数 │ ├─拷贝构造函数 │ ├─析构函数 │ ├─设置年份 │ ├─设置月份 │ ├─设置日期 │ ├─获取年份 │ ├─获取月份 │ ├─获取日期 │ ├…

HTML新特性【缩放图像、图像切片、平移、旋转、缩放、变形、裁切路径、时钟、运动的小球】(二)-全面详解(学习总结---从入门到深化)

目录 绘制图像_缩放图像 绘制图像_图像切片 Canvas状态的保存和恢复 图形变形_平移 图形变形_旋转 图形变形_缩放 图形变形_变形 裁切路径 动画_时钟 动画_运动的小球 引入外部SVG 绘制图像_缩放图像 ctx.drawImage(img, x, y, width, height) img &#xf…

C# 使用NPOI操作Excel的工具类

写在前面 NPOI是POI项目的.NET迁移版本。POI是一个开源的Java 读写 Excel、Word 等微软Ole2组件文档的项目&#xff1b;使用NPOI可以在没有安装Office或者相应环境的机器上对Word或Excel文档进行读写操作。 NPOI类库中操作EXCEL有两个模块分别是&#xff1a; 1️.HSSF模块&a…

Spring Beans;Spring Bean的生命周期;spring Bean的作用域,spring处理线程并发问题

文章目录 Spring Beans请解释Spring Bean的生命周期解释Spring支持的几种bean的作用域Spring容器中的bean可以分为5个范围&#xff1a; Spring如何处理线程并发问题&#xff1f; 在现在的项目开发中经常使用到spring bean&#xff0c;那么来谈谈spring bean的生命周期&#xff…

Lua脚本解决redis实现的分布式锁多条命令原子性问题

线程1现在持有锁之后&#xff0c;在执行业务逻辑过程中&#xff0c;他正准备删除锁&#xff0c;而且已经走到了条件判断的过程中&#xff0c;比如他已经拿到了当前这把锁确实是属于他自己的&#xff0c;正准备删除锁&#xff0c;但是此时他的锁到期了&#xff0c;那么此时线程2…

(三) Windows 下 Sublime Text 3 配置Python环境和Anaconda代码提示

一&#xff1a;新建一个 Python3.7 编译环境。 1 Tools--Build System--New Build System... 修改前&#xff1a; 修改后&#xff1a; 内容&#xff1a; {"cmd":["C:\\Python\\Python37-32\\python.exe","-u","$file"],"file_r…

复数的几何意义

1、复平面&#xff0c;复数的其它表示法 (1)几何表示法 直角平面坐标&#xff1a; 复平面 实轴&#xff0c;虚轴 (2)向量表示法 向量 模&#xff1a; 复数加减法可用向量的三角形法则或者平行四边形法则 (3)结论 (两边之和大于第三边) ((两边之差大于第三边)) *辐角&am…

FlinkCDC实现主数据与各业务系统数据的一致性(瀚高、TIDB)

文章末尾附有flinkcdc对应瀚高数据库flink-cdc-connector代码下载地址 1、业务需求 目前项目有主数据系统和N个业务系统,为保障“一数一源”,各业务系统表涉及到主数据系统的字段都需用主数据系统表中的字段进行实时覆盖,这里以某个业务系统的一张表举例说明:业务系统表Ta…

pytorch安装GPU版本 (Cuda12.1)教程

使用本教程前&#xff0c;默认您已经安装并配置好了python3以上版本 1. 去官网下载匹配的Cuda Cuda下载地址 当前最高版本的Cuda是12.1 我安装的就是这个版本 小提示&#xff1a;自定义安装可以只选择安装Cuda Runtime。Nvidia全家桶不必全部安装。把全家桶全部安装完直接系统…

机器人规划算法——movebase导航框架源码分析

这里对MoveBase类的类成员进行了声明&#xff0c;以下为比较重要的几个类成员函数。 构造函数 MoveBase::MoveBase | 初始化Action 控制主体 MoveBase::executeCb收到目标&#xff0c;触发全局规划线程&#xff0c;循环执行局部规划 全局规划线程 void MoveBase::planThread |…

【小黑送书—第五期】>>《MATLAB科学计算从入门到精通》

从代码到函数&#xff0c;从算法到实战&#xff0c;从问题到应用&#xff0c;由浅入深掌握科学计算方法&#xff0c;高效解决实际问题。 从代码到函数&#xff0c;掌握多种经典算法 跨越多个领域&#xff0c;精通各类科学计算 多种应用实例&#xff0c;高效解决实际问题 今天给…

【尚跑】2023宝鸡马拉松安全完赛,顺利PB达成

1、赛事背景 千年宝地&#xff0c;一马当先&#xff01;10月15日7时30分&#xff0c;吉利银河2023宝鸡马拉松在宝鸡市行政中心广场鸣枪开跑。 不可忽视的是&#xff0c;这次赛事的卓越之处不仅在于规模和参与人数&#xff0c;还在于其精心的策划和细致入微的组织。为了确保每位…

操作NAND flash W25N01G

文章目录 W25N01G1 描述2 特点3 封装3.3.2 连接线 4 引脚/CSDO/WP/Hold SPI指令标准SPI命令双SPI四元SPI命令写保护 5 地址PA与PC最后一个扇区 OTP寄存器1块保护清除块保护指令* WP-E 寄存器2寄存器3BUSYP-FAILE-FAILECC位 8 命令8.1 装置ID 指令解读写状态寄存器 注意内容上拉…

今天给大家带来Python炫酷爱心代码

前言&#xff1a; 这个是小编之前朋友一直要小编去做的&#xff0c;不过之前技术不够所以一直拖欠今天也完成之前的约定吧&#xff01; 至于他是谁&#xff0c;我就不多说了直接上代码 一.代码展示 import random from math import sin, cos, pi, log from tkinter import …

Navicat 技术指引 | 适用于 GaussDB 的用户权限设置

Navicat Premium&#xff08;16.2.8 Windows版或以上&#xff09; 已支持对 GaussDB 主备版的管理和开发功能。它不仅具备轻松、便捷的可视化数据查看和编辑功能&#xff0c;还提供强大的高阶功能&#xff08;如模型、结构同步、协同合作、数据迁移等&#xff09;&#xff0c;这…

SpringMVC系列-7 @CrossOrigin注解与跨域问题

背景 前段时间帮同事分析了一个跨域问题&#xff0c;正好系统分析和整理一下。 1.跨域 理解同源策略是理解跨域的前提。同源策略定义如下&#xff1a; 在同一来源的页面和脚本之间进行数据交互时&#xff0c;浏览器会默认允许操作&#xff0c;而不会造成跨站脚本攻击&#x…