前端小练习——星辰宇宙(JS没有上限!!!)

        前言:在刚开始学习前端的时候,我们会学习到前端三件套中的JavaScript,可能那时候读者没有觉得JavaScript这个语言有多么的牛逼,本篇文章将会使用一个炫酷的案例来刷新你对JavaScript这个语言的认知与理解。


✨✨✨这里是秋刀鱼不做梦的BLOG

✨✨✨想要了解更多内容可以访问我的主页秋刀鱼不做梦-CSDN博客

先让我们看一下最终的结果:

在开始讲解这个炫酷的案例之前,先让我们了解一下本案例所需的前置知识:

  1. Three.js:一个用于创建和显示3D图形的JavaScript库。代码中导入了Three.js的核心库和轨道控制库(OrbitControls),用于处理3D场景的创建和相机控制。

  2. WebGL:用于在网页中绘制3D图形的底层API。Three.js封装了WebGL,使得3D渲染变得更简单。

  3. 模块化 JavaScript:使用 ES6 的模块导入语法 (import) 引入外部库,使代码结构更加清晰。

  4. 着色器编程:自定义顶点和片段着色器,通过 onBeforeCompile 方法替换默认着色器,控制点的大小、颜色和运动效果。

  5. 缓冲几何体:使用 BufferGeometry 来管理大量点的性能,提升渲染效率。

  6. 动画循环:利用 setAnimationLoop 实现流畅的渲染动画,每帧更新控制器状态和场景渲染。

  7. 响应式设计:通过 resize 事件监听器,动态调整相机和渲染器的尺寸,以适应浏览器窗口的变化。

        ——在文章的最后,我们给出了实现这个案例的全部代码,读者可以直接复制后在自己的编译器上执行一下!!!

        那么现在正式开始我们的讲解:

目录

1.导入库和清理控制台

2.创建场景和相机

3.创建渲染器

4. 处理窗口大小变化

5. 控制器设置

6. 创建全局uniform变量和点的属性

7. 创建点的顶点数组

 8. 添加围绕的点

9. 创建几何体和材质

10. 创建点云并添加到场景

11. 渲染循环

——全部代码


1.导入库和清理控制台

        开始我们要先导入库和清理控制台:

import * as THREE from "https://cdn.skypack.dev/three@0.136.0"; // 导入三维模型库
import { OrbitControls } from "https://cdn.skypack.dev/three@0.136.0/examples/jsm/controls/OrbitControls"; // 导入轨道控制库
console.clear(); // 清除控制台

        注释:这部分代码导入了Three.js库及其轨道控制功能,并清理了控制台,以便后续输出信息更清晰。

2.创建场景和相机

        在导入库和清理控制台后,我们就需要创建场景和相机:

let scene = new THREE.Scene(); // 创建场景
scene.background = new THREE.Color(0x160016); // 设置场景背景颜色let camera = new THREE.PerspectiveCamera(60, innerWidth / innerHeight, 1, 1000); // 创建相机
camera.position.set(0, 4, 21); // 设置相机位置

        注释:这部分代码创建了一个场景和一个透视相机,设置了相机的位置和背景颜色,为后续的渲染准备基础环境。

3.创建渲染器

        其后我们需要为其创建一个渲染器:

let renderer = new THREE.WebGLRenderer(); // 创建渲染器
renderer.setSize(innerWidth, innerHeight); // 设置渲染器大小
document.body.appendChild(renderer.domElement); // 把渲染器加入到页面中

        注释:这里创建了一个WebGL渲染器,并设置其大小为窗口的宽高,最后将渲染器的DOM元素添加到网页中,以显示渲染结果。

4. 处理窗口大小变化

        在创建完渲染器之后,我们需要对后续的窗口的大小的变化进行处理:

window.addEventListener("resize", event => {camera.aspect = innerWidth / innerHeight; // 更新相机的长宽比camera.updateProjectionMatrix(); // 更新相机的投影矩阵renderer.setSize(innerWidth, innerHeight); // 设置渲染器大小
});

        注释:这一部分代码监听窗口的大小变化,动态调整相机的长宽比和渲染器的大小,确保在窗口大小变化时,场景仍能正确显示。

5. 控制器设置

        处理完窗口大小的变化之后,我们就需要对控制器进行设置了!

let controls = new OrbitControls(camera, renderer.domElement); // 创建控制器
controls.enableDamping = true; // 开启阻尼效果
controls.enablePan; // 禁用平移(此行未完成)

        注释:这部分代码创建了一个轨道控制器,允许用户通过鼠标控制相机旋转和缩放,增强用户交互体验。注意,这里 enablePan 需要完整设置。

6. 创建全局uniform变量和点的属性

        接下来让哦我们对全局的uniform变量和点的属性进行设置:

let gu = {time: { value: 0 }
}; // 创建全局uniform变量let sizes = []; // 点的大小数组
let shift = []; // 点的移动数组let pushShift = () => { // 创建移动函数shift.push(Math.random() * Math.PI,Math.random() * Math.PI * 2,(Math.random() * 0.9 + 0.1) * Math.PI * 0.1,Math.random() * 0.9 + 0.1); // 随机生成位置信息
};

        注释:定义了一个全局uniform变量 gu 用于时间控制,并初始化了两个数组 sizesshift 用于存储点的大小和位置信息。同时,定义了一个函数 pushShift,用于生成随机的位移数据。

7. 创建点的顶点数组

        接下来让我们创建点的顶点数组:

let pts = new Array(50000).fill().map(p => {sizes.push(Math.random() * 1.5 + 0.5); // 添加随机大小pushShift(); // 添加位置信息return new THREE.Vector3().randomDirection().multiplyScalar(Math.random() * 0.5 + 9.5); // 返回随机方向的点
});

        注释:这里创建了一个包含5万个点的数组 pts,每个点都有随机的大小和方向。通过 randomDirection() 方法生成随机方向的向量,模拟球体内的点。

 8. 添加围绕的点

        创建完点的顶点数组之后,让我们添加其围绕的点:       

for (let i = 0; i < 100000; i++) {let r = 10, R = 40; // 定义内外半径let rand = Math.pow(Math.random(), 1.5); // 生成随机数let radius = Math.sqrt(R * R * rand + (1 - rand) * r * r); // 计算随机半径pts.push(new THREE.Vector3().setFromCylindricalCoords(radius, Math.random() * 2 * Math.PI, (Math.random() - 0.5) * 2)); // 生成点sizes.push(Math.random() * 1.5 + 0.5); // 添加随机大小pushShift(); // 添加位置信息
}

        注释:这部分代码在已有的点基础上,再添加10万个点。使用极坐标系生成点,使其在一定范围内均匀分布,丰富了场景中的点的数量和分布。

9. 创建几何体和材质

        接下来让我们设置一下几何体和其材质样式:

let g = new THREE.BufferGeometry().setFromPoints(pts); // 创建几何体
g.setAttribute("sizes", new THREE.Float32BufferAttribute(sizes, 1)); // 设置sizes属性
g.setAttribute("shift", new THREE.Float32BufferAttribute(shift, 4)); // 设置shift属性let m = new THREE.PointsMaterial({ // 创建点材质size: 0.125, // 点的大小transparent: true, // 透明材质depthTest: false, // 禁用深度测试blending: THREE.AdditiveBlending, // 添加混合模式onBeforeCompile: shader => { // 自定义着色器shader.uniforms.time = gu.time; // 设置uniform变量shader.vertexShader = `uniform float time;attribute float sizes;attribute vec4 shift;varying vec3 vColor;${shader.vertexShader}`; // 修改顶点着色器// 更新点的大小、颜色和移动逻辑shader.vertexShader = shader.vertexShader.replace(`gl_PointSize = size;`, `gl_PointSize = size * sizes;`).replace(`#include <color_vertex>`, `#include <color_vertex> float d = length(abs(position)/vec3(40.,10.,40)); d=clamp(d,0.,1.); vColor = mix(vec3(227.,155.,0.),vec3(100.,50.,255.),d)/255.;`).replace(`#include <begin_vertex>`, `#include <begin_vertex> float t = time; float moveT = mod(shift.x + shift.z * t,PI2); float moveS = mod(shift.y + shift.z * t,PI2); transformed += vec3(cos(moveS) * sin(moveT), cos(moveT), sin(moveS) * sin(moveT)) * shift.w;`);// 修改片元着色器shader.fragmentShader = `varying vec3 vColor;${shader.fragmentShader}`.replace(`#include <clipping_planes_fragment>`, `#include <clipping_planes_fragment> float d = length(gl_PointCoord.xy - 0.5);`).replace(`vec4 diffuseColor = vec4( diffuse, opacity );`, `vec4 diffuseColor = vec4( vColor, smoothstep(0.5, 0.1, d));`);}
});

        注释:在这部分代码中,创建了一个缓冲几何体并设置了点的大小和移动信息。还定义了一个点材质,使用自定义着色器来控制点的大小、颜色和移动效果,提供了动态的视觉效果。

10. 创建点云并添加到场景

        接下来让我们创建点云并添加到场景:

let p = new THREE.Points(g, m); // 创建点云
p.rotation.order = "ZYX"; // 设置旋转顺序
p.rotation.z = 0.2; // 设置初始旋转角度
scene.add(p); // 将点云添加到场景中

        注释:这里将创建的几何体和材质结合成一个点云对象,并设置其旋转顺序和初始旋转角度,最后将其添加到场景中以进行渲染。

11. 渲染循环

        最后让我们渲染一下环境:

let clock = new THREE.Clock(); // 创建时钟对象
renderer.setAnimationLoop(() => { // 设置渲染循环controls.update(); // 更新控制器let t = clock.getElapsedTime() * 0.5; // 获取流逝时间gu.time.value = t * Math.PI; // 更新时间p.rotation.y = t * 0.05; // 更新点云的旋转角度renderer.render(scene, camera); // 渲染场景和相机
});

        注释:最后,这段代码设置了渲染循环,利用时钟对象控制动画的时间,并不断更新控制器和点云的旋转,最终渲染场景。

        通过上述的分层讲解之后,我们就大致的了解每一步都是如何操作并且为什么这么操作的了,为了使读者能更好的理解上述流程,这里我们在进行总结一下:

  1. 导入库

    • 使用Three.js库和OrbitControls模块,准备进行三维场景的创建和交互。

  2. 场景和相机设置

    • 创建一个三维场景并设置背景颜色。

    • 创建透视相机,设定相机的位置,准备从特定角度观察场景。

  3. 渲染器初始化

    • 创建WebGL渲染器,设置其大小与窗口相同,并将其添加到网页中以显示内容。

  4. 窗口大小自适应

    • 添加事件监听器,以确保在窗口大小变化时,自动调整相机的长宽比和渲染器的大小,保持渲染效果。

  5. 控制器设置

    • 创建轨道控制器,允许用户通过鼠标控制相机的旋转和缩放,增强用户交互体验。

  6. 全局变量和点属性初始化

    • 定义用于控制动画的全局变量和点的大小、位移数组,准备生成点的运动效果。

  7. 点的生成

    • 生成大量随机位置的点,包括中心球体内的点和周围分布的点,以增加视觉复杂度。

  8. 几何体和材质设置

    • 创建缓冲几何体,设置点的大小和位移信息。

    • 定义点的材质,使用自定义着色器来控制点的大小、颜色和移动效果。

  9. 点云创建和添加到场景

    • 将几何体和材质组合成点云对象,并设置初始旋转,最后将其添加到场景中以进行渲染。

  10. 渲染循环

    • 使用时钟对象进行动画控制,在每一帧中更新控制器、点云的旋转和动画时间,并渲染场景。

        ——至此,我们就讲解完了上述案例的所以步骤了!!!

——全部代码

        最后在让我们看一下最终的效果,(JavaScript没有极限!!!)

<!DOCTYPE html>
<html lang="en"><head><meta charset="UTF-8"><meta http-equiv="X-UA-Compatible" content="IE=edge"><meta name="viewport" content="width=device-width, initial-scale=1.0"><title>秋刀鱼不做梦</title><style>body {overflow: hidden;margin: 0;}</style>
</head><body><script type="module">// 导入三维模型库import * as THREE from "https://cdn.skypack.dev/three@0.136.0";// 导入轨道控制库import { OrbitControls } from "https://cdn.skypack.dev/three@0.136.0/examples/jsm/controls/OrbitControls";// 清除控制台console.clear()// 创建场景let scene = new THREE.Scene()// 设置场景背景颜色scene.background = new THREE.Color(0x160016)// 创建相机let camera = new THREE.PerspectiveCamera(60, innerWidth / innerHeight, 1, 1000)// 设置相机位置camera.position.set(0, 4, 21)// 创建渲染器let renderer = new THREE.WebGLRenderer()// 设置渲染器大小renderer.setSize(innerWidth, innerHeight)// 把渲染器加入到页面中document.body.appendChild(renderer.domElement)// 监听窗口大小变化事件window.addEventListener("resize", event => {camera.aspect = innerWidth / innerHeightcamera.updateProjectionMatrix()renderer.setSize(innerWidth, innerHeight)})// 创建控制器let controls = new OrbitControls(camera, renderer.domElement)// 开启阻尼效果controls.enableDamping = true// 禁用面板controls.enablePan// 创建全局uniformlet gu = {time: { value: 0 }}// 创建点的大小数组和移动数组let sizes = []let shift = []// 创建移动函数let pushShift = () => {shift.push(Math.random() * Math.PI,Math.random() * Math.PI * 2,(Math.random() * 0.9 + 0.1) * Math.PI * 0.1,Math.random() * 0.9 + 0.1)}// 创建点的顶点数组(中间的球体)// 创建一个长度为5万的数组pts并y用Array.prototype.map()方法遍历数组并对每个元素进行操作let pts = new Array(50000).fill().map(p => {// 每次遍历中,会向sizes数组中添加一个随机大小sizes.push(Math.random() * 1.5 + 0.5)// 调用pushShift()函数添加位置信息,并返回一个随机方向的THREE.Vector对象pushShift()return new THREE.Vector3().randomDirection().multiplyScalar(Math.random() * 0.5 + 9.5)//})// 添加更多的点(旁边围绕的)// 先循环生成十万个点// 每次循环中生成一个随机数rand,再生成一个随机半径radiusfor (let i = 0; i < 100000; i++) {let r = 10, R = 40;let rand = Math.pow(Math.random(), 1.5);let radius = Math.sqrt(R * R * rand + (1 - rand) * r * r);// 使用new THREE.Vector3().setFromCylindricalCoords()生成一个点。pts.push(new THREE.Vector3().setFromCylindricalCoords(radius, Math.random() * 2 * Math.PI, (Math.random() - 0.5) * 2));sizes.push(Math.random() * 1.5 + 0.5);pushShift();}// 生成一个点g,同时将点的大小和位置信息添加到sizes和shift数组中let g = new THREE.BufferGeometry().setFromPoints(pts)// 创建了一个缓冲几何体并设置sizes和shift属性// 注意这里的F要大写Float32BufferAttributeg.setAttribute("sizes", new THREE.Float32BufferAttribute(sizes, 1))g.setAttribute("shift", new THREE.Float32BufferAttribute(shift, 4))// 创建点材质let m = new THREE.PointsMaterial({// 表示点的大小size: 0.125,// 设置材质为透明transparent: true,// 表示禁用深度测试,使点可以叠加depthTest: false,// 使用假发混合模式blending: THREE.AdditiveBlending,// 在材质编译之前修改颜色器,在这里,它用来替换顶点着色器和片元着色器,添加uniform// 和attribute,以鸡自定义颜色和移动onBeforeCompile: shader => {shader.uniforms.time = gu.time// 首先,它为着色器设置了一个uniform变量time,该变量是在点材质中定义的,用来追踪时间// 然后它定义了两个attribute变量sizes和shift,这两个变量是在缓冲几何体中定义的,用来控制点的大小和移动// 最后使用replace方法来替换顶点着色器中的代码shader.vertexShader = `uniform float time;attribute float sizes;attribute vec4 shift;varying vec3 vColor;${shader.vertexShader}`// 注意上面的 ` 不要漏掉了// 使用replace来替换着色器中的代码// 更新点的大小.replace(`gl_PointSize = size;`,`gl_PointSize = size * sizes;`)// 更新点的颜色.replace(`#include <color_vertex>`,`#include <color_vertex>float d = length(abs(position)/vec3(40.,10.,40));d=clamp(d,0.,1.);vColor = mix(vec3(227.,155.,0.),vec3(100.,50.,255.),d)/255.;`)// 记得加上分号// 更新点的移动.replace(`#include <begin_vertex>`,`#include <begin_vertex>float t = time;float moveT = mod(shift.x + shift.z * t,PI2);float moveS = mod(shift.y + shift.z * t,PI2);transformed += vec3(cos(moveS) * sin(moveT),cos(moveT),sin(moveS)*sin(moveT)) * shift.w;`)// 修改片元着色器,用来让点的边缘更加圆滑// 首先,定义一个varying变量vColor,这个变量是在顶点着色器中定义的,用来传递点的颜色到片段着色器// 然后使用replace方法来替换片段着色器的代码shader.fragmentShader = `varying vec3 vColor;${shader.fragmentShader}`.replace(`#include <clipping_planes_fragment>`,`#include <clipping_planes_fragment>float d = length(gl_PointCoord.xy - 0.5);`).replace(// 记得加上空格`vec4 diffuseColor = vec4( diffuse, opacity );`,`vec4 diffuseColor = vec4( vColor, smoothstep(0.5, 0.1, d)/* * 0.5+0.5*/);`);}})// 创建点云并将其添加到场景中,并设置渲染循环let p = new THREE.Points(g, m)// 旋转顺序为"ZYX"p.rotation.order = "ZYX"// 旋转角度 0.2p.rotation.z = 0.2// 把对象(p)添加到场景(scene)中scene.add(p)// 创建一个时钟对象clocklet clock = new THREE.Clock()// 渲染循环,每次循环中会更新控制器,更新p的旋转角度,更新时间renderer.setAnimationLoop(() => {// 更新控制器controls.update()// 获取时钟对象(clock)的已经流逝的时间(t)并将他乘0.5// 先把时钟关了let t = clock.getElapsedTime() * 0.5// 将gu.time.value 设置为t*Math.PIgu.time.value = t * Math.PI// 将对象(p)的旋转角度y设置为t*0.05p.rotation.y = t * 0.05// 渲染场景(scene)和相机(camera)renderer.render(scene, camera)})</script>
</body></html>


以上就是本篇文章的全部内容了!!!

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

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

相关文章

【网络】传输层协议TCP(下)

目录 四次挥手状态变化 流量控制 PSH标记位 URG标记位 滑动窗口 快重传 拥塞控制 延迟应答 mtu TCP异常情况 四次挥手状态变化 之前我们讲了四次挥手的具体过程以及为什么要进行四次挥手&#xff0c;下面是四次挥手的状态变化 那么我们下面可以来验证一下CLOSE_WAIT这…

XingHan-Team团队官网系统源码 全开源

XingHan-Team 官网程序是一个现代化的企业官网管理系统&#xff0c;由星涵网络工作室开发。 本系统提供了完整的网站内容管理功能&#xff0c;包括用户管理、内容发布、成员查询、成员申请等功能。 源码下载&#xff1a;https://download.csdn.net/download/m0_66047725/8995…

vrrp和mstp,vrrp和byd

vrrp和mstp 思路 vrrp是用来虚拟网关&#xff0c;噢&#xff0c;是虚拟一条虚拟网关 优先级&#xff0c;priority越大越优先&#xff0c;优先级相同&#xff0c;哪个的路由器的vrrp先起来&#xff0c;谁就是主 mstp是快速生成树协议&#xff0c;防止环路用的 优先级越小越优…

图说复变函数论重大错误:将无穷多各异平面误为同一面

黄小宁 医学若将前所未知的“新冠”病毒误为已熟知的流感病毒&#xff0c;后果...&#xff1b;数学将前所未知的点集误为已熟知的集就会引出一连串的重大错误。 h定理&#xff1a;点集AB的必要条件是A≌B。 证&#xff1a;&#xff08;1&#xff09;任何图≌自己是几何学最起码…

SpringBoot技术:打造新闻稿件管理平台

2相关技术 2.1 MYSQL数据库 MySQL是一个真正的多用户、多线程SQL数据库服务器。 是基于SQL的客户/服务器模式的关系数据库管理系统&#xff0c;它的有点有有功能强大、使用简单、管理方便、安全可靠性高、运行速度快、多线程、跨平台性、完全网络化、稳定性等&#xff0c;非常…

深入理解DMA(直接存储器访问)

直接存储器访问(DMA,Direct Memory Access)是一种允许外设和内存之间直接传输数据的机制,旨在提高数据传输的效率,减少CPU的负担。在传统的数据传输中,CPU负责所有的数据移动和处理,这导致CPU资源被大量占用,影响系统的整体性能。而DMA的出现,正是为了优化这一过程,使…

【Wi-Fi】WiFi中QAM及16-QAM、64-QAM、512-QAM、1024-QAM、2048-QAM、4096-QAM整理

参考链接 什么是QAM&#xff1f;QAM是如何工作的&#xff1f; - 华为 不同阶QAM调制星座图中&#xff0c;符号能量的归一化计算原理 - 知乎 16 QAM modulation vs 64 QAM modulation vs 256 QAM modulation 512 QAM vs 1024 QAM vs 2048 QAM vs 4096 QAM modulation type…

EHOME视频平台EasyCVR萤石设备视频接入平台视频诊断技术可以识别哪些视频质量问题?

EasyCVR视频监控汇聚管理平台是一款针对大中型项目设计的跨区域网络化视频监控集中管理平台。萤石设备视频接入平台EasyCVR不仅具备视频资源管理、设备管理、用户管理、运维管理和安全管理等功能&#xff0c;还支持多种主流标准协议&#xff0c;如GB28181、GB35114、RTSP/Onvif…

42python数据分析numpy基础之trace计算对角线元素的和

python的numpy库的trace()函数&#xff0c;计算对角线元素的和。 用法 numpy.trace(a, offset0, axis10, axis21, dtypeNone, outNone)描述 numpy.trace(a)&#xff0c;返回数组a的对角线元素的和。 入参 a&#xff1a;必选&#xff0c;数组&#xff0c;列表&#xff0c;元…

WPF+MVVM案例实战(二十三)- 阴影效果详解

文章目录 1、案例效果2、阴影属性参数说明3、阴影效果实现1、案例效果 2、阴影属性参数说明 WPF 中,控件的阴影效果是通过附加属性 Effect 来实现的。这里详细说明以下阴影效果的各个参数。 属性描述BlurRadius阴影模糊程度,值越大越模糊Color阴影颜色Opacity阴影透明度,默…

Vue项目开发:Vuex使用,表单验证配置,ESLint关闭与常见问题解决方案

文章目录 vuexvue配置form表单验证移除vue中表单验证的两种方法关闭vue项目的eslint代码校验做vue项目出现的问题 vuex Vue提供的状态管理工具&#xff0c;用于统一管理我们项目中各种数据的交互和重用&#xff0c;存储我们需要用到的数据对象属性 state&#xff1a;vuex的基本…

HTTP、WebSocket、gRPC 或 WebRTC:各种协议的区别

在为您的应用程序选择通信协议时&#xff0c;有很多不同的选择。 本文将了解四种流行的解决方案&#xff1a;HTTP、WebSocket、gRPC 和 WebRTC。 我们将通过深入学习其背后原理、最佳用途及其优缺点来探索每个协议。 通信方式在不断改进&#xff1a;变得更快、更方便、更可靠&…

24.11.3

星期一&#xff1a; 补24武汉高校联合程序设计新生赛 C cf传送门 最开始用倍增树链刨分&#xff0c;稳定T 思路&#xff1a;处理出树链刨分的dfn序和重链等前置信息&#xff0c;然后对每条重链开个set&#xff08;常见方法&#xff0c;用于存断开的边&…

大端存储和小端存储

大端存储和小端存储 在计算机系统中&#xff0c;数据在内存中的存储方式并不是唯一的。对于多字节的数据类型&#xff08;如 int、float 等&#xff09;&#xff0c;计算机可以以不同的方式在内存中存储它们。这些存储方式通常分为两种&#xff1a;大端存储&#xff08;Big-En…

如何使用RabbitMQ和Python实现广播消息

使用 RabbitMQ 和 Python 实现广播消息的过程涉及设置一个消息队列和多个消费者&#xff0c;以便接收相同的消息。RabbitMQ 的 “fanout” 交换机允许你将消息广播到所有绑定的队列。以下是如何实现这一过程的详细步骤。 1、问题背景 在将系统从Morbid迁移到RabbitMQ时&#x…

C#-类:成员变量

声明在类语句块中&#xff0c;描述对象的特征&#xff0c;可为任意变量类型 可包含&#xff1a;枚举、结构体、类、其他 1. 类成员的详细定义 特征->成员变量&#xff1a;包括类的数据&#xff1a;变量、常量、事件的成员行为->成员方法&#xff1a;普通方法、属性、构…

PAT甲级-1133 Splitting A Linked List

题目 题目大意 给定一个链表的首节点地址和节点个数&#xff0c;以及一个数k。要求重新排列该链表&#xff0c;使其按<0 &#xff0c;> 0 && < k&#xff0c;>k 的顺序排序。但是不改变原有顺序&#xff0c;比如-4 -> -6 -> -2&#xff0c;不需要再…

【spark的集群模式搭建】spark集群之Yarn集群模式搭建(清晰明了的搭建流程)

文章目录 1、使用Anaconda部署Python2、上传、解压、重命名3、创建软连接&#xff08;如果在Standalone模式中创建有就删除&#xff09;4、配置spark环境变量5、修改spark-env.sh配置文件6、修改spark-defaults.conf 配置文件7、修改log4j.properties配置文件8、上传spark jar包…

Android IPC机制(三)进程间通信方式

在Android中有以下几种进程间通信方式: 目录 1.Bundle 2.文件共享 3.Messenger 4.ContentProvider 5.AIDL 1.Bundle Bundle是Android中用于存储一组键值对的类&#xff0c;它实现了Parcelable接口。这使得Bundle能够在不同的进程之间传递数据。当我们通过Intent启动其他应…

GEE数据集:全球天然林和人工林数据集提供了一张高分辨率(30 米)地图,用于区分截至 2021 年全球的天然林和人工林

目录 简介 全球天然林和人工林 数据生成和分类 代码 引用 License 网址推荐 知识星球 机器学习 GEE数据集&#xff1a;全球天然林和人工林数据集提供了一张高分辨率&#xff08;30 米&#xff09;地图&#xff0c;用于区分截至 2021 年全球的天然林和人工林 简介 全球…