使用React复刻ThreeJS官网示例——keyframes动画

最近在看three.js相关的东西,想着学习一下threejs给的examples。源码是用html结合js写的,恰好最近也在学习react,就用react框架学习一下。
本文参考的是threeJs给的第一个示例
three.js examples (threejs.org)

一、下载threeJS源码
通常我们只用通过npm引入threejs的包就可以使用threejs了。为什么这里需要下载源码呢?因为我们要复刻源码给的示例,相关的模型我们是没有的,需要使用源码里用到的模型及解析工具
GitHub - mrdoob/three.js: JavaScript 3D Library.
从git上拉取代码后可以找到示例一的源码
阅读源码可以发现,完成示例需要引入jsm/libs/draco/gltf/路径以及models/gltf/LittlestTokyo.glb模型。
拷贝threeJS的必要的模型和方法
为了方便后续学习,我们直接将这两个文件夹jsm和models拷贝到react项目中;注意路径最好是public下,public是默认的静态资源加载入口

二、功能解析与改写
react搭建及threejs引入可以参考我的之前的博客,这里不多赘述
Three.js机器人与星系动态场景:实现3D渲染与交互式控制-CSDN博客
引入必要信息
import { useEffect, useRef } from "react";
import * as THREE from "three";
import Stats from "three/examples/jsm/libs/stats.module.js";
import { GLTF, GLTFLoader } from "three/examples/jsm/loaders/GLTFLoader.js";
import { OrbitControls } from "three/examples/jsm/controls/OrbitControls";
import { RoomEnvironment } from "three/examples/jsm/environments/RoomEnvironment.js";
import { DRACOLoader } from "three/examples/jsm/loaders/DRACOLoader.js";
初始化Render渲染器/Scene场景/ camer相机/controls轨道控制器
// 初始化渲染器的函数
/*** 初始化 WebGL 渲染器* @returns {THREE.WebGLRenderer} 创建并配置好的渲染器实例*/
// 初始化渲染
function initRender(): THREE.WebGLRenderer {// 创建一个WebGL渲染器const renderer = new THREE.WebGLRenderer({ antialias: true });// 根据设备像素比设置渲染器像素比renderer.setPixelRatio(window.devicePixelRatio);// 设置渲染器大小renderer.setSize(window.innerWidth, window.innerHeight);return renderer;
}// 初始化场景的函数
/*** 初始化场景* @param {THREE.WebGLRenderer} renderer - 渲染器实例* @returns {THREE.Scene} 创建并配置好的场景实例*/
function initScene(renderer: THREE.WebGLRenderer) {// 创建 PMREM 生成器const pmremGenerator = new THREE.PMREMGenerator(renderer);// 创建场景const scene = new THREE.Scene();// 设置场景背景scene.background = new THREE.Color(0xbfe3dd);// 设置场景环境scene.environment = pmremGenerator.fromScene(new RoomEnvironment(renderer), 0.04).texture;return scene;
}// 初始化相机的函数
/*** 初始化相机* @param {number} x - 相机在 x 轴的位置* @param {number} y - 相机在 y 轴的位置* @param {number} z - 相机在 z 轴的位置* @returns {THREE.PerspectiveCamera} 创建并配置好位置的相机实例*/
function initCamera(x: number, y: number, z: number) {const camera = new THREE.PerspectiveCamera(40, window.innerWidth / window.innerHeight, 1, 100);camera.position.set(x, y, z);return camera;
}// 初始化控制器的函数
/*** 初始化轨道控制器* @param {THREE.PerspectiveCamera} camera - 相机实例* @param {THREE.WebGLRenderer} renderer - 渲染器实例* @returns {OrbitControls} 创建并配置好的轨道控制器实例*/
function initControls(camera: THREE.PerspectiveCamera, renderer: THREE.WebGLRenderer) {const controls = new OrbitControls(camera, renderer.domElement);controls.update();controls.enablePan = false;controls.enableDamping = true;return controls;
}
组件核心方法Keyframes
采用react的函数式组件写法,首字母大写作为组件名,并导出
整个流程是初始化渲染器、scene场景、camera相机、controls轨道控制器;在场景中引入模型,并使用dracoLoader解压GLTFLoader引入的模型,开启模型上的动画,设置场景动画。
/*** Keyframes 组件函数*/
function Keyframes() {const containerRef = useRef<HTMLDivElement>(null); // 创建用于引用 HTML 元素的 refconst clock = new THREE.Clock(); // 创建时钟实例const statsRef = useRef<Stats>(); // 创建用于引用统计信息的 refconst mixerRef = useRef<THREE.AnimationMixer>(); // 创建用于引用动画混合器的 refconst renderer = initRender(); // 初始化渲染器const scene = initScene(renderer); // 初始化场景const camera = initCamera(5, 2, 10); // 初始化相机const controls = initControls(camera, renderer); // 初始化控制器controls.target.set(0, 0.5, 0); // 设置控制器的目标const dracoLoader = new DRACOLoader(); // 创建 Draco 加载器dracoLoader.setDecoderPath("jsm/libs/draco/gltf/"); // 设置 Draco 解码器路径const loader = new GLTFLoader(); // 创建 GLTF 加载器loader.setDRACOLoader(dracoLoader); // 为 GLTF 加载器设置 Draco 加载器// 加载 GLTF 模型loader.load("models/gltf/LittlestTokyo.glb",(gltf: GLTF) => {const model = gltf.scene; // 获取模型的场景model.position.set(1, 1, 0); // 设置模型的位置model.scale.set(0.01, 0.01, 0.01); // 设置模型的缩放scene.add(model); // 将模型添加到场景mixerRef.current = new THREE.AnimationMixer(model); // 创建动画混合器mixerRef.current.clipAction(gltf.animations[0]).play(); // 播放动画renderer.setAnimationLoop(animate); // 设置渲染循环},undefined,(e) => {console.error(e); // 处理加载错误},);// 渲染循环函数/*** 每一帧的更新和渲染逻辑*/function animate() {const delta = clock.getDelta(); // 获取时间间隔mixerRef.current && mixerRef.current.update(delta); // 更新动画混合器controls.update(); // 更新控制器statsRef.current && statsRef.current.update(); // 更新统计信息renderer.render(scene, camera); // 渲染场景和相机}// 处理窗口大小改变的函数/*** 处理窗口大小改变时的相机和渲染器更新*/function onWindowResize() {camera.aspect = window.innerWidth / window.innerHeight; // 更新相机的宽高比camera.updateProjectionMatrix(); // 更新相机的投影矩阵controls.update(); // 更新控制器renderer.setSize(window.innerWidth, window.innerHeight); // 更新渲染器的大小}// 使用 useEffect 钩子useEffect(() => {if (!containerRef.current) return;containerRef.current.appendChild(renderer.domElement); // 将渲染器的 DOM 元素添加到引用的元素中statsRef.current = new Stats(); // 创建统计信息实例containerRef.current.appendChild(statsRef.current.dom); // 将统计信息的 DOM 元素添加到引用的元素中window.addEventListener("resize", onWindowResize); // 添加窗口大小改变的监听事件return () => {window.removeEventListener("resize", onWindowResize); // 清除窗口大小改变的监听事件renderer.setAnimationLoop(null); // 清除渲染循环};}, []);return <div ref={containerRef}></div>; // 返回一个带有 ref 的 div 元素
}
export default Keyframes; // 导出 Keyframes 组件
通过<div ref={containerRef}></div> 创建一个dom元素,用于3D场景挂载
模型加载与Draco解码
示例模型提供的是压缩后的模型,在页面加载时需要进行解压,必须使用dracoLoader方法,设置解码方法所在路径。在通过GLTFLoader导入。示例如下:
const dracoLoader = new DRACOLoader(); // 创建 Draco 加载器dracoLoader.setDecoderPath("jsm/libs/draco/gltf/"); // 设置 Draco 解码器路径const loader = new GLTFLoader(); // 创建 GLTF 加载器loader.setDRACOLoader(dracoLoader); // 为 GLTF 加载器设置 Draco 加载器// 加载 GLTF 模型loader.load("models/gltf/LittlestTokyo.glb",(gltf: GLTF) => {//处理模型},undefined,(e) => {console.error(e); // 处理加载错误},);
AnimationMixer 动画混合器
AnimationMixer动画混合器是用于场景中特定对象的动画的播放器。当场景中的多个对象独立动画时,每个对象都可以使用同一个动画混合器。
- 参数:
rootObject混合器播放的动画所属的对象。就是包含动画模型的场景对象。- 常用参数和属性:
.time全局的混合器时间。.clipAction(AnimationClip)返回所传入的剪辑参数的AnimationAction对象。AnimationAction用来调度存储在AnimationClip中的动画。
AnimationClip动画剪辑,是一个可重用的关键帧轨道集,它代表动画。
.getRoot()返回混合器的根对象。.update()推进混合器时间并更新动画。在渲染函数中调用更新动画。
在我们的示例中模型加载到场景时默认时没有动画的,也就是模型自身的动画比如小火车和风扇小人都是不动的。
在模型加载的时候通过AnimationMixer开启模型动画
// 加载 GLTF 模型loader.load("models/gltf/LittlestTokyo.glb",(gltf: GLTF) => {const model = gltf.scene; // 获取模型的场景model.position.set(1, 1, 0); // 设置模型的位置model.scale.set(0.01, 0.01, 0.01); // 设置模型的缩放scene.add(model); // 将模型添加到场景mixerRef.current = new THREE.AnimationMixer(model); // 创建动画混合器mixerRef.current.clipAction(gltf.animations[0]).play(); // 播放动画renderer.setAnimationLoop(animate); // 设置渲染循环},undefined,(e) => {console.error(e); // 处理加载错误},);
setAnimationLoop动画循环
在Three.js中,
setAnimationLoop方法是用来设置一个函数,这个函数会在每一帧被调用来进行渲染。这是必须的,因为在Three.js中,渲染循环不是自动开始的,你需要告诉渲染器何时以及如何进行渲染。
以下是为什么加载模型时必须使用 setAnimationLoop 的一些原因:
-
渲染控制:通过
setAnimationLoop,你可以控制渲染循环的开始和结束。如果你不设置它,即使模型加载完成,也不会自动开始渲染过程。 -
动画播放:在你的代码中,你使用了
AnimationMixer来播放模型中的动画。这个动画需要在每一帧更新,以确保动画的连贯性和流畅性。setAnimationLoop允许你在每一帧更新动画状态。 -
性能优化:使用
setAnimationLoop可以让你在不需要渲染的时候停止渲染,比如在浏览器标签页不可见时,这样可以节省资源并提高性能。 -
逻辑更新:在
animate函数中,你可以执行除了渲染之外的其他逻辑,比如更新动画、控制器和统计信息等。这些更新是渲染过程的一部分,需要在每一帧进行。
如果你不使用
setAnimationLoop,你需要自己手动创建一个循环来不断调用renderer.render(scene, camera),并且确保在合适的时机更新动画和其他逻辑。这通常是通过requestAnimationFrame函数来实现的,但Three.js提供了setAnimationLoop来简化这一过程。总之,
setAnimationLoop是Three.js中用来启动和维持渲染循环的关键方法,特别是在涉及到动画的情况下,它是必须的。
可以看到模型自身的多个动画都动起来了
Stats.js帧检测工具
不管是做游戏还是做普通网页,在这个时代基本都离不开动画。说到动画,第一个联想到的概念就是“帧”。这是用来衡量和描述动画是否流畅的一个单位。
示例程序的左上角有个工具窗口持续监测FPS数值
FPS是“Frames Per Second”的缩写,意为“每秒帧数”。在视频游戏和计算机图形学中,FPS用来衡量显示设备每秒钟能够显示的静止图像(帧)的数量。这个数值越高,表示图像更新得越快,视觉效果就越流畅。
在游戏领域,高FPS通常意味着更平滑的游戏体验,尤其是在快速移动或复杂场景中。然而,FPS并不是唯一影响游戏体验的因素,图像质量、响应时间和系统稳定性也同样重要。
一般来说,人眼能够感知到的流畅动画大约需要30FPS以上,而60FPS或更高则被认为是高质量游戏体验的标准。不过,这也取决于个人的视觉感知能力和对流畅度的要求。

用法
在使用
npm install three下载的依赖包中已经包含了Stats.js了
可以这样引入到项目中
import Stats from "three/examples/jsm/libs/stats.module.js";
通过new Stats()方法创建一个stats实例 。默认showPanel是0,显示FPS面板。

通过showPanel方法切换显示方式;可以根据dom改变stats面板的位置,使用示例如下
const statsRef = useRef<Stats>(); // 创建用于引用统计信息的 refstatsRef.current = new Stats(); // 创建统计信息实例statsRef.current.showPanel(1);statsRef.current.dom.style.position = "absolute"; // 设置统计信息的 DOM 元素的位置statsRef.current.dom.style.top = "0px"; // 设置统计信息的 DOM 元素的位置statsRef.current.dom.style.left = "0px"; // 设置统计信息的 DOM 元素的位置
通过操作dom的方式将stats节点追加到3D场景中
containerRef.current.appendChild(statsRef.current.dom); // 将统计信息的 DOM 元素添加到引用的元素中
默认就显示在屏幕的左上角

当点击该面板时还可以切换监听的类型
响应式窗口
页面加载时给了初始的renderer的宽高,但是如果用户使用过程中可视区域发生了变化renderer无法自动使用屏幕

可以在useEffect里通过事件监听浏览器的resize事件,当浏览器尺寸变化时重新以最新的宽高设为renderer的尺寸信息
// 处理窗口大小改变的函数/*** 处理窗口大小改变时的相机和渲染器更新*/function onWindowResize() {camera.aspect = window.innerWidth / window.innerHeight; // 更新相机的宽高比camera.updateProjectionMatrix(); // 更新相机的投影矩阵controls.update(); // 更新控制器renderer.setSize(window.innerWidth, window.innerHeight); // 更新渲染器的大小}// 使用 useEffect 钩子useEffect(() => {if (!containerRef.current) return;containerRef.current.appendChild(renderer.domElement); // 将渲染器的 DOM 元素添加到引用的元素中statsRef.current = new Stats(); // 创建统计信息实例containerRef.current.appendChild(statsRef.current.dom); // 将统计信息的 DOM 元素添加到引用的元素中window.addEventListener("resize", onWindowResize); // 添加窗口大小改变的监听事件return () => {window.removeEventListener("resize", onWindowResize); // 清除窗口大小改变的监听事件renderer.setAnimationLoop(null); // 清除渲染循环};}, []);

完整代码
import { useEffect, useRef } from "react";
import * as THREE from "three";
import Stats from "three/examples/jsm/libs/stats.module.js";
import { GLTF, GLTFLoader } from "three/examples/jsm/loaders/GLTFLoader.js";
import { OrbitControls } from "three/examples/jsm/controls/OrbitControls";
import { RoomEnvironment } from "three/examples/jsm/environments/RoomEnvironment.js";
import { DRACOLoader } from "three/examples/jsm/loaders/DRACOLoader.js";// 初始化渲染器的函数
/*** 初始化 WebGL 渲染器* @returns {THREE.WebGLRenderer} 创建并配置好的渲染器实例*/
// 初始化渲染
function initRender(): THREE.WebGLRenderer {// 创建一个WebGL渲染器const renderer = new THREE.WebGLRenderer({ antialias: true });// 根据设备像素比设置渲染器像素比renderer.setPixelRatio(window.devicePixelRatio);// 设置渲染器大小renderer.setSize(window.innerWidth, window.innerHeight);return renderer;
}// 初始化场景的函数
/*** 初始化场景* @param {THREE.WebGLRenderer} renderer - 渲染器实例* @returns {THREE.Scene} 创建并配置好的场景实例*/
function initScene(renderer: THREE.WebGLRenderer) {// 创建 PMREM 生成器const pmremGenerator = new THREE.PMREMGenerator(renderer);// 创建场景const scene = new THREE.Scene();// 设置场景背景scene.background = new THREE.Color(0xbfe3dd);// 设置场景环境scene.environment = pmremGenerator.fromScene(new RoomEnvironment(renderer), 0.04).texture;return scene;
}// 初始化相机的函数
/*** 初始化相机* @param {number} x - 相机在 x 轴的位置* @param {number} y - 相机在 y 轴的位置* @param {number} z - 相机在 z 轴的位置* @returns {THREE.PerspectiveCamera} 创建并配置好位置的相机实例*/
function initCamera(x: number, y: number, z: number) {const camera = new THREE.PerspectiveCamera(40, window.innerWidth / window.innerHeight, 1, 100);camera.position.set(x, y, z);return camera;
}// 初始化控制器的函数
/*** 初始化轨道控制器* @param {THREE.PerspectiveCamera} camera - 相机实例* @param {THREE.WebGLRenderer} renderer - 渲染器实例* @returns {OrbitControls} 创建并配置好的轨道控制器实例*/
function initControls(camera: THREE.PerspectiveCamera, renderer: THREE.WebGLRenderer) {const controls = new OrbitControls(camera, renderer.domElement);controls.update();controls.enablePan = false;controls.enableDamping = true;return controls;
}/*** Keyframes 组件函数*/
function Keyframes() {const containerRef = useRef<HTMLDivElement>(null); // 创建用于引用 HTML 元素的 refconst clock = new THREE.Clock(); // 创建时钟实例const statsRef = useRef<Stats>(); // 创建用于引用统计信息的 refconst mixerRef = useRef<THREE.AnimationMixer>(); // 创建用于引用动画混合器的 refconst renderer = initRender(); // 初始化渲染器const scene = initScene(renderer); // 初始化场景const camera = initCamera(5, 2, 10); // 初始化相机const controls = initControls(camera, renderer); // 初始化控制器controls.target.set(0, 0.5, 0); // 设置控制器的目标const dracoLoader = new DRACOLoader(); // 创建 Draco 加载器dracoLoader.setDecoderPath("jsm/libs/draco/gltf/"); // 设置 Draco 解码器路径const loader = new GLTFLoader(); // 创建 GLTF 加载器loader.setDRACOLoader(dracoLoader); // 为 GLTF 加载器设置 Draco 加载器// 加载 GLTF 模型loader.load("models/gltf/LittlestTokyo.glb",(gltf: GLTF) => {const model = gltf.scene; // 获取模型的场景model.position.set(1, 1, 0); // 设置模型的位置model.scale.set(0.01, 0.01, 0.01); // 设置模型的缩放scene.add(model); // 将模型添加到场景mixerRef.current = new THREE.AnimationMixer(model); // 创建动画混合器mixerRef.current.clipAction(gltf.animations[0]).play(); // 播放动画renderer.setAnimationLoop(animate); // 设置渲染循环},undefined,(e) => {console.error(e); // 处理加载错误},);// 渲染循环函数/*** 每一帧的更新和渲染逻辑*/function animate() {const delta = clock.getDelta(); // 获取时间间隔mixerRef.current && mixerRef.current.update(delta); // 更新动画混合器controls.update(); // 更新控制器statsRef.current && statsRef.current.update(); // 更新统计信息renderer.render(scene, camera); // 渲染场景和相机}// 处理窗口大小改变的函数/*** 处理窗口大小改变时的相机和渲染器更新*/function onWindowResize() {camera.aspect = window.innerWidth / window.innerHeight; // 更新相机的宽高比camera.updateProjectionMatrix(); // 更新相机的投影矩阵controls.update(); // 更新控制器renderer.setSize(window.innerWidth, window.innerHeight); // 更新渲染器的大小}// 使用 useEffect 钩子useEffect(() => {if (!containerRef.current) return;containerRef.current.appendChild(renderer.domElement); // 将渲染器的 DOM 元素添加到引用的元素中statsRef.current = new Stats(); // 创建统计信息实例containerRef.current.appendChild(statsRef.current.dom); // 将统计信息的 DOM 元素添加到引用的元素中window.addEventListener("resize", onWindowResize); // 添加窗口大小改变的监听事件return () => {window.removeEventListener("resize", onWindowResize); // 清除窗口大小改变的监听事件renderer.setAnimationLoop(null); // 清除渲染循环};}, []);return <div ref={containerRef}></div>; // 返回一个带有 ref 的 div 元素
}export default Keyframes; // 导出 Keyframes 组件
相关文章:
使用React复刻ThreeJS官网示例——keyframes动画
最近在看three.js相关的东西,想着学习一下threejs给的examples。源码是用html结合js写的,恰好最近也在学习react,就用react框架学习一下。 本文参考的是threeJs给的第一个示例 three.js examples (threejs.org) 一、下载threeJS源码 通常我们…...
嵌入式linux面试1
1. linux 1.1. Window系统和Linux系统的区别 linux区分大小写windows在dos(磁盘操作系统)界面命令下不区分大小写; 1.2. 文件格式区分 windows用扩展名区分文件;如.exe代表执行文件,.txt代表文本文件,.…...
智能交通(3)——Learning Phase Competition for Traffic Signal Control
论文分享 https://dl.acm.org/doi/pdf/10.1145/3357384.3357900https://dl.acm.org/doi/pdf/10.1145/3357384.3357900 论文代码 https://github.com/gjzheng93/frap-pubhttps://github.com/gjzheng93/frap-pub 摘要 越来越多可用的城市数据和先进的学习技术使人们能够提…...
【扩散模型】LCM LoRA:一个通用的Stable Diffusion加速模块
潜在一致性模型:[2310.04378] Latent Consistency Models: Synthesizing High-Resolution Images with Few-Step Inference (arxiv.org) 原文:Paper page - Latent Consistency Models: Synthesizing High-Resolution Images with Few-Step Inference (…...
【PYG】pytorch中size和shape有什么不同
一般使用tensor.shape打印维度信息,因为简单直接 在 PyTorch 中,size 和 shape 都用于获取张量的维度信息,但它们之间有细微的区别。下面是它们的定义和用法: size: size 是一个方法(size())和…...
备份服务器出错怎么办?
在企业的日常运营中,备份服务器扮演着至关重要的角色,它确保了数据的安全和业务的连续性。然而,备份服务器也可能遇到各种问题,如备份失败、数据损坏或备份系统故障等。这些问题可能导致数据丢失或业务中断,给企业带来…...
数据库(表)
要求如下: 一:数据库 1,登录数据库 mysql -uroot -p123123 2,创建数据库zoo create database zoo; Query OK, 1 row affected (0.01 sec) 3,修改字符集 mysql> use zoo;---先进入数据库zoo Database changed …...
Feign-未完成
Feign Java中如何实现接口调用?即如何发起http请求 前三种方式比较麻烦,在发起请求前,需要将Java对象进行序列化转为json格式的数据,才能发送,然后进行响应时,还需要把json数据进行反序列化成java对象。 …...
# [0705] Task06 DDPG 算法、PPO 算法、SAC 算法【理论 only】
easy-rl PDF版本 笔记整理 P5、P10 - P12 joyrl 比对 补充 P11 - P13 OpenAI 文档整理 ⭐ https://spinningup.openai.com/en/latest/index.html 最新版PDF下载 地址:https://github.com/datawhalechina/easy-rl/releases 国内地址(推荐国内读者使用): 链…...
Open3D 点云CPD算法配准(粗配准)
目录 一、概述 二、代码实现 2.1关键函数 2.2完整代码 三、实现效果 3.1原始点云 3.2配准后点云 一、概述 在Open3D中,CPD(Coherent Point Drift,一致性点漂移)算法是一种经典的点云配准方法,适用于无序点云的非…...
04-ArcGIS For JavaScript的可视域分析功能
文章目录 综述代码实现代码解析结果 综述 在数字孪生或者实景三维的项目中,视频融合和可视域分析,一直都是热点问题。Cesium中,支持对阴影的后处理操作,通过重新编写GLSL代码就能实现视域和视频融合的功能。ArcGIS之前支持的可视…...
Nestjs基础
一、创建项目 1、创建 安装 Nest CLI(只需要安装一次) npm i -g nestjs/cli 进入要创建项目的目录,使用 Nest CLI 创建项目 nest new 项目名 运行项目 npm run start 开发环境下运行,自动刷新服务 npm run start:dev 2、…...
DDL:针对于数据库、数据表、数据字段的操作
数据库的操作 # 查询所有数据 SHOW DATABASE; #创建数据库 CREATE DATABASE 2404javaee; #删除数据库 DROP DATABASE 2404javaee; 数据表的操作 #创建表 CREATE TABLE s_student( name VARCHAR(64), s_sex VARCHAR(32), age INT(3), salary FLOAT(8,2), c_course VARC…...
昇思学习打卡-5-基于Mindspore实现BERT对话情绪识别
本章节学习一个基本实践–基于Mindspore实现BERT对话情绪识别 自然语言处理任务的应用很广泛,如预训练语言模型例如问答、自然语言推理、命名实体识别与文本分类、搜索引擎优化、机器翻译、语音识别与合成、情感分析、聊天机器人与虚拟助手、文本摘要与生成、信息抽…...
Java中 普通for循环, 增强for循环( foreach) List中增删改查的注意事项
文章目录 俩种循环遍历增加删除1 根据index删除2 根据对象删除 修改 俩种循环 Java中 普通for循环, 增强for循环( foreach) 俩种List的遍历方式有何异同,性能差异? 普通for循环(使用索引遍历): for (int…...
昇思25天学习打卡营第19天|LSTM+CRF序列标注
概述 序列标注指给定输入序列,给序列中每个Token进行标注标签的过程。序列标注问题通常用于从文本中进行信息抽取,包括分词(Word Segmentation)、词性标注(Position Tagging)、命名实体识别(Named Entity Recognition, NER)等。 条件随机场(…...
微服务: 初识 Spring Cloud
什么是微服务? 微服务就像把一个大公司拆成很多小部门,每个部门各自负责一块业务。这样一来,每个部门都可以独立工作,即使一个部门出了问题,也不会影响整个公司运作。 什么是Spring Cloud? Spring Cloud 是一套工具包&#x…...
探索InitializingBean:Spring框架中的隐藏宝藏
🌈 个人主页:danci_ 🔥 系列专栏:《设计模式》《MYSQL》 💪🏻 制定明确可量化的目标,坚持默默的做事。 ✨欢迎加入探索MYSQL索引数据结构之旅✨ 👋 Spring框架的浩瀚海洋中&#x…...
JVM专题之垃圾收集算法
标记清除算法 第一步:标记 (找出内存中需要回收的对象,并且把它们标记出来) 第二步:清除 (清除掉被标记需要回收的对象,释放出对应的内存空间) 缺点: 标记清除之后会产生大量不连续的内存碎片,空间碎片太多可能会导致以后在程序运行过程中需 要分配较大对象时,无法找到…...
2024年6月后2周重要的大语言模型论文总结:LLM进展、微调、推理和对齐
本文总结了2024年6月后两周发表的一些最重要的大语言模型论文。这些论文涵盖了塑造下一代语言模型的各种主题,从模型优化和缩放到推理、基准测试和增强性能。 LLM进展与基准 1、 BigCodeBench: Benchmarking Code Generation with Diverse Function Calls and Com…...
从WWDC看苹果产品发展的规律
WWDC 是苹果公司一年一度面向全球开发者的盛会,其主题演讲展现了苹果在产品设计、技术路线、用户体验和生态系统构建上的核心理念与演进脉络。我们借助 ChatGPT Deep Research 工具,对过去十年 WWDC 主题演讲内容进行了系统化分析,形成了这份…...
AtCoder 第409场初级竞赛 A~E题解
A Conflict 【题目链接】 原题链接:A - Conflict 【考点】 枚举 【题目大意】 找到是否有两人都想要的物品。 【解析】 遍历两端字符串,只有在同时为 o 时输出 Yes 并结束程序,否则输出 No。 【难度】 GESP三级 【代码参考】 #i…...
深入理解JavaScript设计模式之单例模式
目录 什么是单例模式为什么需要单例模式常见应用场景包括 单例模式实现透明单例模式实现不透明单例模式用代理实现单例模式javaScript中的单例模式使用命名空间使用闭包封装私有变量 惰性单例通用的惰性单例 结语 什么是单例模式 单例模式(Singleton Pattern&#…...
Unity | AmplifyShaderEditor插件基础(第七集:平面波动shader)
目录 一、👋🏻前言 二、😈sinx波动的基本原理 三、😈波动起来 1.sinx节点介绍 2.vertexPosition 3.集成Vector3 a.节点Append b.连起来 4.波动起来 a.波动的原理 b.时间节点 c.sinx的处理 四、🌊波动优化…...
Go 语言并发编程基础:无缓冲与有缓冲通道
在上一章节中,我们了解了 Channel 的基本用法。本章将重点分析 Go 中通道的两种类型 —— 无缓冲通道与有缓冲通道,它们在并发编程中各具特点和应用场景。 一、通道的基本分类 类型定义形式特点无缓冲通道make(chan T)发送和接收都必须准备好࿰…...
纯 Java 项目(非 SpringBoot)集成 Mybatis-Plus 和 Mybatis-Plus-Join
纯 Java 项目(非 SpringBoot)集成 Mybatis-Plus 和 Mybatis-Plus-Join 1、依赖1.1、依赖版本1.2、pom.xml 2、代码2.1、SqlSession 构造器2.2、MybatisPlus代码生成器2.3、获取 config.yml 配置2.3.1、config.yml2.3.2、项目配置类 2.4、ftl 模板2.4.1、…...
C#学习第29天:表达式树(Expression Trees)
目录 什么是表达式树? 核心概念 1.表达式树的构建 2. 表达式树与Lambda表达式 3.解析和访问表达式树 4.动态条件查询 表达式树的优势 1.动态构建查询 2.LINQ 提供程序支持: 3.性能优化 4.元数据处理 5.代码转换和重写 适用场景 代码复杂性…...
Python 实现 Web 静态服务器(HTTP 协议)
目录 一、在本地启动 HTTP 服务器1. Windows 下安装 node.js1)下载安装包2)配置环境变量3)安装镜像4)node.js 的常用命令 2. 安装 http-server 服务3. 使用 http-server 开启服务1)使用 http-server2)详解 …...
Linux系统部署KES
1、安装准备 1.版本说明V008R006C009B0014 V008:是version产品的大版本。 R006:是release产品特性版本。 C009:是通用版 B0014:是build开发过程中的构建版本2.硬件要求 #安全版和企业版 内存:1GB 以上 硬盘…...
Python 训练营打卡 Day 47
注意力热力图可视化 在day 46代码的基础上,对比不同卷积层热力图可视化的结果 import torch import torch.nn as nn import torch.optim as optim from torchvision import datasets, transforms from torch.utils.data import DataLoader import matplotlib.pypl…...

