2 使用React构造前端应用

news2024/11/14 21:15:46

文章目录

  • 简单了解React和Node
  • 搭建开发环境
  • React框架
  • JavaScript客户端
  • ChallengeComponent
    • 组件的主要结构
    • 渲染
    • 与应用程序集成
  • 第一次运行前端
  • 调试
  • 将CORS配置添加到Spring Boot应用
  • 使用应用程序
  • 部署React应用程序
  • 小结

前端代码可从这里下载: 前端示例

后端使用这里介绍的Spring Boot应用程序:一个测试驱动的Spring Boot应用程序开发

现实世界中,用户不会通过REST API使用应用程序,因此,这里为这个服务构造前端应用,便于用户与应用程序进行交互。

简单了解React和Node

React是一个构建用户界面的JavaScript库,由Facebook开发,很流行,已被广泛使用。React基于组件构建,编写一段代码即可在多处复用,这很有优势。可以创建像 Thumbnail、LikeButton 和 Video 这样的组件,然后将它们组合成整个应用程序。
React 组件是 JavaScript 函数,学习 React 就是学习编程。可以在React中使用 JSX,这是由 React 推广的 JavaScript 语法扩展,它允许将 JSX 标签与相关的渲染逻辑放在一起,使得创建、维护和删除 React 组件变得容易。
React 组件接收数据并返回应该出现在屏幕上的内容。可以通过响应交互(例如用户输入)向它们传递新数据。然后,React 将更新屏幕以匹配新数据。也可以不用 React 去构建整个页面,而只是将 React 添加到现有的 HTML 页面中,在任何地方呈现交互式的 React 组件。
React 允许将组件放在一起,而不关注路由和数据获取。要使用 React 构建整个应用程序,建议使用像 Next.js 或 Remix 这样的全栈 React 框架。
React 也是一种架构。实现它的框架可以在服务端甚至是构建阶段使用异步组件来获取数据,也可以从文件或数据库读取数据,并将其传递给交互式组件。
简单的说 Node.js 就是运行在服务端的 JavaScript。Node.js 是一个基于 Chrome JavaScript 运行时建立的一个平台。Node.js 是一个事件驱动 I/O 服务端 JavaScript 环境,基于 Google 的 V8 引擎,V8 引擎执行 Javascript 的速度非常快,性能非常好。
如果你是一个前端程序员,想创建自己的服务,那么 Node.js 是一个非常好的选择。如果你熟悉 Javascript,那么将会很容易的学会 Node.js。当然,如果你是后端程序员,想部署一些高性能的服务,那么学习 Node.js 也是一个非常好的选择。

搭建开发环境

首先,需要到nodejs.org站点上下载应用程序包来安装Node.js,可以下载免安装的zip版本,配置相应的环境变量即可。安装后可以在控制台输入下列命令,查看Node.js和npm的版本:

> node -v
v16.14.2
> npm -v
9.8.1

现在,最新的长期支持的Node版本是20.9.0。
有了Node,就可以使用npx来创建React项目了,命令如下:

> npx create-react-app multiplication-frontend

下载并安装依赖后,会看到如下输出:

> npx create-react-app multiplication-frontend

Creating a new React app in Z:\_Learn\multiplication-frontend.

Installing packages. This might take a couple of minutes.
Installing react, react-dom, and react-scripts with cra-template...


added 1463 packages in 42s

Initialized a git repository.

Installing template dependencies using npm...

added 69 packages, and changed 1 package in 5s
Removing template package using npm...


removed 1 package in 2m

Created git commit.

Success! Created multiplication-frontend at Z:\_Learn\multiplication-frontend
Inside that directory, you can run several commands:

  npm start
    Starts the development server.

  npm run build
    Bundles the app into static files for production.

  npm test
    Starts the test runner.

  npm run eject
    Removes this tool and copies build dependencies, configuration files
    and scripts into the app directory. If you do this, you can’t go back!

We suggest that you begin by typing:

  cd multiplication-frontend
  npm start

Happy hacking!

进入项目目录,执行npm start命令,Node服务器就会启动并打开一个浏览器窗口,访问localhost:3000地址,显示刚刚生成的应用程序。

> cd .\multiplication-frontend\
> npm start

默认页面如图所示:
默认页面

React框架

在IDEA中,加载项目,create-react-app工具已经创建了许多文件,如图所示:
React项目框架

  • package.json和package-lock.json是npm文件,包含关于项目的基本信息,列出相关依赖,依赖项存储在node_modules文件夹中。
  • public存储所有创建后不再变动的静态文件。唯一的例外是index.html,应对其处理以包含生成的JavaScript代码。
  • src存储所有的React源文件及其相关资源。这里可以找到入口点文件index.js和一个React组件App,该示例组件附带自己的样式表App.css和一个测试文件App.test.js。

这里,从index.html开始,删除注释后,内容如下:

<!DOCTYPE html>
<html lang="en">
  <head>
    <meta charset="utf-8" />
    <link rel="icon" href="%PUBLIC_URL%/favicon.ico" />
    <meta name="viewport" content="width=device-width, initial-scale=1" />
    <meta name="theme-color" content="#000000" />
    <meta
      name="description"
      content="Web site created using create-react-app"
    />
    <link rel="apple-touch-icon" href="%PUBLIC_URL%/logo192.png" />
    <link rel="manifest" href="%PUBLIC_URL%/manifest.json" />
    <title>React App</title>
  </head>
  <body>
    <noscript>You need to enable JavaScript to run this app.</noscript>
    <div id="root"></div>
  </body>
</html>

body很简单。index.js定义了渲染内容的入口,代码如下:

import React from 'react';
import ReactDOM from 'react-dom/client';
import './index.css';
import App from './App';
import reportWebVitals from './reportWebVitals';

const root = ReactDOM.createRoot(document.getElementById('root'));
root.render(
  <React.StrictMode>
    <App />
  </React.StrictMode>
);

reportWebVitals();

DOM(文档对象模型)是HTML元素的树结构表达,这段代码将元素React.StrictMode及其子元素App组件渲染到HTML中。具体地说,将渲染到ID为root的元素中,即插入index.html中的div标签。由于App是一个组件,可能包含其他组件,因此,最终会处理并渲染整个React应用程序。

JavaScript客户端

在创建第一个组件前,要确保可以访问前面创建的REST API接口,这需要使用JavaScript类。
JavaScript中的类与Java类类似,如下所示:

class ApiClient {
    static SERVER_URL = 'http://localhost:8080';
    static GET_CHALLENGE = '/challenges/random';
    static POST_RESULT = '/attempts';

    static challenge(): Promise<Response> {
        return fetch(ApiClient.SERVER_URL + ApiClient.GET_CHALLENGE);
    }

    static sendGuess(user: string,
                     a: number,
                     b: number,
                     guess: number): Promise<Response> {
        return fetch(ApiClient.SERVER_URL + ApiClient.POST_RESULT, {
            method: 'POST',
            headers: {
                'Content-Type': 'application/json'
            },
            body: JSON.stringify({
                userAlias: user,
                factorA: a,
                factorB: b,
                guess: guess
            })
        });
    }
}
export default ApiClient;

两个方法都返回Promise,JavaScript中的Promise与Java中的Future类相似:表示异步操作的结果。fetch函数用来与HTTP服务进行交互。
challenge()方法调用fetch函数的基本形式,默认对URL执行GET操作,返回Response对象。
sendGuess()方法接收请求所需的参数,与第二个参数一起使用,定义了HTTP方法(POST)的对象、请求体的内容类型(JSON)和请求体。
最后,为使类可以公开访问,添加了export default ApiClient,就可以将完整的类引入其他组件和类中了。

ChallengeComponent

下面,创建第一个React组件,来处理Challenge域,包括:

  • 将后端检索到的数据渲染到ChallengeComponent
  • 显示表单供用户发送猜测

下面是ChallengeComponent的代码:

import ApiClient from "../services/ApiClient";
import React from "react";

// 类从React.Component继承,这就是React创建组件的方式。
// 唯一要实现的方法是render(),该方法必须返回DOM元素才能在浏览器中显示。
class ChallengeComponent extends React.Component {
    // 构造函数,初始化属性及组件的state(如果需要的话),
    // 这里创建一个state来保持检索到的挑战,以及用户为解决尝试而输入的数据。
    constructor(props) {
        super(props);
        this.state = {
            a: '',
            b: '',
            user: '',
            message: '',
            guess: '',
        };
        // 两个绑定方法。如果想要在事件处理程序中使用,这是必要的,需要实现这些方法来处理用户输入的数据。
        this.handleSubmitResult = this.handleSubmitResult.bind(this);
        this.handleChange = this.handleChange.bind(this);
    }

    // 这是一个生命周期方法,用于首次渲染组件后立即执行逻辑。
    componentDidMount(): void {
        // 使用ApiClient实用程序类来调用服务,检索挑战。
        // 考虑到函数返回一个promise,使用then()来指定获取响应时的操作。
        ApiClient.challenge().then(res => {
            if (res.ok) {
                // 使用then()解析promise,将REST API响应中预期的factorA和factorB传递给setState()。
                res.json().then(
                    json => {
                        this.setState({
                            a: json.factorA,
                            b: json.factorB
                        });
                    }
                );
            } else {
                this.updateMessage("Can't reach the server");
            }
        });
    }

    handleChange(event) {
        const name = event.target.name;
        this.setState({
            [name]: event.target.value
        });
    }

    handleSubmitResult(event) {
        event.preventDefault();
        ApiClient.sendGuess(this.state.user,
            this.state.a,
            this.state.b,
            this.state.guess)
            .then(res => {
                if (res.ok) {
                    res.json().then(json => {
                        if (json.correct) {
                            this.updateMessage("Congratulations! Your guess is correct");
                        } else {
                            this.updateMessage("Oops! Your guess " + json.reaultAttempt + " is" +
                                " wrong, but keep playing!");
                        }
                    });
                } else {
                    this.updateMessage("Error: server error or not available");
                }
            });
    }

    updateMessage(m: string) {
        this.setState({
            message: m
        });
    }

    render() {
        return (
            <div>
                <div>
                    <h3>Your new challenge is</h3>
                    <h1>
                        {this.state.a} x {this.state.b}
                    </h1>
                </div>
                <form onSubmit={this.handleSubmitResult}>
                    <label>
                        Your alias:
                        <input type="text" maxLength="12" name="user"
                               value={this.state.user} onChange={this.handleChange}/>
                    </label>
                    <br/>
                    <label>
                        Your guess:
                        <input type="number" min="0" name="guess"
                            value={this.state.guess} onChange={this.handleChange}/>
                    </label>
                    <br/>
                    <input type="submit" value="Submit"/>
                </form>
                <h4>{this.state.message}</h4>
            </div>
        );
    }
}
export default ChallengeComponent;

组件的主要结构

import ApiClient from "../services/ApiClient";
import React from "react";

// 类从React.Component继承,这就是React创建组件的方式。
// 唯一要实现的方法是render(),该方法必须返回DOM元素才能在浏览器中显示。
class ChallengeComponent extends React.Component {
    // 构造函数,初始化属性及组件的state(如果需要的话),
    // 这里创建一个state来保持检索到的挑战,以及用户为解决尝试而输入的数据。
    constructor(props) {
        super(props);
        this.state = {
            a: '',
            b: '',
            user: '',
            message: '',
            guess: '',
        };
        // 两个绑定方法。如果想要在事件处理程序中使用,这是必要的,需要实现这些方法来处理用户输入的数据。
        this.handleSubmitResult = this.handleSubmitResult.bind(this);
        this.handleChange = this.handleChange.bind(this);
    }

    // 这是一个生命周期方法,用于首次渲染组件后立即执行逻辑。
    componentDidMount(): void {
        // ... Component initialization
    }

    render() {
        return (
        // ... HTML as JSX ...
            )
    }
}

在React中,setState函数重新加载部分DOM。这意味着浏览器将再次渲染HTML被更改的部分,因此收到服务器响应后,会在页面上看到乘法因子。

渲染

JSX可以混合使用HTML和JavaScript。

    render() {
        return (
            <div>
                <div>
                    <h3>Your new challenge is</h3>
                    <h1>
                        {this.state.a} x {this.state.b}
                    </h1>
                </div>
                <form onSubmit={this.handleSubmitResult}>
                    <label>
                        Your alias:
                        <input type="text" maxLength="12" name="user"
                               value={this.state.user} onChange={this.handleChange}/>
                    </label>
                    <br/>
                    <label>
                        Your guess:
                        <input type="number" min="0" name="guess"
                            value={this.state.guess} onChange={this.handleChange}/>
                    </label>
                    <br/>
                    <input type="submit" value="Submit"/>
                </form>
                <h4>{this.state.message}</h4>
            </div>
        );
    }

ChallengeComponent有一个根div元素,包含3个主要代码块。第一个代码块通过state中的两个参数来显示挑战。最后一个代码块,展示message状态属性。第二个代码块创建了一个表单,可以让用户输入自己的猜测。在表单中,涉及相关的处理,用于处理用户输入。

    handleChange(event) {
        const name = event.target.name;
        this.setState({
            [name]: event.target.value
        });
    }

    handleSubmitResult(event) {
        event.preventDefault();
        ApiClient.sendGuess(this.state.user,
            this.state.a,
            this.state.b,
            this.state.guess)
            .then(res => {
                if (res.ok) {
                    res.json().then(json => {
                        if (json.correct) {
                            this.updateMessage("Congratulations! Your guess is correct");
                        } else {
                            this.updateMessage("Oops! Your guess " + json.reaultAttempt + " is" +
                                " wrong, but keep playing!");
                        }
                    });
                } else {
                    this.updateMessage("Error: server error or not available");
                }
            });
    }

表单提交时,调用服务器的API来发送猜测。当获取响应时,检查是否正常,解析JSON,然后,更新状态中的message属性,最后,相应部分的HTML DOM对象会被再次渲染。

与应用程序集成

现在,以及完成了组件的代码,就可以在应用程序中使用了。修改App.js,在其中添加创建的组件。

import React from "react";
import './App.css';
import ChallengeComponent from './components/ChallengeComponent';

function App() {
  return (
    <div className="App">
      <header className="App-header">
        <ChallengeComponent/>
      </header>
    </div>
  );
}

export default App;

框架应用程序在index.js中使用此App组件,构建代码时,生成的脚本包含在index.html文件中。
还需要调整App.test.js中包含的测试代码或直接删除。这里不会探讨React测试的细节,现在可以将其删除。

第一次运行前端

确保运行了Spring Boot应用程序,启动控制台,进入前端应用程序的文件夹,执行npm start命令来启动React前端。
成功编译后,会打开默认浏览器并显示位于localhost:3000的页面,显示如下:
空白前端
这里出问题了,应该去后端获取参数的,但现在的参数区域空白,下面看看如何进行调试。

调试

大多数浏览器都为开发者提供了功能强大的工具,打开开发者模式,刷新浏览器,就可以查看前端是否与后端正确交互。
上面的网页刷新,在开发者模式下,单击“网络”选项卡,会看到对http://localhost:8080/challenges/random的HTTP请求失败,如图所示:
火狐开发者模式
控制台还显示一条描述性消息:已拦截跨源请求:同源策略禁止读取位于 http://localhost:8080/challenges/random 的远程资源。(原因:CORS 头缺少 'Access-Control-Allow-Origin')。状态码:200。
默认情况下,浏览器会阻止那些尝试访问前端所在域以外的域中的资源的请求,以避免浏览器中的恶意页面访问其他页面中的数据,这称为“同源策略”。本例中,虽然在本地主机中同时运行前端和后端,但是不同的端口,因此被认为是不同源的。
有多种方法可以解决该问题。这里,将启用跨域资源共享(CORS),这是一种可在服务器端启用的安全策略,允许前端使用来自不同源的REST API。

将CORS配置添加到Spring Boot应用

回到后端代码库,添加一个Spring Boot @Configuration类,配置CORS,代码如下:

package cn.zhangjuli.multiplication.configuration;

import org.springframework.context.annotation.Configuration;
import org.springframework.web.servlet.config.annotation.CorsRegistry;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;

/**
 * @author Juli Zhang, <a href="mailto:zhjl@lut.edu.cn">Contact me</a> <br>
 */
@Configuration
public class WebConfiguration implements WebMvcConfigurer {
    @Override
    public void addCorsMappings(CorsRegistry registry) {
        registry.addMapping("/**").allowedOrigins("http://localhost:3000");
    }
}

这里通过CorsRegistry 实例完成工作,添加一个映射,允许前端的源访问任何路径(用/**表示)。也可以省略allowedOrigins部分,这样,所有的源域都可以访问。

注意:当前端和后端部署到不同的主机时,应该提供有选择的CORS配置策略,避免为所有的源域添加完全访问权限。

使用应用程序

现在,前后端可以协同工作了,重新启动前后端应用程序,刷新浏览器,如图所示:
使用
这是一个测试,可以完成猜测游戏了。

部署React应用程序

目前为止,前端一直使用的是开发模式,这不是生产环境的工作方式。
要想部署React应用程序,首先需要构建它,使用npm run build命令来构建用于生产部署的React应用程序。执行如下:

> npm run build

> multiplication-frontend@0.1.0 build
> react-scripts build

Creating an optimized production build...
One of your dependencies, babel-preset-react-app, is importing the
"@babel/plugin-proposal-private-property-in-object" package without
declaring it in its dependencies. This is currently working because
"@babel/plugin-proposal-private-property-in-object" is already in your
node_modules folder for unrelated reasons, but it may break at any time.

babel-preset-react-app is part of the create-react-app project, which
is not maintianed anymore. It is thus unlikely that this bug will
ever be fixed. Add "@babel/plugin-proposal-private-property-in-object" to
your devDependencies to work around this error. This will make this message
go away.

Compiled successfully.

File sizes after gzip:

  47.14 kB  build\static\js\main.b3d22150.js
  1.79 kB   build\static\js\787.444a2e11.chunk.js
  515 B     build\static\css\main.f855e6bc.css

The project was built assuming it is hosted at /.
You can control this with the homepage field in your package.json.

The build folder is ready to be deployed.
You may serve it with a static server:

  serve -s build

Find out more about deployment here:

  https://cra.link/deployment

该命令在build文件夹下生成了所有脚本和文件,还可以在其中找到放在public文件夹中的文件的副本。这些日志还说明了如何使用npm安装静态Web服务器。
另外,Spring Boot应用程序已经嵌入了Web服务器Tomcat,也可以直接使用。最简单的方式是,将整个应用程序(前端和后端)打包在同一个可部署单元中:Spring Boot生成的胖JAR文件。需要做的就是,将前端build文件夹中的所有文件复制到Multiplication代码库的src/main/resources/static文件夹中。Spring Boot的默认服务器配置为静态Web文件添加了一些预定义的位置,static文件夹就是其中之一。如图所示:
将build结果放入静态资源中
可根据需要配置这些资源位置及其映射。其中一个需要微调的就是WebMvcConfigurer接口实现。这里不需要改动,因为前端和后端共享同一个源域http://localhost:8080,当然,也可以删除它。

小结

文章介绍了如何基于React创建一个前端Web应用程序的过程。首先,使用create-react-app工具创建React应用程序框架,然后创建一个ApiClient类来实现与后端API服务的访问,并创建一个使用该服务并显示结果的React组件。为了使前后端能够协同,在后端增加了CORS配置。最后,介绍了如何构建用于生产环境的React应用程序,以及如何在Spring Boot的嵌入式Tomcat中集成。

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

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

unity shaderGraph实例-可交互瀑布

不要问我水在哪里&#xff0c;你自己相像这是一个瀑布&#xff0c;瀑布的效果我还不会做 效果展示 整体结构 这里片元着色器最后输出的baseColor应该是黑色&#xff0c;白色为错误。 各区域内容 区域1 计算球到瀑布的距离&#xff0c;然后减去一个值&#xff0c;实现黑色区域…

【小黑送书—第九期】>>重磅!这本30w人都在看的Python数据分析畅销书:更新了!

想学习python进行数据分析&#xff0c;这本《利用python进行数据分析》是绕不开的一本书。目前该书根据Python3.10已经更新到第三版。 Python 语言极具吸引力。自从 1991 年诞生以来&#xff0c;Python 如今已经成为最受欢迎的解释型编程语言。 pandas 诞生于2008年。它是由韦…

【亚太杯前两问论文】2023年第十三届APMCM亚太地区大学生数学建模竞赛——(文末领取方式)

2023年第十三届APMCM亚太地区大学生数学建模竞赛——论文无偿分享&#xff01;&#xff01;&#xff01; C题前两问论文代码已出&#xff0c;其他赛题及后续论文代码会持续更新。 祝各位小伙伴都能在比赛中发挥出色&#xff0c;取得心仪的成绩呦&#xff01;一起加油&#xff…

使用Arrays.Sort并定制Comparator排序解决合并区间

合并区间-力扣算法题56题 以数组 intervals 表示若干个区间的集合&#xff0c;其中单个区间为 intervals[i] [starti, endi] 。请你合并所有重叠的区间&#xff0c;并返回 一个不重叠的区间数组&#xff0c;该数组需恰好覆盖输入中的所有区间 。 示例 1&#xff1a; 输入&am…

姿态传感器——MPU6050

1、MPU6050介绍 MPU6050是由三个陀螺仪和三个加速度传感器组成的6轴运动处理组件&#xff0c;是一款六轴&#xff08;三轴加速度三轴角速度&#xff08;陀螺仪&#xff09;&#xff09;传感器。 内部主要结构 陀螺仪、加速度计、数字运动处理器DMP&#xff08;Digital Moti…

uniapp 轮播图(含组件封装,自动注册全局组件)

效果预览 组件封装 src\components\SUI_Swiper.vue 可参考官网配置更多属性 swipernavigator <script setup lang"ts"> import { ref } from vue defineProps({config: Object, })const activeIndex ref(0) const change: UniHelper.SwiperOnChange (e) &…

msvcp120.dll丢失是什么意思,哪个修复方法最简单

在计算机使用过程中&#xff0c;我们经常会遇到一些错误提示&#xff0c;其中之一就是“找不到msvcp120.dll”。这个错误通常发生在运行某些程序或游戏时&#xff0c;它会导致程序无法正常启动或运行。那么&#xff0c;这个错误提示到底是什么意思呢&#xff1f;为了解决这个问…

当老师应该选文科还是理科

教育不断发展和改革&#xff0c;教师职业的选择也越来越受到关注。许多人在选择专业时都会考虑成为一名教师&#xff0c;但对于选择文科还是理科却感到困惑。本文将探讨当老师应该选文科还是理科。 文科注重的是人文素养和社会科学方面的知识&#xff0c;而理科则注重自然科学和…

springcloud超市管理系统源码

技术说明&#xff1a; jdk1.8&#xff0c;mysql5.7&#xff0c;idea&#xff0c;vscode springcloud springboot mybatis vue elementui mysql 功能介绍&#xff1a; 后台管理&#xff1a; 统计分析&#xff1a;查看用户&#xff0c;商品&#xff0c;销售数量&#xff1b;…

王道p150 20.将给定的表达式树转化为等价的中缀表达式(通过括号反应操作符的计算次序)

本题代码如下 void btreetoexp(tree t, char deep) {if (t NULL)return;else if (t->lchild NULL && t->rchild NULL)printf("%c", t->data);//输出操作数&#xff0c;不加括号else {if (deep > 1)printf("(");btreetoexp(t->l…

职场Excel:求和家族,不简单

说到excel函数&#xff0c;很多人第一时间想到的就是求和函数sum。作为excel入门级函数&#xff0c;sum的确是小白级的&#xff0c;以至于很多人对求和函数有点“误解”&#xff0c;觉得求和函数太简单了。 但是&#xff0c;你可能不知道&#xff0c;sum只是excel求和家族里的一…

阿里入局鸿蒙!鸿蒙原生应用再添两员新丁

今日HarmonyOS微博称&#xff0c;阿里钉钉、蚂蚁集团旗下的移动开发平台mPaaS与华为达成合作&#xff0c;宣布启动鸿蒙原生应用的开发&#xff01;相关应用将以原生方式适配#HarmonyOS NEXT#系统。 #HarmonyOS#市场或迎来爆发式增长&#xff01; 阿里钉钉 阿里钉钉与华为达成合…

231123 刷题日报-动态规划

今天主要看了DP&#xff0c;前几天频繁遇到DP打击有点大。。 1. 0-1背包问题 要点&#xff1a; a. 三部曲&#xff1a; 1. 状态和选择 状态&#xff1a;物品序号、背包容量 选择&#xff1a;放、不放 2. dp数组定义、base case dp[i][w] 对于前i个物品&#xff0c;当前背包…

简单的用Python采集股票数据,保存表格后分析历史数据

前言 字节跳动如果上市&#xff0c;那么钟老板将成为我国第一个世界首富 趁着现在还没上市&#xff0c;咱们提前学习一下用Python分析股票历史数据&#xff0c;抱住粗大腿坐等起飞~ 好了话不多说&#xff0c;我们直接开始正文 准备工作 环境使用 Python 3.10 解释器Pychar…

检验LIS系统:医院信息管理的重要组成部分

检验LIS系统源码&#xff0c;云LIS系统源码 云LIS系统是医院信息管理的重要组成部分之一&#xff0c;集申请、采样、核收、计费、检验、审核、发布、质控、查询、耗材控制等检验科工作为一体的网络管理系统。LIS系统不仅是自动接收检验数据&#xff0c;打印检验报告&#xff0c…

WordPress网站如何修复数千个帖子的SEO错误

在本教程中&#xff0c;我们将向您展示如何解决您经常犯的SEO错误。 最好的是您不必花费太多时间&#xff0c;因为您不需要打开并编辑每个帖子。 相反&#xff0c;我们将向您展示如何使用 WordPress 内的电子表格来修复 WordPress 帖子的 SEO。 在这里&#xff0c;我们为您提…

机器学习---最大似然估计和贝叶斯参数估计

1. 估计 贝叶斯框架下的数据收集&#xff0c;在以下条件下我们可以设计一个可选择的分类器 : P(wi) (先验)&#xff1b;P(x | wi) (类条件密度) 但是。我们很少能够完整的得到这些信息! 从一个传统的样本中设计一个分类器&#xff1a; ①先验估计不成问题 ②对类条件密度…

分享5款工作和学习中,经常用到的软件

​ 如今&#xff0c;工作和学习都离不开电脑&#xff0c;所以电脑里的软件自然也是必不可少的&#xff0c;但是电脑软件那么多&#xff0c;不可能每个都装上吧&#xff0c;所以我们要装好用的、实用的&#xff0c;下面给大家分享5款好用到爆的软件&#xff0c;很多懂电脑的人都…

基于JavaWeb+SSM+Vue校园水电费管理小程序系统的设计和实现

基于JavaWebSSMVue校园水电费管理小程序系统的设计和实现 源码获取入口Lun文目录前言主要技术系统设计功能截图订阅经典源码专栏Java项目精品实战案例《500套》 源码获取 源码获取入口 Lun文目录 摘 要 III Abstract 1 1 系统概述 2 1.1 概述 2 1.2课题意义 3 1.3 主要内容 3…

传统制造业如何有效实现数字化?企业数字化转型可以借助哪些工具?

2020年&#xff0c;制造业数字化转型行业的价值为2630亿美元。然而&#xff0c;到2026年&#xff0c;这一数字预计将达到惊人的7670亿美元。随着新技术的出现&#xff0c;工业4.0时代已经开始。这是由软件开发和自动化带来的对数字化的日益依赖所决定的&#xff0c;这使得制造过…