React 低代码项目:网络请求与问卷基础实现

🍞吐司问卷:网络请求与问卷基础实现

Date: February 10, 2025


Log

技术要点:

  • HTTP协议
  • XMLHttpRequest、fetch、axios
  • mock.js、postman
  • Webpack devServer 代理、craco.js 扩展 webpack
  • Restful API

开发要点:

  • 搭建 mock 服务

注:前端项目并不推荐直接使用 mock.js。因为它不支持 fetch,且上线时需要剔除模拟接口。

因此,建议构建一个简易服务端,通过 Koa 搭建一个接口路由用于测试接口。

  • Ajax 封装、useRequest 使用
  • 分页、LoadMore



Mock 数据

前端 Mock 模拟 Ajax

要点:

  • 前端引入 mock.js 测试 api

安装:

npm i mockjs
npm i --save-dev @types/mockjs  // 使用ts需要额外安装

注意点:

  • mock.js 只能劫持 XMLHttpRequest,不能劫持 fetch
  • 要在生产环境(上线时)注释掉,否则线上请求也被劫持

Case:

**效果:**会执行两次 mock(原因见下)

image.png

定义的mock

import Mock from 'mockjs'

Mock.mock('/api/test', 'get', () => {
  return {
    error: 0,
    data: {
      name: 'test',
      age: 18,
    },
  }
})

页面中引用

import React, { FC, useEffect } from 'react'
import styles from './Home.module.scss'
import { useNavigate } from 'react-router-dom'
import { Typography, Button } from 'antd'
import { MANAGE_INDEX_PATHNAME } from '../router'
import axios from 'axios'
import '../_mock/index'

const { Title, Paragraph } = Typography

const Home: FC = () => {
  const nav = useNavigate()
  useEffect(() => {
    axios.get('/api/test').then(res => console.log(res))
  }, [])
  return (
    <div className={styles.container}>
      <div className={styles.info}>
        <Title>问卷调查 | 在线投票</Title>
        <Paragraph>
          已累计创建问卷 100 份,发布问卷 90 份,收到答卷 980 份
        </Paragraph>
        <div>
          <Button type="primary" onClick={() => nav(MANAGE_INDEX_PATHNAME)}>
            创建问卷
          </Button>
        </div>
      </div>
    </div>
  )
}

export default Home

思考:

为什么 useEffect 会执行两次?

React 18 中,useEffect 默认会在开发模式下执行两次,这是为了帮助开发者发现副作用的潜在问题。

参考:

https://github.com/nuysoft/Mock/wiki/Getting-Started



服务端 nodejs 实现 mock.js

服务端 mock 实现

目标:

  • 服务端实现mock

要点:

  • mock.js 用于劫持网络请求,并实现丰富的 Random 能力
  • mock.js 部署于 nodejs 服务端,并实现 Random 功能

安装:

npm init -y
npm i mockjs
npm i koa koa-router
npm i nodemon  # 用于监听node修改, 不用重启项目

功能实现:

思路:服务端采用 Koa 构建路由处理需要 Mock 的 api

mock文件夹用于存放 Mock 的api,其中 index 做所有 Mock api 的整合。

目录:

.
├── index.js
├── mock
│   ├── index.js
│   ├── question.js
│   └── test.js
├── package-lock.json
├── package.json
└── projectTree.md

2 directories, 7 files

index.js

注意:这里设计 getRes() 可以刻意延迟 1s,模拟 loading 效果

const Koa = require('koa')
const Router = require('koa-router')
const mockList = require('./mock/index')

const app = new Koa()
const router = new Router()

// 模拟网络延迟函数
async function getRes(fn) {
  return new Promise(resolve => {
    setTimeout(() => {
      const res = fn()
      resolve(res)
    }, 1000)
  })
}

mockList.forEach(item => {
  const {url, method, response} = item
  router[method](url, async (ctx, next) => {
    const res = await getRes(response)
    ctx.body = res
  }
  )
})
app.use(router.routes())
app.listen(3002)

mock/index.js

const test = require('./test')
const question = require('./question')

const mockList = [
  ...test,
  ...question
]

module.exports = mockList

question.js

const Mock = require('mockjs')

const Random = Mock.Random

module.exports = [
	{
		url: '/api/question/:id',
		method: 'get',
		response() {
			return {
				error: 0,
				data: {
					id: Random.id(),
					title: Random.ctitle(),
					content: Random.cparagraph()
				}
			}
		}
	}, 
  {
    url: '/api/question',
    method: 'post',
    response() {
      return {
        error: 0,
        data: {
          id: Random.id()
        }
      }
    }
  }
]


**测试:**采用 postman 进行测试 post 请求

image.png


跨域问题处理

**目标:**处理跨域问题

刚刚我们搞定了服务端的 Mock,并处理了前端页面。现在遇到跨域问题:

问题:

image.png

问题原因:

http://localhost:3001/home 访问 http://localhost:3002/api/test 会产生 CORS 即跨域问题

Home.tsx

  const nav = useNavigate()
  useEffect(() => {
    try {
      const fetchData = async () => {
        try {
          const response = await axios.get('http://localhost:3001/api/test')
          console.log(response.data) // 输出返回的响应数据
        } catch (error) {
          console.error('请求失败', error)
        }
      }
      fetchData()
    } catch (error) {
      console.error('请求失败', error)
    }
  }, [])

解决方案:

采用 Craco 来处理 React 中的跨域问题,本质上讲是通过拓展 React 的 CRA 工具配置来处理跨域

具体步骤:

  • 前端配置Craco: 配置见参考文档
  • 通过 Craco 构建 api 代理

image.png

**结果:**成功处理

image.png

参考文档:

  • https://github.com/dilanx/craco



API 设计

Restful API

概念:

RESTful API 是一种基于 REST(Representational State Transfer)架构风格的 Web 服务设计方法。

特点:

资源导向

  • 将系统中的所有内容视为资源,每个资源有唯一的 URI(统一资源标识符)。例如,/users 表示用户资源。

无状态性(Statelessness)

  • 每个请求都是独立的,不依赖于之前的请求。服务器不保留客户端状态信息。

表现层状态转移(Representation of Resources)

  • 通过 JSON、XML 等格式在客户端和服务器之间传递资源的表现形式,而不是资源本身。

统一接口

  • 定义一致的方式进行操作,使得不同的客户端可以以统一的接口与服务器交互。

自描述消息

  • 请求和响应中包含所有必要的信息,例如 HTTP 状态码、头信息等,以帮助客户端理解操作结果。

可缓存性

  • 设计 API 使得响应可以被缓存,从而提高性能。

使用标准 HTTP 方法

  • 使用 HTTP 动词来操作资源:
    • GET:获取资源。
    • POST:创建资源。
    • PUT:更新资源。
    • DELETE:删除资源。

总结:

RESTful API 简洁灵活,适用于构建现代Web服务,因其遵循标准化的设计原则,使得开发和集成变得简单直观。



用户和问卷API设计

以下是设计的 API 表格,涵盖了用户功能和问卷功能:

功能方法路径请求体响应
获取用户信息GET/api/user/info{ errno: 0, data: {...} }{ errno: 10001, msg: 'xxx' }
注册POST/api/user/register{ username, password, nickname }{ errno: 0 }
登录POST/api/user/login{ username, password }{ errno: 0, data: { token } } — JWT 使用 token
创建问卷POST/api/question{ errno: 0, data: { id } }
获取单个问卷GET/api/question/:id{ errno: 0, data: { id, title ... } }
获取问卷列表GET/api/question{ errno: 0, data: { list: [ ... ], total } }
更新问卷信息PATCH/api/question/:id{ title, isStar ... }{ errno: 0 }
批量彻底删除问卷DELETE/api/question{ ids: [ ... ] }{ errno: 0 }
复制问卷POST/api/question/duplicate/:id{ errno: 0, data: { id } }

说明:

  • GET 请求 通常用于获取资源,不需要请求体。
  • POST 请求 用于创建资源或进行某些操作,可能需要请求体包含必要的数据。
  • PATCH 请求 用于部分更新资源,需要请求体提供更新的字段和值。
  • DELETE 请求 用于删除资源,这里是“假删除”,通过更新 isDeleted 属性实现。



问卷功能实现

目标:

  • 配置 axios 基础功能
  • 开发问卷功能,期间使用 useRequest
  • 分页和 LoadMore


接口案例测试

**目标:**构建接口文件并测试

要点:

  • 设计 axios instance 实例
  • 设计 getQuestionList 接口
  • 测试 getQuestionList 接口

文件树:

├── src
│   ├── services
│   │   ├── ajax.ts
│   │   └── question.ts

ajax.ts

import axios from 'axios'
import { message } from 'antd'

const instance = axios.create({
  timeout: 10000,
})

instance.interceptors.response.use(res => {
  const resData = (res.data || {}) as ResType
  console.log('resData', resData)
  const { errno, data, msg } = resData
  if (errno !== 0) {
    if (msg) {
      message.error(msg)
    }
    throw new Error(msg || '未知错误')
  }
  return data as any
})

export default instance

export type ResType = {
  errno: number
  data?: ResDataType
  msg?: string
}

// key表示字段名,any表示字段值的类型
export type ResDataType = {
  [key: string]: any
}

question.tsx

import axios, { ResDataType } from './ajax'

export const getQuestionList = async (id: string): Promise<ResDataType> => {
  const url = `/api/question/${id}`
  const data = (await axios.get(url)) as ResDataType
  return data
}

接口测试:

import React, { FC, useEffect } from 'react'
import { useParams } from 'react-router-dom'
import { getQuestionList } from '../../../services/question'

const Edit: FC = () => {
  const { id = '' } = useParams()
  useEffect(() => {
    async function fetchData() {
      const res = await getQuestionList(id)
      console.log('res', res)
    }
    fetchData()
  }, [])
  return (
    <div>
      <h1>Edit {id}</h1>
    </div>
  )
}

export default Edit

image.png



设置 loading 状态优化体验

前言:之前我们在设计接口的时候,故意设计延迟函数用于模拟

// 模拟网络延迟函数
async function getRes(fn) {
  return new Promise(resolve => {
    setTimeout(() => {
      const res = fn()
      resolve(res)
    }, 1000)
  })
}

**问题:**现在我们设计完成新增问卷函数 createQuestionService() 。实际测试时,点击创建页面到新页面时,会发生1s的延迟。在这期间,我们仍然可以频繁点击创建问卷,如下所示:

2025-02-08 16.43.17.gif

**解决方案:**设置 disable 属性,当点击时禁用问卷创建即可

2025-02-08 16.42.31.gif

Case:

import { createQuestionService } from '../services/question'
const ManageLayout: FC = () => {
  const nav = useNavigate()
  const { pathname } = useLocation()
  const [loading, setLoading] = useState(false)
  async function handleCreateClick() {
    setLoading(true)
    const data = await createQuestionService()
    const { id } = data
    if (id) {
      nav(`/question/edit/${id}`)
      message.success('创建成功')
    }
    setLoading(false)
  }
  return (
    <>
      <div className={styles.container}>
        <div className={styles.left}>
          <Flex gap="small" wrap>
            <Button
              type="primary"
              size="large"
              icon={<PlusOutlined />}
              disabled={loading}
              onClick={handleCreateClick}
            >
              新建问卷
            </Button>
          </Flex>
        </div>
    </>
  )
}

export default ManageLayout



自定义Hook抽离公共逻辑

**思路:**抽离原有的获取编辑页面的数据为 hook,方便编辑页面进行复用。

不用 Hook 之前:/edit/index

import React, { FC, useState, useEffect } from 'react'
import { useParams } from 'react-router-dom'
import { getQuestionListService } from '../../../services/question'

const Edit: FC = () => {
  const { id = '' } = useParams()
  const [loading, setLoading] = useState(true)
  const [questionData, setQuestionData] = useState({})
  useEffect(() => {
    async function fetchData() {
      const res = await getQuestionListService(id)
      setQuestionData(res)
      setLoading(false)
    }
    fetchData()
  }, [])
  return (
    <div>
      <h1>Edit {id}</h1>
      {loading ? (
        <div>Loading...</div>
      ) : (
        <div>
          <p>{JSON.stringify(questionData)}</p>
        </div>
      )}
    </div>
  )
}

export default Edit

Hook设计:

hooks/useLoadQuestionData

import { useEffect, useState } from 'react'
import { useParams } from 'react-router-dom'
import { getQuestionListService } from '../services/question'

function useLoadQuestionData() {
  const { id = '' } = useParams()
  const [loading, setLoading] = useState(true)
  const [questionData, setQuestionData] = useState({})
  useEffect(() => {
    async function fetchData() {
      const res = await getQuestionListService(id)
      setQuestionData(res)
      setLoading(false)
    }
    fetchData()
  }, [])
  return { loading, questionData }
}

export default useLoadQuestionData

优化之后:/edit/index

import React, { FC } from 'react'
import { useParams } from 'react-router-dom'
import useLoadQuestionData from '../../../hooks/useLoadQuestionData'

const Edit: FC = () => {
  const { id = '' } = useParams()
  const { loading, questionData } = useLoadQuestionData()

  return (
    <div>
      <h1>Edit {id}</h1>
      {loading ? (
        <div>Loading...</div>
      ) : (
        <div>
          <p>{JSON.stringify(questionData)}</p>
        </div>
      )}
    </div>
  )
}

export default Edit



useRequest重构Ajax请求

**思路:**采用 ahooks 中的 useRequest 钩子重构之前的 Ajax 请求

useRequest:

默认请求:默认情况下,useRequest 第一个参数是一个异步函数,在组件初始化时,会自动执行该异步函数。同时自动管理该异步函数的 loading , data , error 等状态。

const { data, error, loading } = useRequest(service);

**Case:**重构 useLoadQuestionData

原本:

import { useEffect, useState } from 'react'
import { useParams } from 'react-router-dom'
import { getQuestionListService } from '../services/question'

function useLoadQuestionData() {
  const { id = '' } = useParams()
  const [loading, setLoading] = useState(true)
  const [questionData, setQuestionData] = useState({})
  useEffect(() => {
    async function fetchData() {
      const res = await getQuestionListService(id)
      setQuestionData(res)
      setLoading(false)
    }
    fetchData()
  }, [])
  return { loading, questionData }
}

export default useLoadQuestionData

重构之后:

import { useParams } from 'react-router-dom'
import { getQuestionListService } from '../services/question'
import { useRequest } from 'ahooks'

function useLoadQuestionData() {
  const { id = '' } = useParams()
  async function load() {
    const data = await getQuestionListService(id)
    return data
  }
  const { data, loading } = useRequest(load)
  return { data, loading }
}

export default useLoadQuestionData

参考:

https://ahooks.js.org/zh-CN/hooks/use-request/index#index-default



分页功能实现

要点:

  • 从 URL 参数中获取 page 和 pageSize, 并同步到 Pagination 组件中
  • 当 page 或 pageSize 变化时, 更新 URL 参数
  • AntD 中 Pagination 的 current、pageSize、total、onChange 等属性和方法

ListPage.tsx

import React, { FC } from 'react'
import { Pagination, PaginationProps } from 'antd'
import { useSearchParams, useNavigate, useLocation } from 'react-router-dom'
import {
  LIST_PAGE_SIZE,
  LIST_PAGE_PARAM_KEY,
  LIST_PAGE_SIZE_PARAM_KEY,
} from '../constant'

type ListPageProps = {
  total: number
}

const ListPage: FC<ListPageProps> = (props: ListPageProps) => {
  const { total } = props
  const [current, setCurrent] = React.useState(1)
  const [pageSize, setPageSize] = React.useState(LIST_PAGE_SIZE)
  // 从 URL 参数中获取 page 和 pageSize, 并同步到 Pagination 组件中
  const [searchParams] = useSearchParams()
  const nav = useNavigate()
  const { pathname } = useLocation()

  const handleChange: PaginationProps['onChange'] = pageNumber => {
    searchParams.set(LIST_PAGE_PARAM_KEY, pageNumber.toString())
    searchParams.set(LIST_PAGE_SIZE_PARAM_KEY, pageSize.toString())
    nav({
      pathname,
      search: searchParams.toString(),
    })
  }
  React.useEffect(() => {
    const page = parseInt(searchParams.get(LIST_PAGE_PARAM_KEY) || '') || 1
    const pageSize =
      parseInt(searchParams.get(LIST_PAGE_SIZE_PARAM_KEY) || '') ||
      LIST_PAGE_SIZE
    setCurrent(page)
    setPageSize(pageSize)
  }, [searchParams])
  return (
    <Pagination
      current={current}
      pageSize={pageSize}
      total={total}
      onChange={handleChange}
    />
  )
}

export default ListPage

问卷中进行使用:

Star.tsx

...
const { Title } = Typography

const Star: FC = () => {
  useTitle('星标问卷')
  const { data = {}, loading } = useLoadQuestionListData({ isStar: true })
  const { list = [], total = 0 } = data

  return (
    <>
	    ...
      {!loading && list.length > 0 && (
        <div className={styles.footer}>
          <ListPage total={total} />
        </div>
      )}
    </>
  )
}

export default Star


LoadMore 功能实现

要点:

  • 防抖功能实现

思路:

当页面的 ele 的 bottom 距离顶部一段距离时,自动加载页面

image.png



问卷标星、复制、删除功能

**目标:**实现问卷标星功能

**效果:**点击星标更新

2025-02-10 15.27.50.gif

思路:

  • 标星接口更新实现:采用 useRequest 实现
  • 页面标星状态更新:采用 useRequest 的回调函数实现

Code:

const [isStarState, setIsStarState] = useState(isStar)

// 标星接口更新实现
const { loading: changeStarLoading, run: changeStar } = useRequest(
  async () => {
    await updateQuestionService(_id, { isStar: !isStarState })
  },
  {
	  // 页面标星状态更新
    manual: true,
    onSuccess: () => {
      setIsStarState(!isStarState)
      message.success('已更新')
    },
  }
)

**目标:**实现问卷复制功能

思路:

  • 实现复制功能的接口请求
  • 实现复制功能的回调实现,实现导航到编辑页面

细节:

  • 防止重复点击:loading: duplicateLoading 绑定到 Button 上,当我们点击复制后,在接口数据返回前,按钮无法再次点击。

Code:

const { loading: duplicateLoading, run: duplicate } = useRequest(
  async () => {
    const data = await duplicateQuestionService(_id)
    return data
  },
  {
    manual: true,
    onSuccess: (res: any) => {
      message.success('复制成功')
      nav(`/question/edit/${res.id}`)
    },
  }
)

----

<Popconfirm
  title="确认复制吗?"
  okText="确认"
  cancelText="取消"
  onConfirm={duplicate}
>
  <Button
    type="text"
    size="small"
    icon={<CopyOutlined />}
    disabled={duplicateLoading}
  >
    复制
  </Button>
</Popconfirm>


**目标:**实现问卷删除功能

**需求:**实现删除功能,问卷点击删除是假删除,删除后,问卷会进入回收站

思路:

  • 实现删除功能的接口请求与回调
  • 实现当删除后,页面会不再渲染此卡片
const [isDeleted, setIsDeleted] = useState(false)
const { loading: deleteLoading, run: deleteQuestion } = useRequest(
  async () => await updateQuestionService(_id, { isDeleted: true }),
  {
    manual: true,
    onSuccess: () => {
      message.success('删除成功')
    },
  }
)
function del() {
  confirm({
    title: '删除问卷',
    icon: <ExclamationCircleOutlined />,
    onOk() {
      deleteQuestion()
      setIsDeleted(true)
    },
  })
}
// 实现当删除后,页面会不再渲染此卡片
if (isDeleted) return null // 已经删除的问卷,不要再渲染卡片了

return (
  <div className={styles.container}>
    <div className={styles.title}>
      <div className={styles.left}>
	      ...

---

<Button
  type="text"
  size="small"
  icon={<DeleteOutlined />}
  onClick={del}
  disabled={deleteLoading}
>
  删除
</Button>


问卷恢复与删除

要点:

  • for await (const id of selectionIds) 可以遍历请求
  • useRequeset 中的debounceWait 可以实现恢复防抖

2025-02-17 16.01.24.gif

  • useRequeset 中的refresh() 可以实现:使用上一次的参数,重新发起请求。

理解:refresh() 触发数据的重新加载,它确保在执行恢复和删除操作后,页面上的数据能够及时更新,避免了显示过时的信息。

Code:

const {
  data = {},
  loading,
  refresh,
} = useLoadQuestionListData({ isDeleted: true })

...

// 恢复
const { run: recover } = useRequest(
  async () => {
    for await (const id of selectionIds) {
      await updateQuestionService(id, { isDeleted: false })
    }
  },
  {
    manual: true,
    debounceWait: 500,
    onSuccess: () => {
      message.success('恢复成功')
      refresh()
      setSelectionIds([])
    },
  }
)

// 删除
const { run: deleteQuestion } = useRequest(
  async () => await deleteQuestionService(selectionIds),
  {
    manual: true,
    onSuccess: () => {
      message.success('删除成功')
      refresh()
      setSelectionIds([])
    },
  }
)

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

大流量汽(柴)油机泵,抗洪抢险的可靠选择|深圳鼎跃

近年来&#xff0c;全球范围内极端天气频发&#xff0c;洪涝灾害成为危及人民生命财产安全的重要因素。在抗洪抢险行动中&#xff0c;如何迅速、高效地排除积水&#xff0c;保障救援通道和安全区域成为关键。汽柴油机泵凭借其动力强、移动灵活、环境适应性强等特点&#xff0c;…

游戏开发微信小程序--工具箱之父

小程序工具箱之父已更新 Page({data: {score: 0,lives: 3,gameOver: false,playerVisible: true,level: 1,petType: cat,speedBuff: 1,coins: 0,friends: [],achievements: [],currentPetFrame: 0, // 当前宠物动画帧scoreMultiplier: 1, // 得分倍率gameSpeed: 1, // …

一.数据治理理论架构

1、数据治理核心思想&#xff1a; 数据治理理论架构图描绘了一个由顶层设计、管控机制、核心领域和管理系统四个主要部分组成的数据治理框架。它旨在通过系统化的方法&#xff0c;解决数据治理机制缺失引发的业务和技术问题&#xff0c;并最终提升企业的数据管理水平。 数据治…

一键安装教程

有需要的可以私信 亮点&#xff1a; 不再需要安装完去配置环境变量&#xff0c;下载完程序&#xff0c;解压后&#xff0c;右键进行管理员安装&#xff0c;安装完毕自动配置环境变量&#xff0c;即可使用 Maven 安装 右键 以管理员身份运行点击 下一步安装完成后会同步配置环境…

crud项目分析(2)

JWT令牌验证是否登录成功 简单的验证账号密码是否正确(存在) 全局异常处理器 过滤器 因为login下只有这一个网页 唯一一种操作 package com.itheima.filter;import ch.qos.logback.core.util.StringUtil; import com.alibaba.fastjson.JSONObject; import com.itheima.pojo.R…

深入解析iOS视频录制(二):自定义UI的实现

深入解析 iOS 视频录制&#xff08;一&#xff09;&#xff1a;录制管理核心MWRecordingController 类的设计与实现 深入解析iOS视频录制&#xff08;二&#xff09;&#xff1a;自定义UI的实现​​​​​​​ 深入解析 iOS 视频录制&#xff08;三&#xff09;&#xff1a;完…

【Linux系统】生产者消费者模型:基于环形队列(信号量机制)

理论层面 1、环形队列的特性认识 环形队列采用数组模拟&#xff0c;用模运算来模拟环状特性 环形结构起始状态和结束状态都是⼀样的&#xff0c;不好判断为空或者为满&#xff0c;所以可以通过加计数器或者标记位来判断满或者空。另外也可以预留⼀个空的位置&#xff0c;作为…

【笔记】LLM|Ubuntu22服务器极简本地部署DeepSeek+API使用方式

2025/02/18说明&#xff1a;2月18日~2月20日是2024年度博客之星投票时间&#xff0c;走过路过可以帮忙点点投票吗&#xff1f;我想要前一百的实体证书&#xff0c;经过我严密的计算只要再拿到60票就稳了。一人可能会有多票&#xff0c;Thanks♪(&#xff65;ω&#xff65;)&am…

leetcode-414.第三大的数

leetcode-414.第三大的数 code review! 文章目录 leetcode-414.第三大的数一.题目描述二.代码提交 一.题目描述 二.代码提交 class Solution { public:int thirdMax(vector<int>& nums) {set<int> set_v(nums.begin(), nums.end());auto it set_v.rbegin()…

【设计模式】 代理模式(静态代理、动态代理{JDK动态代理、JDK动态代理与CGLIB动态代理的区别})

代理模式 代理模式是一种结构型设计模式&#xff0c;它提供了一种替代访问的方法&#xff0c;即通过代理对象来间接访问目标对象。代理模式可以在不改变原始类代码的情况下&#xff0c;增加额外的功能&#xff0c;如权限控制、日志记录等。 静态代理 静态代理是指创建的或特…

深度学习之图像回归(二)

前言 这篇文章主要是在图像回归&#xff08;一&#xff09;的基础上对该项目进行的优化。&#xff08;一&#xff09;主要是帮助迅速入门 理清一个深度学习项目的逻辑 这篇文章则主要注重在此基础上对于数据预处理和模型训练进行优化前者会通过涉及PCA主成分分析 特征选择 后…

利用分治策略优化快速排序

1. 基本思想 分治快速排序&#xff08;Quick Sort&#xff09;是一种基于分治法的排序算法&#xff0c;采用递归的方式将一个数组分割成小的子数组&#xff0c;并通过交换元素来使得每个子数组元素按照特定顺序排列&#xff0c;最终将整个数组排序。 快速排序的基本步骤&#…

照片模糊怎么变清晰?图生生AI修图-一键清晰放大

当打开手机相册时&#xff0c;那些泛着噪点的合影、细节模糊的风景照、像素化的证件图片&#xff0c;让珍贵时刻蒙上遗憾的面纱。而专业级图像修复工具的门槛&#xff0c;让多数人只能无奈接受这些"不完美的记忆"。AI技术的发展&#xff0c;让普通用户也能轻松拥有专…

Linux 网络与常用操作(适合开发/运维/网络工程师)

目录 OSI 七层协议简介 应用层 传输层 Linux 命令&#xff01;&#xff01;&#xff01; 1. ifconfig 命令 简介 1. 查看网络地址信息 2. 指定开启、或者关闭网卡 3. 修改、设置 IP 地址 4. 修改机器的 MAC 地址信息 5. 永久修改网络设备信息 2. route 路由命令 …

PID控制学习

前言 本篇文章属于PID控制算法的学习笔记&#xff0c;来源于B站教学视频。下面是这位up主的视频链接。本文为个人学习笔记&#xff0c;只能做参考&#xff0c;细节方面建议观看视频&#xff0c;肯定受益匪浅。 PID入门教程-电机控制 倒立摆 持续更新中_哔哩哔哩_bilibili 一…

第1期 定时器实现非阻塞式程序 按键控制LED闪烁模式

第1期 定时器实现非阻塞式程序 按键控制LED闪烁模式 解决按键扫描&#xff0c;松手检测时阻塞的问题实现LED闪烁的非阻塞总结补充&#xff08;为什么不会阻塞&#xff09; 参考江协科技 KEY1和KEY2两者独立控制互不影响 阻塞&#xff1a;如果按下按键不松手&#xff0c;程序就…

【Arxiv 大模型最新进展】PEAR: 零额外推理开销,提升RAG性能!(★AI最前线★)

【Arxiv 大模型最新进展】PEAR: 零额外推理开销&#xff0c;提升RAG性能&#xff01;&#xff08;★AI最前线★&#xff09; &#x1f31f; 嗨&#xff0c;你好&#xff0c;我是 青松 &#xff01; &#x1f308; 自小刺头深草里&#xff0c;而今渐觉出蓬蒿。 NLP Github 项目…

vscode的一些实用操作

1. 焦点切换(比如主要用到使用快捷键在编辑区和终端区进行切换操作) 2. 跳转行号 使用ctrl g,然后输入指定的文件内容&#xff0c;即可跳转到相应位置。 使用ctrl p,然后输入指定的行号&#xff0c;回车即可跳转到相应行号位置。

OAI 平台 4G(LTE)基站 、终端、核心网 端到端部署实践(一)

本系列文章,基于OAI LTE代码搭建端到端运行环境,包含 eNB,EPC,UE三个网元。本小节先介绍系统总体架构,硬件平台及驱动安装方法。 1. Overview 系统总体架构如下图所示。 2 Machine setup 2.1 Machine specs Distributor ID: Ubuntu Description: Ubuntu 18.04.5 LTS…

Linux环境Docker使用代理推拉镜像

闲扯几句 不知不觉已经2月中了&#xff0c;1个半月忙得没写博客&#xff0c;这篇其实很早就想写了&#xff08;可追溯到Docker刚刚无法拉镜像的时候&#xff09;&#xff0c;由于工作和生活上的事比较多又在备考软考架构&#xff0c;拖了好久…… 简单记录下怎么做的&#xf…