当前位置: 首页 > news >正文

WebGL 选中物体

目录

前言

如何实现选中物体

示例程序(PickObject.js)

代码详解 

gl.readPixels()函数规范

示例效果


前言

有些三维应用程序需要允许用户能够交互地操纵三维物体,要这样做首先就得允许用户选中某个物体。对物体进行选中操作的用处很广泛。比如,让用户选中三维用户界面上的一个按钮,或者让用户选中三维场景中的多张照片中的某一张,这些动作都具有实际意义。

选中三维物体比选中二维物体更加复杂,因为我们需要更多的数学过程来计算鼠标是否悬浮在某个图形上。但是,示例程序PickObject使用了一个简单的技巧解决了这一问题。在本例中,用户可以点击正在旋转的立方体,如果用户点击到了立方体,就显示一则消息,如下图所示。现在,请先在浏览器中运行示例程序,点击立方体试图选中它,直观地了解一下该示例程序的作用。

 

上图显示了用户点击立方体时浏览器弹出的消息。这则消息说,“The cube was selected!”(立方体被选中了!)。同样,你也可以试试在黑色背景上点击会不会弹出这则消息。 

如何实现选中物体

我们遵循以下步骤,检查鼠标点击是否击中了立方体:

1. 当鼠标左键按下时,将整个立方体重绘为单一的红色,如下图(中)所示。

2. 读取鼠标点击处的像素颜色。

3. 使用立方体原来的颜色对其进行重绘。

4. 如果第2步读取到的颜色是红色,就显示消息“The cube was selected!”。

如果不加以处理,那么当立方体被重绘为红色时,就可以看到这个立方体闪烁了一下,而且闪烁的一瞬间是红色的。然后我们读取鼠标点击处的像素在这一瞬间的颜色值,就可以通过判断该颜色是否为红色来确定鼠标是否点击在了立方体上。

鼠标点击立方体的过程

 

为了使用户看不到立方体的这一闪烁过程,我们还得在取出像素颜色之后立即(而不是等到下一帧)将立方体重绘成原来的样子。下面来看一下示例程序代码。 

示例程序(PickObject.js)

如下显示了示例程序的代码。实现上述第1步将立方体重绘为红色的过程,发生在顶点着色器中,我们向其中添加了一个u_Clicked变量(第7行),这样就可以在恰当的时候通过该变量通知顶点着色器将立方体绘制成红色。鼠标点击时,JavaScript就会向u_Click变量传入true值,然后顶点着色器经过判断(第11行),将一个固定的颜色值(1.0,0.0,0.0,1.0)即红色,赋值给v_Color变量。如果u_Click为false,那么顶点着色器就照常将立方体原来的颜色a_Color赋值给v_Color。这样一来,鼠标点击时,立方体就被绘制成红色。

// PickObject.js (c) 2012 matsuda and kanda
// Vertex shader program
var VSHADER_SOURCE ='attribute vec4 a_Position;\n' +'attribute vec4 a_Color;\n' +'uniform mat4 u_MvpMatrix;\n' +'uniform bool u_Clicked;\n' + // Mouse is pressed'varying vec4 v_Color;\n' +'void main() {\n' +'  gl_Position = u_MvpMatrix * a_Position;\n' +'  if (u_Clicked) {\n' + //  Draw in red if mouse is pressed'    v_Color = vec4(1.0, 0.0, 0.0, 1.0);\n' +'  } else {\n' +'    v_Color = a_Color;\n' +'  }\n' +'}\n';// Fragment shader program
var FSHADER_SOURCE ='#ifdef GL_ES\n' +'precision mediump float;\n' +'#endif\n' +'varying vec4 v_Color;\n' +'void main() {\n' +'  gl_FragColor = v_Color;\n' +'}\n';var ANGLE_STEP = 20.0; // Rotation angle (degrees/second)function main() {// Retrieve <canvas> elementvar canvas = document.getElementById('webgl');// Get the rendering context for WebGLvar gl = getWebGLContext(canvas);if (!gl) {console.log('Failed to get the rendering context for WebGL');return;}// Initialize shadersif (!initShaders(gl, VSHADER_SOURCE, FSHADER_SOURCE)) {console.log('Failed to intialize shaders.');return;}// Set the vertex informationvar n = initVertexBuffers(gl);if (n < 0) {console.log('Failed to set the vertex information');return;}// Set the clear color and enable the depth testgl.clearColor(0.0, 0.0, 0.0, 1.0);gl.enable(gl.DEPTH_TEST);// Get the storage locations of uniform variablesvar u_MvpMatrix = gl.getUniformLocation(gl.program, 'u_MvpMatrix');var u_Clicked = gl.getUniformLocation(gl.program, 'u_Clicked');if (!u_MvpMatrix || !u_Clicked) { console.log('Failed to get the storage location of uniform variable');return;}// Calculate the view projection matrixvar viewProjMatrix = new Matrix4();viewProjMatrix.setPerspective(30.0, canvas.width / canvas.height, 1.0, 100.0);viewProjMatrix.lookAt(0.0, 0.0, 7.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0);gl.uniform1i(u_Clicked, 0); // Pass false to u_Clickedvar currentAngle = 0.0; // Current rotation angle// Register the event handlercanvas.onmousedown = function(ev) {   // Mouse is pressedvar x = ev.clientX, y = ev.clientY;var rect = ev.target.getBoundingClientRect();if (rect.left <= x && x < rect.right && rect.top <= y && y < rect.bottom) {// If pressed position is inside <canvas>, check if it is above objectvar x_in_canvas = x - rect.left, y_in_canvas = rect.bottom - y;var picked = check(gl, n, x_in_canvas, y_in_canvas, currentAngle, u_Clicked, viewProjMatrix, u_MvpMatrix);if (picked) alert('The cube was selected! ');}}var tick = function() {   // Start drawingcurrentAngle = animate(currentAngle);draw(gl, n, currentAngle, viewProjMatrix, u_MvpMatrix);requestAnimationFrame(tick, canvas);};tick();
}function initVertexBuffers(gl) {// Create a cube//    v6----- v5//   /|      /|//  v1------v0|//  | |     | |//  | |v7---|-|v4//  |/      |///  v2------v3var vertices = new Float32Array([   // Vertex coordinates1.0, 1.0, 1.0,  -1.0, 1.0, 1.0,  -1.0,-1.0, 1.0,   1.0,-1.0, 1.0,    // v0-v1-v2-v3 front1.0, 1.0, 1.0,   1.0,-1.0, 1.0,   1.0,-1.0,-1.0,   1.0, 1.0,-1.0,    // v0-v3-v4-v5 right1.0, 1.0, 1.0,   1.0, 1.0,-1.0,  -1.0, 1.0,-1.0,  -1.0, 1.0, 1.0,    // v0-v5-v6-v1 up-1.0, 1.0, 1.0,  -1.0, 1.0,-1.0,  -1.0,-1.0,-1.0,  -1.0,-1.0, 1.0,    // v1-v6-v7-v2 left-1.0,-1.0,-1.0,   1.0,-1.0,-1.0,   1.0,-1.0, 1.0,  -1.0,-1.0, 1.0,    // v7-v4-v3-v2 down1.0,-1.0,-1.0,  -1.0,-1.0,-1.0,  -1.0, 1.0,-1.0,   1.0, 1.0,-1.0     // v4-v7-v6-v5 back]);var colors = new Float32Array([   // Colors0.2, 0.58, 0.82,   0.2, 0.58, 0.82,   0.2,  0.58, 0.82,  0.2,  0.58, 0.82, // v0-v1-v2-v3 front0.5,  0.41, 0.69,  0.5, 0.41, 0.69,   0.5, 0.41, 0.69,   0.5, 0.41, 0.69,  // v0-v3-v4-v5 right0.0,  0.32, 0.61,  0.0, 0.32, 0.61,   0.0, 0.32, 0.61,   0.0, 0.32, 0.61,  // v0-v5-v6-v1 up0.78, 0.69, 0.84,  0.78, 0.69, 0.84,  0.78, 0.69, 0.84,  0.78, 0.69, 0.84, // v1-v6-v7-v2 left0.32, 0.18, 0.56,  0.32, 0.18, 0.56,  0.32, 0.18, 0.56,  0.32, 0.18, 0.56, // v7-v4-v3-v2 down0.73, 0.82, 0.93,  0.73, 0.82, 0.93,  0.73, 0.82, 0.93,  0.73, 0.82, 0.93, // v4-v7-v6-v5 back]);// Indices of the verticesvar indices = new Uint8Array([0, 1, 2,   0, 2, 3,    // front4, 5, 6,   4, 6, 7,    // right8, 9,10,   8,10,11,    // up12,13,14,  12,14,15,    // left16,17,18,  16,18,19,    // down20,21,22,  20,22,23     // back]);// Write vertex information to buffer objectif (!initArrayBuffer(gl, vertices, gl.FLOAT, 3, 'a_Position')) return -1; // Coordinate Informationif (!initArrayBuffer(gl, colors, gl.FLOAT, 3, 'a_Color')) return -1;      // Color Information// Create a buffer objectvar indexBuffer = gl.createBuffer();if (!indexBuffer) {return -1;}// Write the indices to the buffer objectgl.bindBuffer(gl.ELEMENT_ARRAY_BUFFER, indexBuffer);gl.bufferData(gl.ELEMENT_ARRAY_BUFFER, indices, gl.STATIC_DRAW);return indices.length;
}function check(gl, n, x, y, currentAngle, u_Clicked, viewProjMatrix, u_MvpMatrix) {var picked = false;gl.uniform1i(u_Clicked, 1);  // Pass true to u_Clickeddraw(gl, n, currentAngle, viewProjMatrix, u_MvpMatrix); // Draw cube with red// Read pixel at the clicked positionvar pixels = new Uint8Array(4); // Array for storing the pixel valuegl.readPixels(x, y, 1, 1, gl.RGBA, gl.UNSIGNED_BYTE, pixels);if (pixels[0] == 255) // The mouse in on cube if R(pixels[0]) is 255picked = true;gl.uniform1i(u_Clicked, 0);  // Pass false to u_Clicked(rewrite the cube)draw(gl, n, currentAngle, viewProjMatrix, u_MvpMatrix); // Draw the cubereturn picked;
}var g_MvpMatrix = new Matrix4(); // Model view projection matrix
function draw(gl, n, currentAngle, viewProjMatrix, u_MvpMatrix) {// Caliculate The model view projection matrix and pass it to u_MvpMatrixg_MvpMatrix.set(viewProjMatrix);g_MvpMatrix.rotate(currentAngle, 1.0, 0.0, 0.0); // Rotate appropriatelyg_MvpMatrix.rotate(currentAngle, 0.0, 1.0, 0.0);g_MvpMatrix.rotate(currentAngle, 0.0, 0.0, 1.0);gl.uniformMatrix4fv(u_MvpMatrix, false, g_MvpMatrix.elements);gl.clear(gl.COLOR_BUFFER_BIT | gl.DEPTH_BUFFER_BIT);     // Clear buffersgl.drawElements(gl.TRIANGLES, n, gl.UNSIGNED_BYTE, 0);   // Draw
}var last = Date.now(); // Last time that this function was called
function animate(angle) {var now = Date.now();   // Calculate the elapsed timevar elapsed = now - last;last = now;// Update the current rotation angle (adjusted by the elapsed time)var newAngle = angle + (ANGLE_STEP * elapsed) / 1000.0;return newAngle % 360;
}function initArrayBuffer (gl, data, type, num, attribute) {// Create a buffer objectvar buffer = gl.createBuffer();if (!buffer) {console.log('Failed to create the buffer object');return false;}// Write date into the buffer objectgl.bindBuffer(gl.ARRAY_BUFFER, buffer);gl.bufferData(gl.ARRAY_BUFFER, data, gl.STATIC_DRAW);// Assign the buffer object to the attribute variablevar a_attribute = gl.getAttribLocation(gl.program, attribute);if (a_attribute < 0) {console.log('Failed to get the storage location of ' + attribute);return false;}gl.vertexAttribPointer(a_attribute, num, type, false, 0, 0);// Enable the assignment to a_attribute variablegl.enableVertexAttribArray(a_attribute);return true;
}

代码详解 

在main()函数中(第30行),我们获取了u_Click变量的存储地址,并将初始值false值传给该变量(第71行)。

然后,注册事件响应函数,用户点击鼠标后立即调用之(第75行)。事件响应函数首先检查鼠标点击位置是否在<canvas>内(第78行)。如果是,则调用check()函数(第81行)。check()函数的作用是,根据第3个和第4个参数传入的点击位置坐标,判断是否点击在立方体上。如果是,则返回true,并显示消息(第82行)。

check()函数执行上述的第2步和第3步(第147行):首先将true传给顶点着色器的u_Click变量,以通知顶点着色器鼠标被点击了(第149行);然后根据立方体的当前旋转角度重绘立方体,由于此时u_Click为true,所以立方体是红色的;接着调用gl.readPixels()函数从颜色缓冲区中读取点击处的像素颜色(第153行)。下面是该函数的规范。

gl.readPixels()函数规范

读取到的像素颜色值被保存在pixels数组中,它是一个长度为4的数组(第152行),4个元素pixels[0]、pixels[1]、pixels[2]、pixels[3]分别存储了像素的R、G、B、A的值。本例只需要读取一个像素,所以width和height参数都是1,根据这个像素是红色还是黑色,就可以判断出鼠标点击在了立方体上还是背景上。我们检查红色分量pixels[0],如果是1.0,就将picked变量赋值为true。

然后,将u_Click变量恢复为false(第158行),重新绘制立方体为原始的颜色(第159行)。最后将picked变量返回,check()函数就结束了。

注意,如果在重绘正常状态的立方体之前,就进行某个会阻塞代码继续运行的操作,如调用alert()函数,那么这时,已经写入颜色缓冲区中的内容就会显示在<canvas>上。比如,如果我们在第156行执行(实际上我们并没有这么做)alert('The cube was displayed!'),那就真的会看到之前绘制的红色立方体了。

对于具有多个物体的场景,这个简单的方法也能适用,只需要为场景中的每个物体都指定不同的颜色即可。比如场景中有三个物体,那么就可以使用红色、绿色和蓝色三种颜色。如果场景中有更多的物体,那么你可以为每个物体分配一个唯一的颜色值。通常,颜色缓冲区单个像素R、G、B、A每个分量都是8比特,也就是说,仅使用R分量就可以区分255个物体。

示例效果

相关文章:

WebGL 选中物体

目录 前言 如何实现选中物体 示例程序&#xff08;PickObject.js&#xff09; 代码详解 gl.readPixels&#xff08;&#xff09;函数规范 示例效果 前言 有些三维应用程序需要允许用户能够交互地操纵三维物体&#xff0c;要这样做首先就得允许用户选中某个物体。对物体…...

科目二倒车入库

调整座位和后视镜 离合踩到底大腿小腿成130-140 上半身90-100 座椅高度能看到前方全部情况 后视镜调节到能看到后门把手&#xff0c;且后门把手刚好在后视镜上方边缘、离车1/3处。 保持直线&#xff1a; 前进&#xff1a; 车仪表盘中央的原点和地面上的黄线擦边&#xff…...

PostgreSQL如何支持PL/Python过程语言

瀚高数据库 目录 环境 文档用途 详细信息 环境 系统平台&#xff1a;Linux x86-64 Red Hat Enterprise Linux 7 版本&#xff1a;10.4 文档用途 本文档主要介绍PostgreSQL如何支持PL/Python过程语言&#xff0c;如何创建plpython扩展。 详细信息 一、PostgreSQL支持python语言…...

【C++】STL之适配器---用deque实现栈和队列

目录 前言 一、deque 1、deque 的原理介绍 2、deque 的底层结构 3、deque 的迭代器 4、deque 的优缺点 4.1、优点 4.2、缺点 二、stack 的介绍和使用 1、stack 的介绍 2、stack 的使用 3、stack 的模拟实现 三、queue 的介绍和使用 1、queue 的介绍 2、queue 的使用 3、qu…...

PHY6230低成本遥控灯控芯片国产蓝牙BLE5.2 2.4G SoC

高性价比的低功耗高性能蓝牙5.2系统级芯片&#xff0c;适用多种PC/手机外设连接场景。 高性能多模射频收发机&#xff1a; 通过硬件模块的充分复用实现高性能多模数字收发机。发射机&#xff0c;最大发射功率10dBm&#xff1b;BLE 1Mbps速率接收机灵敏度达到-96dBm&#xff1…...

OceanBase杨传辉传递亚运火炬:国产数据库为“智能亚运”提供稳稳支持

9 月 14 日&#xff0c;亚运火炬传递到了浙江台州&#xff0c;OceanBase 的 CTO 杨传辉作为火炬手交接了第 89 棒火炬。 2010 年&#xff0c;杨传辉作为创始成员之一参与自研原生分布式数据库 OceanBase。十年磨一剑&#xff0c;国产数据库 OceanBase 交出了一张优秀的成绩单&a…...

分布式锁实现方法

分布式锁 什么时候需要加锁 有并发&#xff0c;多线程有写操作有竞争关系 场景&#xff1a; 电商系统&#xff0c;下单流程&#xff1a;用户下单–>秒杀系统检查redis商品库存信息–>用户锁定并更新库存&#xff08;mysql&#xff09;—>秒杀系统更新redis 问题&…...

软件测试缺陷报告详解

【软件测试行业现状】2023年了你还敢学软件测试&#xff1f;未来已寄..测试人该何去何从&#xff1f;【自动化测试、测试开发、性能测试】 缺陷报告是描述软件缺陷现象和重现步骤地集合。软件缺陷报告Software Bug Report&#xff08;SBR&#xff09;或软件问题报告Software Pr…...

pytorch冻结参数训练的坑

由于项目需要训练一个主干网络接多个分支的模型&#xff0c;所以先训练一个主干网络加第一个分支&#xff0c;再用另外的数据训练第二个分支&#xff0c;训练的过程中需要冻结主干网络部分&#xff0c;后面的分支训练过程也一样需要冻结主干网络部分。 冻结模型的方式 for nam…...

P1827 [USACO3.4] 美国血统 American Heritage(前序 + 中序 生成后序)

P1827 [USACO3.4] 美国血统 American Heritage&#xff08;前序 中序 生成后序&#xff09; 一、前言 二叉树入门题。涉及到树的基本知识、树的结构、树的生成。 本文从会从结构&#xff0c;到完成到&#xff0c;优化。 二、基础知识 Ⅰ、二叉树的遍历 前序遍历&#xff…...

【四、centOS安装docker】

安装docker sudo yum install -y yum-utils device-mapper-persistent-data lvm2 如果以上报错 备份系统自带yum源配置文件 mv /etc/yum.repos.d/CentOS-Base.repo /etc/yum.repos.d/CentOS-Base.repo.backup进入 /etc/yum.repos.d cd /etc/yum.repos.d删除文件 rm -f *.r…...

想学嵌入式开发,薪资怎么样?

想学嵌入式开发&#xff0c;薪资怎么样&#xff1f; 对于嵌入式工程师来说呢&#xff0c;它重点学习内容就是首先一定要打好基础&#xff0c;如果从编程语言角度来讲&#xff0c;那么可以在语言上选C或者C&#xff0c;你可以选择其中任何一门语言作为你的入门。 最近很多小伙伴…...

SQL死锁进程内容查询语句

1.方式1 SELECT object_name(A.resource_associated_entity_id) as TABLENAME, A.request_session_id AS SPID,DB_NAME(B.dbid) AS DBName,B.blocked,B.dbid,B.program_name,B.waitresource,B.lastwaittype,B.loginame,B.hostname,B.login_time,B.last_batch--,B.* FROM sy…...

Ubuntu 20.04中Nightingale二进制部署

参考博客《【夜莺监控】初识夜莺&#xff0c;强&#xff01;》 lsb_release -r可以看到操作系统版本是20.04&#xff0c;uname -r可以看到内核版本是5.5.19。 sudo apt-get update进行更新镜像源。 完成之后&#xff0c;如下图&#xff1a; sudo apt-get upgrade更新软件…...

深入探讨Java面试中内存泄漏:如何识别、预防和解决

引言 在编写和维护Java应用程序时&#xff0c;内存泄漏是一个重要的问题&#xff0c;可能导致性能下降和不稳定性。本文将介绍内存泄漏的概念&#xff0c;为什么它在Java应用程序中如此重要&#xff0c;并明确本文的目标&#xff0c;即识别、预防和解决内存泄漏问题。 内存泄…...

win10 安装.net framework 3.5,错误代码0x8024401C

win10 安装.net framework 3.5&#xff0c;错误代码0x8024401C 参考链接&#xff1a;https://www.gxlsystem.com/diannaowenti-386775.html 解决方法如下&#xff0c;cmd中执行&#xff1a; net stop wuauserv reg delete HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\W…...

杂记 | Langchain中few-shot提示词模板的使用(给提示词添加示例)

文章目录 01 普通的提示词模板02 few-shot提示词模板 Langchain是一个集成多个大语言模型的开源框架&#xff0c;可以使用它来快速开发大语言模型应用。 本文的代码使用到的模块&#xff1a; from typing import List, Dict from langchain import PromptTemplate, FewShotPr…...

SVN -基础

SVN - 基础 概念操作步骤开发实际经验 概念 带SVN路径 有隐藏文件&#xff0c;记录repo的一些信息&#xff0c;与repo进行关联&#xff0c;可以与repo进行同步 不带SVN路径 只是单纯的文件&#xff0c;与repo独立 操作步骤 checkout 具有路径 URLcheckout dir 输出目标文件夹…...

MySQL基础终端命令与Python简单操作MySQL

文章目录 MySQL终端命令1. 进入mysql2. 创建数据库3. 选择数据库4. 创建数据表1. 主键约束2. 外键约束3. 非空约束4. 唯一约束5. 使用默认约束6. 设置id为自增列 5. 查看数据表6. 修改数据表1. 修改表名2. 修改表的字段类型3. 修改表的字段名4. 为表添加字段5. 删除字段6. 调整…...

编译原理.龙书学习1

第一章&#xff1a; 编译器&#xff1a;将程序翻译成一种能够被计算机执行的形式 解释器&#xff1a;解释器直接利用用户提供的输入执行源程序中指定的操作 一个编译器的结构 编译器将源程序映射为语义上等价的目标程序&#xff0c;这个映射过程由两部分组成&#xff1a;分析…...

anaconda安装完成之后输入conda -V没有反应

anaconda安装完成后&#xff0c;conda没有反应 vim ~/.bashrc后面添加内容 # added by Anaconda3 5.3.0 installer # >>> conda init >>> # !! Contents within this block are managed by conda init !! __conda_setup"$(CONDA_REPORT_ERRORSfalse /u…...

netty报文解析之粘包半包问题

粘包问题 Netty 的粘包问题是指在网络传输过程中&#xff0c;由于 TCP 协议本身的特点&#xff0c;导致发送方发送的若干个小数据包被接收方合并成了一个大数据包。这种情况称为粘包。 TCP 协议是面向流的协议&#xff0c;没有数据边界&#xff0c;发送方发送的数据可能会被分…...

EasyCode整合mybatis-plus的配置

文章目录 entitymapper.javamapper.xmlserviceserviceImplcontroller 这篇文章不教你如何安装和使用EasyCode&#xff0c;只是贴出可以使用的配置。 具体EasyCode的使用可以查看其它的文章。 entity ##导入宏定义 $!{define.vm}##保存文件&#xff08;宏定义&#xff09; #sa…...

实施预测性维护解决方案的挑战及PreMaint的应对方法

前面我们介绍了企业选择预测性维护解决方案的常见问题和PreMaint的策略&#xff0c;本期我们将带来实施过程中可能会遇到的挑战&#xff0c;以及如何通过PreMaint来应对这些挑战&#xff0c;以实现可靠的预测性维护。 随着工业技术的不断进步&#xff0c;预测性维护作为一种先进…...

1. js中let、var、const定义变量区别与方式

1 声明语法 var upperA A; let upperB B; const upperC C; 只声明不初始化的结果&#xff0c;【 const定义的常量不可以修改&#xff0c;而且必须初始化】 // var 声明变量 var upperA; console.log(打印大写的A&#xff1a;%s, upperA); // 结果&#xff1a;打印大写的A&am…...

【STM32学习】I2C通信协议 | OLED屏

&#x1f431;作者&#xff1a;一只大喵咪1201 &#x1f431;专栏&#xff1a;《STM32学习》 &#x1f525;格言&#xff1a;你只管努力&#xff0c;剩下的交给时间&#xff01; 今天需要将代码烧录到开发板中&#xff0c;本喵默认大家都会创建工程&#xff0c;以及进行基本的…...

Nvme Spec 第一章节学习

Nvme Express Base Specification 第一章 简介 1.1概述 NVM ExpressTM&#xff08;NVMeTM&#xff09;接口允许主机软件与非易失性存储器子系统通信。 此接口针对企业和客户端固态驱动器进行了优化&#xff0c;通常作为寄存器级接口连接到PCI Express接口。 注&#xff1a;在…...

第一章:最新版零基础学习 PYTHON 教程(第九节 - Python 语句中的 – 多行语句)

Python 中的语句: 在Python中,语句是Python解释器可以读取和执行的逻辑命令。它可能是Python 中的赋值语句或表达式。 Python 中的多行语句: 在Python中,语句通常写成一行,每行的最后一个字符是换行符。要将语句扩展到一行或多行,我们可以使用大括号 {}、圆括号 ()、方…...

kafka 3.0 离线安装

1.安装zookeeper 解压apache-zookeeper-3.8.0-bin.tar.gz到指定目录,复制conf目录下zoo_sample.cfg到zoo.cfg,并修改配置。 # The number of milliseconds of each tick tickTime=2000 # The number of ticks that the initial # synchronization phase can take initLimit…...

MySQL数据库入门到精通2--基础篇(函数,约束,多表查询,事务)

3. 函数 函数 是指一段可以直接被另一段程序调用的程序或代码。MySQL中的函数主要分为以下四类&#xff1a; 字符串函数、数值函数、日期函数、流程函数。 3.1 字符串函数 MySQL中内置了很多字符串函数&#xff0c;常用的几个如下&#xff1a; 演示如下&#xff1a; A. con…...

巢湖做网站/企业管理培训

Object Relational Mapping(ORM) ORM介绍 ORM概念 对象关系映射&#xff08;Object Relational Mapping&#xff0c;简称ORM&#xff09;模式是一种为了解决面向对象与关系数据库存在的互不匹配的现象的技术。 简单的说&#xff0c;ORM是通过使用描述对象和数据库之间映射的元数…...

邯郸移动网站制作/麒麟seo

2019独角兽企业重金招聘Python工程师标准>>> CentOS下用于查看系统当前登录用户信息的4种方法 2015年07月24日 17:09:09 slovyz 阅读数&#xff1a;5865更多 个人分类&#xff1a; centos 1. 使用w命令查看登录用户正在使用的进程信息 w命令用于显示已经登录系统的用…...

织梦门户网站模板/关键词优化公司哪家好

调结者的执行actionStrutsExecuteFilter类的工作就是执行对应的action请求。StrutsExecuteFilter类的工作还需要有一个叫ExecuteOperations类的帮助。如果看过源码的朋友都知道&#xff0c;StrutsExecuteFilter类的代码里用了ExecuteOperations类的俩个方法。一个是&#xff1a…...

医院咨询男科/seo推广软

我有个有趣的观察&#xff0c;外企公司多的是25-35岁的白领&#xff0c;40岁以上的员工很少&#xff0c;二三十岁的外企员工是意气风发的&#xff0c;但外企公司40岁附近的经理人是很尴尬的。我见过的40岁附近的外企经理人大多在一直跳槽&#xff0c;最后大多跳到民企&#xff…...

长沙个人做网站/百度识图扫一扫

作者&#xff1a;桂。 链接&#xff1a;http://www.cnblogs.com/xingshansi/articles/6291358.html 声明&#xff1a;转载请注明出处&#xff0c;谢谢。 前言 工欲善其事&#xff0c;必先利其器。在信息爆炸的今天&#xff0c;如何快速有效搜索期望的信息&#xff0c;成了困扰…...

网站建化/口碑营销的特点

统计字符数原文转自&#xff1a;http://blog.sina.com.cn/s/blog_5f1a42440100r2pp.htmlTime Limit:1000MSMemory Limit:65536KTotal Submit:345 Accepted:133Description判断一个由a~z这26个字符组成的字符串中哪个字符出现的次数最多。Input第一行是测试数据的组数n&#xff…...