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

工程化与框架系列(26)--前端可视化开发

前端可视化开发 📊

引言

前端可视化是现代Web应用中不可或缺的一部分,它能够以直观的方式展示复杂的数据和信息。本文将深入探讨前端可视化开发的关键技术和最佳实践,包括图表绘制、数据处理、动画效果等方面。

可视化技术概述

前端可视化主要包括以下技术方向:

  • Canvas绘图:像素级别的图形绘制
  • SVG矢量图:可缩放的矢量图形
  • WebGL 3D:三维图形渲染
  • 可视化库:ECharts、D3.js等
  • 地理信息:地图可视化

Canvas图形绘制

基础绘图API

// Canvas绘图管理器
class CanvasRenderer {private canvas: HTMLCanvasElement;private ctx: CanvasRenderingContext2D;constructor(canvas: HTMLCanvasElement) {this.canvas = canvas;this.ctx = canvas.getContext('2d')!;this.initializeCanvas();}// 初始化画布private initializeCanvas(): void {// 设置画布尺寸为显示尺寸的2倍,提高清晰度const displayWidth = this.canvas.clientWidth;const displayHeight = this.canvas.clientHeight;this.canvas.width = displayWidth * 2;this.canvas.height = displayHeight * 2;// 缩放上下文以匹配显示尺寸this.ctx.scale(2, 2);// 设置默认样式this.ctx.lineWidth = 2;this.ctx.strokeStyle = '#333';this.ctx.fillStyle = '#666';}// 清空画布clear(): void {this.ctx.clearRect(0, 0, this.canvas.width, this.canvas.height);}// 绘制直线drawLine(startX: number,startY: number,endX: number,endY: number,options: LineOptions = {}): void {this.ctx.save();// 应用样式选项if (options.color) this.ctx.strokeStyle = options.color;if (options.width) this.ctx.lineWidth = options.width;if (options.dash) this.ctx.setLineDash(options.dash);// 绘制路径this.ctx.beginPath();this.ctx.moveTo(startX, startY);this.ctx.lineTo(endX, endY);this.ctx.stroke();this.ctx.restore();}// 绘制矩形drawRect(x: number,y: number,width: number,height: number,options: ShapeOptions = {}): void {this.ctx.save();// 应用样式选项if (options.fillColor) this.ctx.fillStyle = options.fillColor;if (options.strokeColor) this.ctx.strokeStyle = options.strokeColor;if (options.lineWidth) this.ctx.lineWidth = options.lineWidth;// 绘制矩形if (options.fillColor) {this.ctx.fillRect(x, y, width, height);}if (options.strokeColor) {this.ctx.strokeRect(x, y, width, height);}this.ctx.restore();}// 绘制圆形drawCircle(x: number,y: number,radius: number,options: ShapeOptions = {}): void {this.ctx.save();// 应用样式选项if (options.fillColor) this.ctx.fillStyle = options.fillColor;if (options.strokeColor) this.ctx.strokeStyle = options.strokeColor;if (options.lineWidth) this.ctx.lineWidth = options.lineWidth;// 绘制圆形this.ctx.beginPath();this.ctx.arc(x, y, radius, 0, Math.PI * 2);if (options.fillColor) {this.ctx.fill();}if (options.strokeColor) {this.ctx.stroke();}this.ctx.restore();}// 绘制文本drawText(text: string,x: number,y: number,options: TextOptions = {}): void {this.ctx.save();// 应用样式选项if (options.font) this.ctx.font = options.font;if (options.color) this.ctx.fillStyle = options.color;if (options.align) this.ctx.textAlign = options.align;if (options.baseline) this.ctx.textBaseline = options.baseline;// 绘制文本this.ctx.fillText(text, x, y);this.ctx.restore();}
}// 绘图选项接口
interface LineOptions {color?: string;width?: number;dash?: number[];
}interface ShapeOptions {fillColor?: string;strokeColor?: string;lineWidth?: number;
}interface TextOptions {font?: string;color?: string;align?: CanvasTextAlign;baseline?: CanvasTextBaseline;
}// 使用示例
const canvas = document.getElementById('canvas') as HTMLCanvasElement;
const renderer = new CanvasRenderer(canvas);// 绘制图形
renderer.drawRect(50, 50, 100, 80, {fillColor: '#f0f0f0',strokeColor: '#333'
});renderer.drawCircle(200, 100, 40, {fillColor: '#1890ff'
});renderer.drawLine(50, 200, 250, 200, {color: '#666',width: 2,dash: [5, 5]
});renderer.drawText('Hello Canvas', 100, 250, {font: '20px Arial',color: '#333',align: 'center'
});

动画实现

// 动画管理器
class AnimationManager {private animations: Animation[];private isRunning: boolean;private lastTime: number;constructor() {this.animations = [];this.isRunning = false;this.lastTime = 0;this.animate = this.animate.bind(this);}// 添加动画addAnimation(animation: Animation): void {this.animations.push(animation);if (!this.isRunning) {this.start();}}// 移除动画removeAnimation(animation: Animation): void {const index = this.animations.indexOf(animation);if (index !== -1) {this.animations.splice(index, 1);}if (this.animations.length === 0) {this.stop();}}// 启动动画循环private start(): void {this.isRunning = true;this.lastTime = performance.now();requestAnimationFrame(this.animate);}// 停止动画循环private stop(): void {this.isRunning = false;}// 动画循环private animate(currentTime: number): void {if (!this.isRunning) return;// 计算时间增量const deltaTime = currentTime - this.lastTime;this.lastTime = currentTime;// 更新所有动画this.animations.forEach(animation => {animation.update(deltaTime);});// 继续动画循环requestAnimationFrame(this.animate);}
}// 动画基类
abstract class Animation {protected duration: number;protected elapsed: number;protected isComplete: boolean;constructor(duration: number) {this.duration = duration;this.elapsed = 0;this.isComplete = false;}// 更新动画状态update(deltaTime: number): void {if (this.isComplete) return;this.elapsed += deltaTime;if (this.elapsed >= this.duration) {this.elapsed = this.duration;this.isComplete = true;}const progress = this.elapsed / this.duration;this.onUpdate(this.easeInOut(progress));}// 缓动函数protected easeInOut(t: number): number {return t < 0.5? 2 * t * t: -1 + (4 - 2 * t) * t;}// 动画更新回调protected abstract onUpdate(progress: number): void;
}// 圆形动画示例
class CircleAnimation extends Animation {private renderer: CanvasRenderer;private startRadius: number;private endRadius: number;private x: number;private y: number;constructor(renderer: CanvasRenderer,x: number,y: number,startRadius: number,endRadius: number,duration: number) {super(duration);this.renderer = renderer;this.x = x;this.y = y;this.startRadius = startRadius;this.endRadius = endRadius;}protected onUpdate(progress: number): void {const currentRadius = this.startRadius + (this.endRadius - this.startRadius) * progress;this.renderer.clear();this.renderer.drawCircle(this.x, this.y, currentRadius, {fillColor: '#1890ff'});}
}// 使用示例
const canvas = document.getElementById('canvas') as HTMLCanvasElement;
const renderer = new CanvasRenderer(canvas);
const animationManager = new AnimationManager();// 创建并添加动画
const circleAnimation = new CircleAnimation(renderer,200,200,0,100,1000 // 1秒
);animationManager.addAnimation(circleAnimation);

SVG图形绘制

SVG基础组件

// SVG渲染器
class SVGRenderer {private svg: SVGSVGElement;constructor(container: HTMLElement, width: number, height: number) {this.svg = document.createElementNS('http://www.w3.org/2000/svg', 'svg');this.svg.setAttribute('width', width.toString());this.svg.setAttribute('height', height.toString());this.svg.setAttribute('viewBox', `0 0 ${width} ${height}`);container.appendChild(this.svg);}// 创建矩形createRect(x: number,y: number,width: number,height: number,options: SVGShapeOptions = {}): SVGRectElement {const rect = document.createElementNS('http://www.w3.org/2000/svg', 'rect');rect.setAttribute('x', x.toString());rect.setAttribute('y', y.toString());rect.setAttribute('width', width.toString());rect.setAttribute('height', height.toString());this.applyShapeOptions(rect, options);this.svg.appendChild(rect);return rect;}// 创建圆形createCircle(cx: number,cy: number,r: number,options: SVGShapeOptions = {}): SVGCircleElement {const circle = document.createElementNS('http://www.w3.org/2000/svg', 'circle');circle.setAttribute('cx', cx.toString());circle.setAttribute('cy', cy.toString());circle.setAttribute('r', r.toString());this.applyShapeOptions(circle, options);this.svg.appendChild(circle);return circle;}// 创建路径createPath(d: string,options: SVGShapeOptions = {}): SVGPathElement {const path = document.createElementNS('http://www.w3.org/2000/svg', 'path');path.setAttribute('d', d);this.applyShapeOptions(path, options);this.svg.appendChild(path);return path;}// 创建文本createText(x: number,y: number,text: string,options: SVGTextOptions = {}): SVGTextElement {const textElement = document.createElementNS('http://www.w3.org/2000/svg', 'text');textElement.setAttribute('x', x.toString());textElement.setAttribute('y', y.toString());textElement.textContent = text;if (options.fontSize) {textElement.style.fontSize = options.fontSize;}if (options.fontFamily) {textElement.style.fontFamily = options.fontFamily;}if (options.fill) {textElement.setAttribute('fill', options.fill);}if (options.textAnchor) {textElement.setAttribute('text-anchor', options.textAnchor);}this.svg.appendChild(textElement);return textElement;}// 应用形状样式选项private applyShapeOptions(element: SVGElement,options: SVGShapeOptions): void {if (options.fill) {element.setAttribute('fill', options.fill);}if (options.stroke) {element.setAttribute('stroke', options.stroke);}if (options.strokeWidth) {element.setAttribute('stroke-width', options.strokeWidth.toString());}if (options.opacity) {element.setAttribute('opacity', options.opacity.toString());}}
}// SVG样式选项接口
interface SVGShapeOptions {fill?: string;stroke?: string;strokeWidth?: number;opacity?: number;
}interface SVGTextOptions {fontSize?: string;fontFamily?: string;fill?: string;textAnchor?: 'start' | 'middle' | 'end';
}// 使用示例
const container = document.getElementById('container')!;
const renderer = new SVGRenderer(container, 400, 300);// 创建各种SVG图形
renderer.createRect(50, 50, 100, 80, {fill: '#f0f0f0',stroke: '#333',strokeWidth: 2
});renderer.createCircle(200, 100, 40, {fill: '#1890ff',opacity: 0.8
});renderer.createPath('M100,100 L200,100 L150,50 Z', {fill: '#666',stroke: '#333',strokeWidth: 1
});renderer.createText(150, 200, 'Hello SVG', {fontSize: '20px',fontFamily: 'Arial',fill: '#333',textAnchor: 'middle'
});

数据可视化实现

柱状图实现

// 柱状图渲染器
class BarChart {private svg: SVGRenderer;private width: number;private height: number;private padding: number;constructor(container: HTMLElement,width: number,height: number,padding: number = 40) {this.width = width;this.height = height;this.padding = padding;this.svg = new SVGRenderer(container, width, height);}// 渲染柱状图render(data: BarData[]): void {// 计算坐标轴范围const maxValue = Math.max(...data.map(d => d.value));const chartWidth = this.width - 2 * this.padding;const chartHeight = this.height - 2 * this.padding;const barWidth = chartWidth / data.length * 0.8;const barGap = chartWidth / data.length * 0.2;// 绘制坐标轴this.drawAxis(chartWidth, chartHeight, maxValue);// 绘制柱子data.forEach((item, index) => {const x = this.padding + index * (barWidth + barGap);const barHeight = (item.value / maxValue) * chartHeight;const y = this.height - this.padding - barHeight;// 绘制柱子this.svg.createRect(x, y, barWidth, barHeight, {fill: item.color || '#1890ff',opacity: 0.8});// 绘制标签this.svg.createText(x + barWidth / 2,this.height - this.padding + 20,item.label,{fontSize: '12px',textAnchor: 'middle'});// 绘制数值this.svg.createText(x + barWidth / 2,y - 5,item.value.toString(),{fontSize: '12px',textAnchor: 'middle'});});}// 绘制坐标轴private drawAxis(chartWidth: number,chartHeight: number,maxValue: number): void {// X轴this.svg.createPath(`M${this.padding},${this.height - this.padding} ` +`L${this.width - this.padding},${this.height - this.padding}`,{stroke: '#666',strokeWidth: 1});// Y轴this.svg.createPath(`M${this.padding},${this.padding} ` +`L${this.padding},${this.height - this.padding}`,{stroke: '#666',strokeWidth: 1});// Y轴刻度const tickCount = 5;for (let i = 0; i <= tickCount; i++) {const y = this.height - this.padding - (i / tickCount) * chartHeight;const value = Math.round(maxValue * (i / tickCount));// 刻度线this.svg.createPath(`M${this.padding - 5},${y} L${this.padding},${y}`,{stroke: '#666',strokeWidth: 1});// 刻度值this.svg.createText(this.padding - 10,y,value.toString(),{fontSize: '12px',textAnchor: 'end'});}}
}// 数据接口
interface BarData {label: string;value: number;color?: string;
}// 使用示例
const container = document.getElementById('chart-container')!;
const chart = new BarChart(container, 600, 400);const data: BarData[] = [{ label: '一月', value: 120, color: '#1890ff' },{ label: '二月', value: 200, color: '#2fc25b' },{ label: '三月', value: 150, color: '#facc14' },{ label: '四月', value: 180, color: '#223273' },{ label: '五月', value: 240, color: '#8543e0' }
];chart.render(data);

饼图实现

// 饼图渲染器
class PieChart {private svg: SVGRenderer;private width: number;private height: number;private radius: number;constructor(container: HTMLElement,width: number,height: number) {this.width = width;this.height = height;this.radius = Math.min(width, height) / 3;this.svg = new SVGRenderer(container, width, height);}// 渲染饼图render(data: PieData[]): void {const total = data.reduce((sum, item) => sum + item.value, 0);let startAngle = 0;// 绘制扇形data.forEach(item => {const percentage = item.value / total;const endAngle = startAngle + percentage * Math.PI * 2;// 计算扇形路径const path = this.createArcPath(this.width / 2,this.height / 2,this.radius,startAngle,endAngle);// 绘制扇形this.svg.createPath(path, {fill: item.color || '#1890ff',stroke: '#fff',strokeWidth: 1});// 计算标签位置const labelAngle = startAngle + (endAngle - startAngle) / 2;const labelRadius = this.radius * 1.2;const labelX = this.width / 2 + Math.cos(labelAngle) * labelRadius;const labelY = this.height / 2 + Math.sin(labelAngle) * labelRadius;// 绘制标签this.svg.createText(labelX,labelY,`${item.label} (${Math.round(percentage * 100)}%)`,{fontSize: '12px',textAnchor: 'middle'});startAngle = endAngle;});}// 创建扇形路径private createArcPath(cx: number,cy: number,radius: number,startAngle: number,endAngle: number): string {const start = {x: cx + Math.cos(startAngle) * radius,y: cy + Math.sin(startAngle) * radius};const end = {x: cx + Math.cos(endAngle) * radius,y: cy + Math.sin(endAngle) * radius};const largeArcFlag = endAngle - startAngle <= Math.PI ? '0' : '1';return ['M', cx, cy,'L', start.x, start.y,'A', radius, radius, 0, largeArcFlag, 1, end.x, end.y,'Z'].join(' ');}
}// 数据接口
interface PieData {label: string;value: number;color?: string;
}// 使用示例
const container = document.getElementById('pie-container')!;
const chart = new PieChart(container, 400, 400);const data: PieData[] = [{ label: '产品A', value: 30, color: '#1890ff' },{ label: '产品B', value: 20, color: '#2fc25b' },{ label: '产品C', value: 25, color: '#facc14' },{ label: '产品D', value: 15, color: '#223273' },{ label: '产品E', value: 10, color: '#8543e0' }
];chart.render(data);

最佳实践与建议

  1. 性能优化

    • 使用适当的渲染技术
    • 实现图形缓存
    • 优化动画性能
    • 控制重绘频率
  2. 代码组织

    • 模块化设计
    • 组件封装
    • 统一接口
    • 类型定义
  3. 用户体验

    • 流畅的动画
    • 交互响应
    • 适当的提示
    • 错误处理
  4. 可维护性

    • 清晰的架构
    • 完善的文档
    • 单元测试
    • 代码规范

总结

前端可视化开发需要考虑以下方面:

  1. 选择合适的可视化技术
  2. 设计清晰的架构
  3. 实现高效的渲染
  4. 优化性能和体验
  5. 保持代码可维护性

通过合理的技术选型和架构设计,可以构建出高性能、易用的可视化应用。

学习资源

  1. Canvas API文档
  2. SVG开发指南
  3. WebGL教程
  4. 数据可视化最佳实践
  5. 性能优化技巧

如果你觉得这篇文章有帮助,欢迎点赞收藏,也期待在评论区看到你的想法和建议!👇

终身学习,共同成长。

咱们下一期见

💻

相关文章:

工程化与框架系列(26)--前端可视化开发

前端可视化开发 &#x1f4ca; 引言 前端可视化是现代Web应用中不可或缺的一部分&#xff0c;它能够以直观的方式展示复杂的数据和信息。本文将深入探讨前端可视化开发的关键技术和最佳实践&#xff0c;包括图表绘制、数据处理、动画效果等方面。 可视化技术概述 前端可视化…...

ESP32的IDF开发学习-WiFi的开启、配置与连接

前言 本章节将实现如何使用ESP32的WiFi功能&#xff0c;尽可能的详细地介绍 简介 ESP32中的wifi支持双工作模式 Station&#xff08;STA&#xff09;模式&#xff1a;连接到路由器或其他AP设备&#xff0c;可通过esp_wifi_set_mode(WIFI_MODE_STA)设置。SoftAP模式&#xf…...

2025-3-9 一周总结

目前来看本学期上半程汇编语言,编译原理,数字电路和离散数学是相对重点的课程. 在汇编语言和编译原理这块,个人感觉黑书内知识点更多,细节更到位,体系更完整,可以在老师讲解之前进行预习 应当及时复习每天的内容.第一是看书,然后听课,在一天结束后保证自己的知识梳理完整,没有…...

【网络编程】事件选择模型

十、基于I/O模型的网络开发 10.9 事件选择模型 10.0.1 基本概念 事件选择(WSAEventSelect) 模型是另一个有用的异步 I/O 模型。和 WSAAsyncSelect 模 型类似的是&#xff0c;它也允许应用程序在一个或多个套接字上接收以事件为基础的网络事件通知&#xff0c;最 主要的差别在…...

Java核心语法:从变量到控制流

一、变量与数据类型&#xff08;对比Python/C特性&#xff09; 1. 变量声明三要素 // Java&#xff08;强类型语言&#xff0c;需显式声明类型&#xff09; int age 25; String name "CSDN"; // Python&#xff08;动态类型&#xff09; age 25 name …...

信息安全与网络安全的区别_信息安全与网络安全之差异探析

在当今数字化时代&#xff0c;信息安全与网络安全成为了人们关注的热点话题。尽管这两个概念经常被提及&#xff0c;但它们之间存在着明显的区别。本文旨在探讨信息安全与网络安全的定义、范畴及应对策略&#xff0c;以帮助读者更好地理解和应对相关挑战。 一、定义与范畴的差…...

http协议的三次握手机制

HTTP协议是基于TCP协议的&#xff0c;因此HTTP的三次握手机制实际上就是TCP的三次握手机制。TCP&#xff08;传输控制协议&#xff09;是一种面向连接的、可靠的、基于字节流的传输层通信协议。为了确保通信的可靠性&#xff0c;TCP在建立连接时需要进行三次握手。下面我们详细…...

探秘沃尔什-哈达玛变换(WHT)原理

沃尔什-哈达玛变换&#xff08;WHT&#xff09;起源 起源与命名&#xff08;20世纪早期&#xff09; 数学基础&#xff1a;该变换的理论基础由法国数学家雅克哈达玛&#xff08;Jacques Hadamard&#xff09;在1893年提出&#xff0c;其核心是哈达玛矩阵的构造。扩展与命名&…...

C++ Windows下屏幕截图

屏幕截图核心代码&#xff08;如果要求高帧率&#xff0c;请使用DxGI&#xff09;&#xff1a; // RGB到YUV的转换公式 #define RGB_TO_Y(r, g, b) ((int)((0.299 * (r)) (0.587 * (g)) (0.114 * (b)))) #define RGB_TO_U(r, g, b) ((int)((-0.169 * (r)) - (0.331 * (g)) …...

【python爬虫】酷狗音乐爬取练习

注意&#xff1a;本次爬取的音乐仅有1分钟试听&#xff0c;仅作学习爬虫的原理&#xff0c;完整音乐需要自行下载客户端。 一、 初步分析 登陆酷狗音乐后随机选取一首歌&#xff0c;在请求里发现一段mp3文件&#xff0c;复制网址&#xff0c;确实是我们需要的url。 复制音频的…...

电路的一些设计经验

这个C37在这里位于AMS1117-3.3稳压器的输入端。这个是作为输入滤波电容&#xff0c;有助于平滑输入电压&#xff0c;减少输入电压的纹波和噪声&#xff0c;从而提高稳压器LDO的稳定性。 电容器储存电荷&#xff0c;当输入电压出现小的拨动或者纹波时&#xff0c;电容器可以释放…...

Windows编译环境搭建(MSYS2\MinGW\cmake)

我的音视频/流媒体开源项目(github) 一、基础环境搭建 1.1 MSYS2\MinGW 参考&#xff1a;1. 基于MSYS2的Mingw-w64 GCC搭建Windows下C开发环境_msys2使用mingw64编译 在Widndows系统上&#xff0c;使用gcc工具链&#xff08;g&#xff09;进行C程序开发&#xff1f;可以的&a…...

Vue 框架深度解析:源码分析与实现原理详解

文章目录 一、Vue 核心架构设计1.1 整体架构流程图1.2 模块职责划分 二、响应式系统源码解析2.1 核心类关系图2.2 核心源码分析2.2.1 数据劫持实现2.2.2 依赖收集过程 三、虚拟DOM与Diff算法实现3.1 Diff算法流程图3.2 核心Diff源码 四、模板编译全流程剖析4.1 编译流程图4.2 编…...

前端 | CORS 跨域问题解决

问题&#xff1a;Access to fetch at http://localhost:3000/save from origin http://localhost:5174 has been blocked by CORS policy: Response to preflight request doesnt pass access control check: No Access-Control-Allow-Origin header is present on the request…...

《白帽子讲 Web 安全》之文件操作安全

目录 引言 &#xff08;一&#xff09;文件上传与下载漏洞概述 1.文件上传的常见安全隐患 1.1前端校验的脆弱性与服务端脚本执行危机在文件上传流程中&#xff0c;部分开发者可能会在前端使用 JavaScript 代码对文件后缀名进行简单校验&#xff0c;试图以此阻止非法文件上传…...

【AI】AI开源IDE:CLine源码分析报告

1. 源码位置&#xff1a; CLine 是一个开源的 VSCode 插件&#xff0c;其完整源码托管在 GitHub 的 cline/cline 仓库中。这个仓库包含 CLine 的核心逻辑&#xff08;TypeScript 编写&#xff09;&#xff0c;包括与 LLM 的对话控制、工具调用接口&#xff0c;以及 VSCode 插件…...

使用数据库和缓存的时候,是如何解决数据不一致的问题的?

1.缓存更新策略 1.1. 缓存旁路模式&#xff08;Cache Aside&#xff09; 在应用里负责管理缓存&#xff0c;读取时先查缓存&#xff0c;如果命中了则返回缓存&#xff0c;如果未命中就查询数据库&#xff0c;然后返回缓存&#xff0c;返回缓存的同时把数据给写入缓存中。更新…...

docker compose 以redis为例

常见docker compose 命令 》》注意这个是旧版本的&#xff0c;新版本 docker 与compose 之间没有 - 新版本的 docker compose 把 version 取消了 &#xff0c;redis 默认是没有配置文件的 &#xff0c;nginx&#xff0c;mysql 默认是有的 services:redis:image: redis:lat…...

基于Kubernetes部署MySQL主从集群

以下是一个基于Kubernetes部署MySQL主从集群的详细YAML示例&#xff0c;包含StatefulSet、Service、ConfigMap和Secret等关键配置。MySQL主从集群需要至少1个主节点和多个从节点&#xff0c;这里使用 StatefulSet 初始化脚本 实现主从自动配置。 1. 创建 Namespace (可选) ap…...

VMware中安装配置Ubuntu(2024最新版 超详细)

目录 一、安装虚拟机软件 二、VMware虚拟机 三、 Ubuntu 下载 &#xff08;1&#xff09;官网下载 &#xff08;2&#xff09;清华镜像网站下载 四、创建虚拟机 五、Ubuntu 系统安装过程的配置 六、更换国内镜像源 七、环境搭建完毕 全篇较长&#xff0c;请慢慢观看 一…...

【Linux】信号处理以及补充知识

目录 一、信号被处理的时机&#xff1a; 1、理解&#xff1a; 2、内核态与用户态&#xff1a; 1、概念&#xff1a; 2、重谈地址空间&#xff1a; 3、处理时机&#xff1a; 补充知识&#xff1a; 1、sigaction&#xff1a; 2、函数重入&#xff1a; 3、volatile&…...

如何在rust中解析 windows 的 lnk文件(快捷方式)

一、从标题二开始看&#x1f601; 这些天在使用rust写一个pc端应用程序&#xff0c;需要解析lnk文件获取lnk的图标以及原程序地址&#xff0c;之前并没有过pc端应用程序开发的经验&#xff0c; 所以在广大的互联网上游荡了两天。额&#x1f97a; 今天找到了这个库 lnk_parse很…...

大模型系列课程学习-基于Vllm/Ollama/Ktransformers完成Deepseek推理服务部署

1.机器配置及实验说明 基于前期搭建的双卡机器装机教程&#xff0c;配置如下&#xff1a; 硬件名称参数备注CPUE5-2680V42 *2&#xff08;线程28个&#xff09;无GPU2080TI-22G 双卡魔改卡系统WSL Unbuntu 22.04.5 LTS虚拟机 本轮实验目的&#xff1a;基于VLLM/Ollama/ktran…...

Unity Shader学习总结

1.帧缓冲区和颜色缓冲区区别 用于存储每帧每个像素颜色信息的缓冲区 帧缓冲区包括&#xff1a;颜色缓冲区 深度缓冲区 模板缓冲区 自定义缓冲区 2.ImageEffectShader是什么 后处理用的shader模版 3.computerShader 独立于渲染管线之外&#xff0c;在显卡上运行&#xff0c;大量…...

Java多线程与高并发专题——什么是阻塞队列?

引入 阻塞队列&#xff08;Blocking Queue&#xff09;是一种线程安全的队列数据结构&#xff0c;它的主要特点是&#xff1a; 线程安全&#xff1a;多个线程可以安全地同时访问队列。阻塞操作&#xff1a;当队列为空时&#xff0c;从队列中获取元素的操作会被阻塞&#xff0…...

【Recon】CTF Web类题目主要类型

CTF Web类题目主要类型 1. 信息搜集类2. 注入类漏洞3. 文件处理漏洞4. 身份验证与会话漏洞5. 服务端漏洞6. 客户端漏洞7. 代码审计与PHP特性8. 业务逻辑漏洞总结 CTF&#xff08;Capture The Flag&#xff09;竞赛中的Web类题目主要考察参赛者对Web应用漏洞的识别与利用能力&am…...

comfyui(python)下载insightface失败

使用comfyui时&#xff0c;安装插件zenid、instantid、ip-adapter等换脸插件时&#xff0c;因为依赖insightface安装失败&#xff0c;导致插件中的节点无法正常使用&#xff0c;需要单独安装insightface。 下载insightface到本地&#xff0c;下载地址 选择与自己python版本一致…...

《DataWorks 深度洞察:量子机器学习重塑深度学习架构,决胜复杂数据战场》

在数字化浪潮汹涌澎湃的当下&#xff0c;大数据已然成为推动各行业发展的核心动力。身处这一时代洪流&#xff0c;企业对数据的处理与分析能力&#xff0c;直接关乎其竞争力的高低。阿里巴巴的DataWorks作为大数据领域的扛鼎之作&#xff0c;凭借强大的数据处理与分析能力&…...

Docker小游戏 | 使用Docker部署DOS游戏合集

Docker小游戏 | 使用Docker部署DOS游戏合集 前言项目介绍项目简介项目预览二、系统要求环境要求环境检查Docker版本检查检查操作系统版本三、部署dos-games网页小游戏下载镜像创建容器检查容器状态检查服务端口检查容器日志安全设置四、访问DOS游戏网页五、进阶玩法下载游戏拷贝…...

【redis】慢查询分析与优化

慢查询指在Redis中执行时间超过预设阈值的命令&#xff0c;其日志记录是排查性能瓶颈的核心工具。Redis采用单线程模型&#xff0c;任何耗时操作都可能阻塞后续请求&#xff0c;导致整体性能下降。 命令的执行流程 根据Redis的核心机制&#xff0c;命令执行流程可分为以下步骤…...

ThinkPHP框架

在电脑C磁盘中安装composer 命令 在电脑的D盘中创建cd文件夹 切换磁盘 创建tp框架 创建一个aa的网站&#xff0c;更换路径到上一步下载的tp框架路径 在管理中修改路径 下载压缩包public和view 将前面代码中的public和view文件替换 在PHPStom 中打开文件 运行指定路径 修改demo…...

从零构建高可用MySQL自动化配置系统:核心技术、工具开发与企业级最佳实践

在现代企业级数据库管理中,手动配置 MySQL 已无法满足高效、稳定和可扩展的需求。本文从 MySQL 配置管理的核心原理 出发,深入剖析 自动化配置工具的架构设计、关键技术实现,并结合 企业级落地方案,帮助读者构建一套 高可用、智能化的 MySQL 自动化配置系统。无论是 DevOps…...

qt 播放pcm音频

一、获取PCM音频 ffmpeg -i input.mp3 -acodec pcm_s16le -ar 44100 -ac 2 -f s16le output.pcm -acodec pcm_s16le&#xff1a;指定16位小端PCM编码格式&#xff08;兼容性最佳&#xff09;-ar 44100&#xff1a;设置采样率为CD标准44.1kHz&#xff08;可替换为16000/8000等&a…...

开启mysql远程登录

目录 前言开启步骤 前言 为了安全考虑&#xff0c;mysql默认不允许远程登录&#xff0c;需要我们自己开启。当然在远程登录之前mysql的端口也要开放。下面是mysql开启远程登录的步骤。 开启步骤 本地登录mysql mysql -u root -p然后输入登录密码 给登录账号授权 GRANT AL…...

中级网络工程师面试题参考示例(5)

企业园区网络设计 问题&#xff1a; 请描述一下如何设计一个企业园区网络&#xff0c;包括核心层、汇聚层和接入层的功能及其关键技术。 解答&#xff1a; 核心层&#xff1a;负责高速数据交换&#xff0c;通常使用高性能的三层交换机&#xff0c;支持高带宽和低延迟。关键技…...

【每日学点HarmonyOS Next知识】输入框自动获取焦点、JS桥实现方式、Popup设置全屏蒙版、鼠标事件适配、Web跨域

1、HarmonyOS TextInput或TextArea如何自动获取焦点&#xff1f; 可以使用 focusControl.requestFocus 对需要获取焦点的组件设置焦点&#xff0c;具体可以参考文档&#xff1a; https://developer.huawei.com/consumer/cn/doc/harmonyos-references-V5/ts-universal-attribut…...

Git学习笔记(二)

Git学习笔记&#xff08;二&#xff09; 下载VSCode创建本地仓库推送远程仓库界面功能 使用 VSCode 进行Git仓库的项目管理 这篇文章是我学完使用 命令行终端 管理Git仓库额外学习的 文章主要用于巩固和方便后续复习 下载VSCode 可以看我这篇文章下载VSCode 创建本地仓库 …...

UDP协议和报文格式

✍作者&#xff1a;柒烨带你飞 &#x1f4aa;格言&#xff1a;生活的情况越艰难&#xff0c;我越感到自己更坚强&#xff1b;我这个人走得很慢&#xff0c;但我从不后退。 &#x1f4dc;系列专栏&#xff1a;网络安全从菜鸟到飞鸟的逆袭 目录 一&#xff0c;UDP协议1&#xff0…...

Java TCP 通信:实现简单的 Echo 服务器与客户端

TCP&#xff08;Transmission Control Protocol&#xff09;是一种面向连接的、可靠的传输层协议。与 UDP 不同&#xff0c;TCP 保证了数据的顺序、可靠性和完整性&#xff0c;适用于需要可靠传输的应用场景&#xff0c;如文件传输、网页浏览等。本文将基于 Java 实现一个简单的…...

升级到Android Studio 2024.2.2 版本遇到的坑

一、上来就编译报错&#xff0c;大概率是因为选择了替换安装&#xff0c;本地配置文件出错 找到本地当前版本的配置文件&#xff0c;删掉&#xff0c;重启studio就好了&#xff1a; 1、打开终端 2、“cd /Users/用户名/Library/Application\ Support/Google” //到Google目录 …...

hom_mat2d_to_affine_par 的c#实现

hom_mat2d_to_affine_par 的c#实现 背景&#xff1a;为课室贡献一个通用函数&#xff0c;实现halcon算子的同等效果&#xff0c;查询csdn未果&#xff0c;deepseek二哥与chtgpt大哥给不了最终程序&#xff0c;在大哥与二哥帮助下&#xff0c;最终实现同等效果。 踩坑&#xf…...

#9 【code】实现扩散模型的一个jupyter notebook

今天以一个简单的notebook入手,学习一下扩散模型的运行流程。有点困难不要紧,一个人吃了六个馒头才饱,他是吃第一个饱的,还是第六个饱的呢?始终坚信,现在的技术积累,终会成为未来高楼大厦的根基! import torch import torchvision import matplotlib.pyplot as pltdef …...

三星首款三折叠手机被曝外屏6.49英寸:折叠屏领域的新突破

在智能手机的发展历程中,折叠屏手机的出现无疑是一次具有里程碑意义的创新。它打破了传统手机屏幕尺寸的限制,为用户带来了更加多元和便捷的使用体验。而三星,作为手机行业的巨头,一直以来都在折叠屏技术领域积极探索和创新。近日,三星首款三折叠手机的诸多细节被曝光,其…...

《OkHttp:工作原理 拦截器链深度解析》

目录 一、OKHttp 的基本使用 1. 添加依赖 2. 发起 HTTP 请求 3. 拦截器&#xff08;Interceptor&#xff09; 4. 高级配置 二、OKHttp 核心原理 1. 责任链模式&#xff08;Interceptor Chain&#xff09; 2. 连接池&#xff08;ConnectionPool&#xff09; 3. 请求调度…...

Python 中多种方式获取屏幕的 DPI值

在 Python 中&#xff0c;可以通过多种方式获取屏幕的 DPI&#xff08;每英寸点数&#xff09;。以下是几种常见的方法&#xff1a; 方法 1&#xff1a;使用 tkinter 模块 tkinter 是 Python 的标准 GUI 库&#xff0c;可以通过它获取屏幕的 DPI。 import tkinter as tkdef …...

linux安装Mariadb10.5并修改端口

首先配置yum源 进入下方的文件进行配置 vim /etc/yum.repos.d/MariaDB.repo填写下方内容 [mariadb]name MariaDBbaseurl https:///mirrors.aliyun.com/mariadb/yum/10.5/centos8-amd64/gpgkeyhttps:///mirrors.aliyun.com/mariadb/yum/RPM-GPG-KEY-MariaDBmodule_hotfixes…...

Java EE 进阶:Spring IoCDI

IOC的简单介绍 什么是Spring&#xff1f;Spring是一个开源的框架&#xff0c;让我们的开发更加的简单&#xff0c;我们可以用一句更加具体的话来概括Spring&#xff0c;就是Spring是一个包含众多工具方法的IOC容器。 简单介绍一下IOC&#xff0c;我们之前说过通过ReqestContr…...

蓝桥杯备考:图论初解

1&#xff1a;图的定义 我们学了线性表和树的结构&#xff0c;那什么是图呢&#xff1f; 线性表是一个串一个是一对一的结构 树是一对多的&#xff0c;每个结点可以有多个孩子&#xff0c;但只能有一个父亲 而我们今天学的图&#xff01;就是多对多的结构了 V表示的是图的顶点集…...

JVM类加载器面试题及原理

JVM只会运行二进制文件&#xff0c;类加载器的作用就是将字节码文件加载到JVM中&#xff0c;从而让Java程序能够启动起来。 1. 类加载器的种类 启动类加载器&#xff08;BootStrap ClassLoader&#xff09;&#xff1a;加载JAVA_HOME/jre/lib目录下的库扩展类加载器&#xff…...

《V8 引擎狂飙,Node.js 续写 JavaScript 传奇》

”你没想过也许是这个镇子对你来说太小了吗&#xff1f; 对我而言&#xff0c;这个小镇容不下我的雄心壮志。 “ 什么是 Node.js&#xff1f; Node.js是一个跨平台JS运行环境&#xff0c;使开发者可以搭建服务器端的JS应用程序 作用&#xff1a;使用 Node.js 编写服务器端程序…...