【计算机视觉基础CV-图像分类】03-深度学习图像分类实战:鲜花数据集加载与预处理详解
本文将深入介绍鲜花分类数据集的加载与处理方式,同时详细解释代码的每一步骤并给出更丰富的实践建议和拓展思路。以实用为导向,为读者提供从数据组织、预处理、加载到可视化展示的完整过程,并为后续模型训练打下基础。
前言
在计算机视觉的深度学习实践中,数据加载和预处理是至关重要的一步。无论你是初学者,还是有一定经验的从业者,都需要深刻理解如何将原始数据转化为神经网络可接受的输入。PyTorch中的torchvision.datasets和torchvision.transforms为我们提供了极大的便利,使图像数据的加载和处理更加高效与简洁。
本文将以“鲜花分类数据集”(一个包含5种不同花卉类别的图像数据集)为例,详细讲述如何使用ImageFolder类进行数据加载,并通过transforms对图像进行预处理和数据增强。我们还会深入讨论数据集结构、训练/验证集划分、代码注释和实践建议,并给出详细说明。
数据集简介与结构
本例使用的鲜花分类数据集共包含5种花:雏菊(daisy)、蒲公英(dandelion)、玫瑰(roses)、向日葵(sunflowers)和郁金香(tulips)。数据量约为:
-
训练集(train):3306张图像
-
验证集(val):364张图像
数据已按类别分好目录,每个类别对应一个文件夹,文件夹中存放若干图片文件。结构示意如下:
dataset/flower_datas/├─ train/│ ├─ daisy/ # 雏菊类图像若干张│ ├─ dandelion/ # 蒲公英类图像若干张│ ├─ roses/ # 玫瑰类图像若干张│ ├─ sunflowers/ # 向日葵类图像若干张│ └─ tulips/ # 郁金香类图像若干张└─ val/├─ daisy/├─ dandelion/├─ roses/├─ sunflowers/└─ tulips/
这种目录结构非常适合ImageFolder数据集类,它会根据子文件夹的名称自动分配类别标签,从0开始编号。例如:
-
daisy -> 0
-
dandelion -> 1
-
roses -> 2
-
sunflowers -> 3
-
tulips -> 4
这样无需手动编码类别映射,简化了流程。
ImageFolder和transform
ImageFolder简介
ImageFolder是torchvision.datasets中的一个实用数据类,它假设数据按如下规则组织:
-
root/class_x/xxx.png -
root/class_x/xxy.png -
root/class_y/xxz.png -
...
其中class_x和class_y是类名(字符串),ImageFolder会根据这些类名自动生成类别索引。加载后,每个样本是一个(image, label)二元组,image通常会通过transform转换为Tensor,label为整数索引。
transforms的数据预处理功能
torchvision.transforms提供多种图像处理方法,用来改变图像格式、尺寸、颜色空间和进行数据增强。例如:
-
ToTensor():将PIL图像或Numpy数组转换为(C,H,W)格式的张量,并将像素值归一化到[0,1]之间。 -
Resize((224,224)):将图像缩放到224x224大小,这通常是预训练模型如ResNet、VGG的标准输入尺寸。 -
RandomHorizontalFlip():随机水平翻转图像,用于数据增强,提高模型对翻转不敏感。 -
Normalize(mean, std):对图像的每个通道进行归一化,使训练更稳定。
你可以根据需求灵活组合多个变换操作,使用transforms.Compose将其串联成流水线。
加载鲜花分类数据集的示例代码
下面的代码示例中,我将详细注释每个步骤,为读者提供清晰的思路。该示例以最基本的ToTensor和Resize为主,读者可按需添加更多transform。
import torch
import torchvision
from torchvision.datasets import ImageFolder
from torchvision import transforms
import matplotlib.pyplot as plt# 数据集存放路径,根据实际情况修改
flowers_train_path = '../01.图像分类/dataset/flower_datas/train/'
flowers_val_path = '../01.图像分类/dataset/flower_datas/val/'# 定义数据预处理
# 这里的transforms主要包括:
# 1. ToTensor():将PIL图片或numpy数组转为Tensor,并将像素值归一化到[0,1]区间。
# 2. Resize((224,224)):将所有图片大小统一为224x224,以匹配后续卷积神经网络的输入要求。
# 对于实际训练,更建议加入数据增强手段(如随机裁剪、翻转、归一化等),
# 但本例先展示基本流程。
dataset_transform = transforms.Compose([transforms.ToTensor(),transforms.Resize((224,224))
])# 使用ImageFolder加载训练集和验证集
# ImageFolder会扫描指定目录下的子文件夹,并以子文件夹名称作为类别。
flowers_train = ImageFolder(root=flowers_train_path, transform=dataset_transform)
flowers_val = ImageFolder(root=flowers_val_path, transform=dataset_transform)# 打印样本数量
print("训练集样本数:", len(flowers_train))
print("验证集样本数:", len(flowers_val))# flowers_train.classes属性包含类别名称列表,如['daisy', 'dandelion', 'roses', 'sunflowers', 'tulips']
print("类别名称列表:", flowers_train.classes)# 获取单个样本进行查看
# __getitem__(index)返回(img, label),img是Tensor,label是int
sample_index = 3000
sample_img, sample_label = flowers_train[sample_index]print("样本索引:", sample_index)
print("类别标签索引:", sample_label, "类别名称:", flowers_train.classes[sample_label])
print("图像Tensor尺寸:", sample_img.shape) # 期望为[3,224,224]# 可视化图像
# Matplotlib的imshow要求图像为(H,W,C),而Tensor是(C,H,W),需要permute调整维度顺序。
plt.imshow(sample_img.permute(1,2,0))
plt.title(flowers_train.classes[sample_label])
plt.show()
代码输出:

关于训练集、验证集和测试集的说明
本数据集中已提前将数据分为train和val两个目录:
-
train/:训练集,用于模型训练过程中反向传播和参数更新。 -
val/:验证集,用于在训练中间进行性能评估,不参与参数更新,仅用于选择超参数或判断训练是否过拟合。
有些数据集还会提供test/测试集,用于最终评估模型在未知数据上的表现,但本例中未提供,如有需要可自行分割数据或从其他来源获取。
DataLoader的引入
仅有ImageFolder还不够,为了在训练时批量读取数据并进行迭代,我们通常会将数据集对象传入DataLoader中。
DataLoader的作用是:
-
按指定的batch_size从Dataset中抽取样本构成mini-batch。
-
可设置
shuffle=True来随机打乱样本顺序,防止模型记住样本顺序。 -
使用
num_workers参数并行加速数据加载。
示例(可选代码):
from torch.utils.data import DataLoaderbatch_size = 32
# 定义训练集和验证集的DataLoader
train_loader = DataLoader(flowers_train, batch_size=batch_size, shuffle=True, num_workers=2)
val_loader = DataLoader(flowers_val, batch_size=batch_size, shuffle=False, num_workers=2)# 测试一下加载结果
images, labels = next(iter(train_loader))
print("一个batch的图像尺寸:", images.shape) # [batch_size, 3, 224, 224]
print("对应的标签:", labels) # 张量形式,如tensor([0, 1, 3, ...])

有了DataLoader,我们在训练模型时,就可以轻松迭代数据:
for epoch in range(1):for batch_images, batch_labels in train_loader:# 在这里将batch_images, batch_labels输入模型进行训练print("一个batch的图像尺寸:", batch_images.shape) # [batch_size, 3, 224, 224]print("对应的标签:", batch_labels) # 张量形式,如tensor([0, 1, 3, ...])passbreak

我们可以打印一下第一个batch 和最后一个batch的标签
batch_count = 0
first_batch_images, first_batch_labels = None, None
last_batch_images, last_batch_labels = None, Nonefor epoch in range(1):for batch_images, batch_labels in train_loader:batch_count += 1# 保存第一个batchif batch_count == 1:first_batch_images, first_batch_labels = batch_images, batch_labelsprint("第一个batch的图像尺寸:", batch_images.shape)print("第一个batch的标签:", batch_labels)# 每次循环都会更新last_batchlast_batch_images, last_batch_labels = batch_images, batch_labelsbreak # 只进行一次epoch的训练,移除这行会进行多个epoch的训练# 打印最后一个batch
print("最后一个batch的图像尺寸:", last_batch_images.shape)
print("最后一个batch的标签:", last_batch_labels)# 打印总共的batch数量
print("总共的batch数量:", batch_count)

数据增强策略的拓展
实际训练中,为提高模型的泛化能力,我们常加入数据增强操作。这些操作对训练集图像进行随机变换,如随机剪裁、翻转、颜色抖动、归一化等。这样模型不会过度记忆特定图像的像素分布,而会学习更有泛化性的特征。
一个常用的transform示例:
# 定义训练集的图像预处理流程
train_transform = transforms.Compose([# 随机裁剪并缩放图像到224x224的尺寸,裁剪的区域大小是随机的transforms.RandomResizedCrop(224), # 随机进行水平翻转,用于数据增强,提升模型的泛化能力transforms.RandomHorizontalFlip(),# 将图像转换为Tensor类型,PyTorch要求输入为Tensor格式transforms.ToTensor(),# 进行图像的标准化处理。根据ImageNet数据集的均值和标准差进行归一化,# 使得不同的通道(RGB)具有相同的尺度,便于训练。transforms.Normalize(mean=[0.485,0.456,0.406], std=[0.229,0.224,0.225])
])# 定义验证集的图像预处理流程
val_transform = transforms.Compose([# 将图像的最短边缩放到256像素,保持长宽比例不变transforms.Resize(256), # 从缩放后的图像中进行中心裁剪,裁剪出224x224的区域,这样图像的尺寸就一致了transforms.CenterCrop(224),# 将图像转换为Tensor类型,PyTorch要求输入为Tensor格式transforms.ToTensor(),# 进行图像的标准化处理。根据ImageNet数据集的均值和标准差进行归一化,# 使得不同的通道(RGB)具有相同的尺度,便于训练。transforms.Normalize(mean=[0.485,0.456,0.406], std=[0.229,0.224,0.225])
])# 使用定义的transform对训练集和验证集进行图像预处理
# flowers_train_path和flowers_val_path是训练集和验证集图像所在的路径
flowers_train = ImageFolder(flowers_train_path, transform=train_transform) # 训练集
flowers_val = ImageFolder(flowers_val_path, transform=val_transform) # 验证集
在此示例中,Normalize的参数是使用ImageNet数据集的均值和标准差,这在使用ImageNet预训练模型时是常规操作。对于自定义数据集,你也可以先统计本数据集的均值和方差,再进行归一化。
我们可以打印一下变化前后的图像区别
import os
import random
import numpy as np # 需要导入numpy
import matplotlib.pyplot as plt
from PIL import Image
from torchvision import transforms
from torchvision.datasets import ImageFolder# 定义训练集的图像预处理流程
train_transform = transforms.Compose([transforms.RandomResizedCrop(224),transforms.RandomHorizontalFlip(),transforms.ToTensor(),transforms.Normalize(mean=[0.485, 0.456, 0.406], std=[0.229, 0.224, 0.225])
])# 定义图像数据集路径
train_image_folder = '/Users/coyi/PycharmProjects/coyi_pythonProject/01.图像分类/dataset/flower_datas/train/'# 使用ImageFolder加载数据集
dataset = ImageFolder(train_image_folder, transform=None)# 随机选取一张图片
random_idx = random.randint(0, len(dataset) - 1)
image, label = dataset[random_idx]# 显示原始图像
plt.figure(figsize=(5,5))
plt.title("Original Image")
plt.imshow(image)
plt.axis('off') # 不显示坐标轴
plt.show()# 应用train_transform变换
transformed_image = train_transform(image)# 反标准化(Undo normalization)以恢复图片的原始视觉效果,因为训练的时候需要标准化
inv_normalize = transforms.Normalize(mean=[-0.485, -0.456, -0.406], std=[1/0.229, 1/0.224, 1/0.225])
unnormalized_image = inv_normalize(transformed_image)# 将Tensor转回PIL图像进行显示
unnormalized_image = unnormalized_image.permute(1, 2, 0).numpy() # 转换为HWC格式
unnormalized_image = np.clip(unnormalized_image, 0, 1) # 限制值在[0, 1]之间,以符合视觉输出# 显示变换后的图像
plt.figure(figsize=(5,5))
plt.title("Transformed Image")
plt.imshow(unnormalized_image)
plt.axis('off') # 不显示坐标轴
plt.show()
输出:

备注: 为了显示图片,我对处理后的图片进行了反标准化,实际上训练的时候是不需要反标准化的
为什么要反标准化?
标准化是一个常见的预处理步骤,目的是让模型训练时更稳定,通常是将像素值转换到均值为0、标准差为1的范围。这可以帮助模型更好地收敛,并且消除不同通道(例如RGB)的尺度差异。
然而,标准化后的图像不适合直接用于可视化,因为它们的像素值已经不在[0, 1]的范围内,可能会变成负数或大于1。反标准化的目的是恢复图像的原始视觉效果,让它们的像素值回到原始的视觉范围。
不反标准化可以吗?
在可视化时不反标准化是可以的,但你会看到经过标准化后的图像没有直观的可视化效果,因为图像的像素值会偏离 [0, 1] 的可视化范围。这会导致显示的图像看起来可能是“失真”的,例如图像会变得非常暗、非常亮,或者有一些不自然的颜色。
简而言之:
• 反标准化是为了恢复图像的原始视觉效果,使得图像显示更符合人类的感知。
• **np.clip()**是为了确保图像的像素值在[0, 1]范围内,符合图像显示的要求。
示例:
假设标准化之后,你得到了一个像素值为 -0.5 或 1.5 的图像像素。这时,如果不进行 np.clip(),直接用 matplotlib 显示,可能会看到图像出现异常的颜色或显示不出来。而通过 np.clip(),将这些像素值限制在[0, 1]的范围内,可以确保图像能正确显示。
类别分布与标签可解释性
flowers_train.classes或flowers_val.classes可以查看类名列表。例如:

这意味着模型预测结果中的label=0代表daisy,label=1代表dandelion,以此类推。当我们预测模型输出为label=3时,就可以将其解释为sunflowers。这种可读性非常有助于后期分析和调试。
如果想查看具体每类样本数量,可手动统计,例如:
通过查看类别分布,我们可了解数据是否偏斜(某些类样本过多或过少),从而采取相应措施(如类均衡采样、权重平衡等)。
实战建议和下一步计划
-
数据准备完成后做什么? 通常下一步就是定义和加载模型(如预训练的ResNet18),然后编写训练循环对模型进行微调或从头训练。在训练循环中,
train_loader提供批数据,val_loader则用于评估模型在验证集上的表现。 -
调试DataLoader是否正确工作: 在正式训练前,尝试可视化几个batch的数据样本,确保图像大小、颜色正确,标签映射无误。如果出现图像显示不正确或标签偏移,及时检查目录结构和transform流程。
-
善用数据增强: 当验证集精度停滞不前或出现过拟合时,尝试加入更多数据增强手段(如
RandomRotation、ColorJitter、RandomGrayscale等)提升泛化性能。 -
硬件加速: 在加载大规模数据时,合理增加
num_workers可以提高数据读取速度(依赖操作系统和硬件条件)。同时,如果是分布式训练,也需考虑分布式Sampler和合适的数据划分策略。 -
定制Dataset: 如果你的数据不遵循
ImageFolder的结构,也可以自行定义Dataset类,通过实现__len__和__getitem__方法来自定义数据加载流程。但对像本例这样已按类分文件夹的数据集,ImageFolder无疑是最简单高效的方案。
小结
在本文中,我们从零出发,详细介绍了如何使用PyTorch的ImageFolder和transforms加载和预处理鲜花分类数据集。主要点包括:
-
数据集组织结构:子文件夹命名为类名,便于ImageFolder自动识别类别。
-
使用transforms对图像进行ToTensor和Resize等变换,以满足神经网络输入要求。
-
通过可视化样本和打印类别信息确认数据加载的正确性。
-
引入DataLoader批量采样和迭代数据,为后续训练循环奠定基础。
-
展望数据增强、Normalize以及预训练模型迁移学习等实战技巧。
数据加载与预处理是深度学习项目不可或缺的步骤。掌握这些技能,能够让你在模型开发和实验中更加得心应手。未来你可以尝试更多高级技巧,如自定义transforms、对数据集进行统计分析、探索更复杂的增强策略和分布式数据加载方法。
达成这些基础后,你就可以开始定义模型(如使用torchvision.models.resnet18(pretrained=True)加载预训练模型)、设置损失函数(如CrossEntropyLoss)、选择优化器(如Adam或SGD),并在训练循环中快速迭代提升模型性能。
希望本文介绍,能为你对CV数据加载与预处理的理解添砖加瓦,帮助你在图像分类任务中迈出稳健的一步。
如果你遇到了什么问题,或者想了解某些方面的知识,欢迎在评论区留言
相关文章:
【计算机视觉基础CV-图像分类】03-深度学习图像分类实战:鲜花数据集加载与预处理详解
本文将深入介绍鲜花分类数据集的加载与处理方式,同时详细解释代码的每一步骤并给出更丰富的实践建议和拓展思路。以实用为导向,为读者提供从数据组织、预处理、加载到可视化展示的完整过程,并为后续模型训练打下基础。 前言 在计算机视觉的深…...
大模型应用技术系列(一):大模型应用整体技术栈浅析
RAG相关的技术学习暂时告一段落了,接下来尝试探索新的学习方向。这就引入一个问题:接下来该做什么?为了能进一步推进,我需要有一个整体的视角,从更上层来看整个技术栈,从而确定接下来感兴趣的方向。本文主要探索从更上层的视角来看构建大模型的技术栈,从而进一步确定研究…...
绿色环保木塑复合材料自动化生产线设计书
《绿色环保木塑复合材料自动化生产线设计书》 一、项目概述 随着全球对环境保护和可持续发展的日益重视,绿色环保材料的研发与生产成为了热门领域。木塑复合材料作为一种新型的绿色环保材料,它将木材纤维与塑料通过特定工艺复合而成,兼具木材与塑料的双重特性,具有防水、…...
Sourcegraph 概述
Sourcegraph 报告 Sourcegraph 是一款强大的代码搜索和智能导航工具,专为大型代码库、分布式系统和跨多个仓库的开发环境设计。它能显著提高开发者对复杂系统的理解和维护效率,帮助团队在庞大的代码库中快速找到关键信息。本文将详细讲解 Sourcegraph 的…...
c 保存 csv格式的文件
在C语言中保存数据为CSV(逗号分隔值)格式的文件,你可以使用标准I/O库函数,如fprintf,来将数据写入文件,并确保每个字段之间用逗号分隔。以下是一个简单的示例,说明如何在C语言中创建一个CSV文件…...
C语言扫雷游戏教学(有图形界面)(提供源码+实验报告)(计时+排行榜+难度选择+登录注册+背景音乐)(涉及easyX库)
前言: 本篇文章篇幅较长,请根据自己的需求在目录上跳转对应内容哦!源码及实验报告的获取在文章的后面哦!本人代码水平不佳,希望本文章和项目能带给大家帮助! 目录 前言: 一.成果预览&#x…...
第五节:GLM-4v-9b模型model加载源码解读(模型相关参数方法解读)
文章目录 前言一、GLM-4v-9b模型model加载源码解读1、GLM-4v-9b模型model加载主函数源码2、GLM-4v-9b模型model加载源码源码解读3、GLM-4v-9b自定义模型类源码解读 二、基于GLM-4v-9b模型获取模型输入参数等内容源码解读(from_pretrained-->huggingface)1、from_pretrained函…...
面试经验分享 | 北京渗透测试岗位
更多大厂面试经验的视频经验分享看主页 目录: 所面试的公司:安全大厂 所在城市:北京 面试职位:渗透测试工程师 面试方式:腾讯会议线上面试线下面试 面试过程: 面试官的问题: 1、说一下XSS有哪…...
unity Toggle制作滑动开关
先上效果图 重点是这个Graphic要清空,不然显示不能直接切换,会消失 using DG.Tweening; using UnityEngine; using UnityEngine.UI;public class SwitchToggle : MonoBehaviour {public RectTransform handleRect;public float duration 0.5f;private Vector2 handlePos;To…...
全面解析 Kubernetes 流量负载均衡:iptables 与 IPVS 模式
目录 Kubernetes 中 Service 的流量负载均衡模式 1. iptables 模式 工作原理 数据路径 优点 缺点 适用场景 2. IPVS 模式 工作原理 数据路径 优点 缺点 适用场景 两种模式的对比 如何切换模式 启用 IPVS 模式 验证模式 总结 Kubernetes 中 Service 的流量负载…...
【unity】【游戏开发】Unity项目一运行就蓝屏报Watch Dog Timeout
【背景】 由于是蓝屏所以没法截屏,总之今天遇到了一开Unity,过一阵就蓝屏的情况,报Watch Dog Timeout。 【分析】 通过任务管理器查看,发现Unity占用率100%,再观察Unity内部,每次右下角出现一个Global I…...
【macos java反编译工具Java Decompiler】
mac上能用的反编译工具 https://java-decompiler.github.io/...
宠物用品电子商务系统|Java|SSM|VUE| 前后端分离
【技术栈】 1⃣️:架构: B/S、MVC 2⃣️:系统环境:Windowsh/Mac 3⃣️:开发环境:IDEA、JDK1.8、Maven、Mysql5.7 4⃣️:技术栈:Java、Mysql、SSM、Mybatis-Plus、VUE、jquery,html 5⃣️数据库可…...
脑肿瘤检测数据集,对9900张原始图片进行YOLO,COCO,VOC格式的标注
脑肿瘤检测数据集,对9900张原始图片进行YOLO,COCO,VOC格式的标注 数据集分割 训练组 70% 6930图片 有效集 20% 1980图片 测试集 10% 990图片 预处理 静态裁剪: 24-82&…...
Adversarial Machine Learning(对抗机器学习)
之前把机器学习(Machine Learning)的安全问题简单记录了一下,这里有深入研究了一些具体的概念,这里记录一下方便以后查阅。 Adversarial Machine Learning(对抗机器学习) Adversarial Examples 相关内容Eva…...
每日十题八股-2024年12月23日
1.MySQL如何避免重复插入数据? 2.CHAR 和 VARCHAR有什么区别? 3.Text数据类型可以无限大吗? 4.说一下外键约束 5.MySQL的关键字in和exist 6.mysql中的一些基本函数,你知道哪些? 7.SQL查询语句的执行顺序是怎么样的&…...
Android Studio新建项目在源码中编译
新建空白项目 用AS新建默认空项目,代码目录如下: MyApplication$ tree -L 4 . ├── Android.bp // bp编译脚本 ├── Android.mk.bak // mk编译脚本 ├── app // 下面目录结构是AS新建工程目录 │ ├── build.gradle │ ├── pro…...
ubuntu使用ffmpeg+ZLMediaKit搭建rtsp推流环境
最方便的方式,ubuntu上安装vlc播放器,通过vlc来推流,在网上有很多教程。这里采用ffmpegZLMediaKit 必备条件: 1、安装ffmpeg 2、安装ZLMediaKit 一、安装ffmpeg sudo apt update sudo apt install ffmpeg 二、安装ZLMediaKit…...
vue中的css深度选择器v-deep 配合!important
当 <style> 标签有 scoped 属性时,它的 CSS 只作用于当前组件中的元素,父组件的样式将不会渗透到子组件。 如果你希望 scoped 样式中的一个选择器能够作用得“更深”,例如影响子组件,你可以使用深度选择器。 ::v-deep { } 举…...
Python读写JSON文件
import jsondef writeJSONFile(self):with open(g_updateFilePath, "w" encodingutf-8) as fiel:json.dump(dictData, fiel, indent4, ensure_asciiFalse)fiel.close()def readJsonToDict(file):with open(file, r, encodingutf-8) as f: # 确保文件以 UTF-8 编码打…...
【Axure高保真原型】引导弹窗
今天和大家中分享引导弹窗的原型模板,载入页面后,会显示引导弹窗,适用于引导用户使用页面,点击完成后,会显示下一个引导弹窗,直至最后一个引导弹窗完成后进入首页。具体效果可以点击下方视频观看或打开下方…...
Debian系统简介
目录 Debian系统介绍 Debian版本介绍 Debian软件源介绍 软件包管理工具dpkg dpkg核心指令详解 安装软件包 卸载软件包 查询软件包状态 验证软件包完整性 手动处理依赖关系 dpkg vs apt Debian系统介绍 Debian 和 Ubuntu 都是基于 Debian内核 的 Linux 发行版ÿ…...
鸿蒙中用HarmonyOS SDK应用服务 HarmonyOS5开发一个医院挂号小程序
一、开发准备 环境搭建: 安装DevEco Studio 3.0或更高版本配置HarmonyOS SDK申请开发者账号 项目创建: File > New > Create Project > Application (选择"Empty Ability") 二、核心功能实现 1. 医院科室展示 /…...
抖音增长新引擎:品融电商,一站式全案代运营领跑者
抖音增长新引擎:品融电商,一站式全案代运营领跑者 在抖音这个日活超7亿的流量汪洋中,品牌如何破浪前行?自建团队成本高、效果难控;碎片化运营又难成合力——这正是许多企业面临的增长困局。品融电商以「抖音全案代运营…...
页面渲染流程与性能优化
页面渲染流程与性能优化详解(完整版) 一、现代浏览器渲染流程(详细说明) 1. 构建DOM树 浏览器接收到HTML文档后,会逐步解析并构建DOM(Document Object Model)树。具体过程如下: (…...
C++:多态机制详解
目录 一. 多态的概念 1.静态多态(编译时多态) 二.动态多态的定义及实现 1.多态的构成条件 2.虚函数 3.虚函数的重写/覆盖 4.虚函数重写的一些其他问题 1).协变 2).析构函数的重写 5.override 和 final关键字 1&#…...
解决:Android studio 编译后报错\app\src\main\cpp\CMakeLists.txt‘ to exist
现象: android studio报错: [CXX1409] D:\GitLab\xxxxx\app.cxx\Debug\3f3w4y1i\arm64-v8a\android_gradle_build.json : expected buildFiles file ‘D:\GitLab\xxxxx\app\src\main\cpp\CMakeLists.txt’ to exist 解决: 不要动CMakeLists.…...
全面解析数据库:从基础概念到前沿应用
在数字化时代,数据已成为企业和社会发展的核心资产,而数据库作为存储、管理和处理数据的关键工具,在各个领域发挥着举足轻重的作用。从电商平台的商品信息管理,到社交网络的用户数据存储,再到金融行业的交易记录处理&a…...
土建施工员考试:建筑施工技术重点知识有哪些?
《管理实务》是土建施工员考试中侧重实操应用与管理能力的科目,核心考查施工组织、质量安全、进度成本等现场管理要点。以下是结合考试大纲与高频考点整理的重点内容,附学习方向和应试技巧: 一、施工组织与进度管理 核心目标: 规…...
车载诊断架构 --- ZEVonUDS(J1979-3)简介第一篇
我是穿拖鞋的汉子,魔都中坚持长期主义的汽车电子工程师。 老规矩,分享一段喜欢的文字,避免自己成为高知识低文化的工程师: 做到欲望极简,了解自己的真实欲望,不受外在潮流的影响,不盲从,不跟风。把自己的精力全部用在自己。一是去掉多余,凡事找规律,基础是诚信;二是…...
