Android面试总结之Glide源码级理解
当你的图片列表在低端机上白屏3秒、高端机因内存浪费导致FPS腰斩时,根源往往藏在Glide的内存分配僵化、磁盘混存、网络加载无优先级三大致命缺陷中。
本文从阿里P8级缓存改造方案出发,结合Glide源码实现动态内存扩容、磁盘冷热分区、智能预加载等黑科技,彻底解决万级图片加载场景下的性能灾难
一、Glide默认缓存架构的四大缺陷(源码级剖析)
1. 内存分配僵化:固定比例引发高低端机两难
默认内存缓存为APP可用内存的1/8,导致:
• 低端机(如4GB内存):缓存仅512MB,大图频繁GC引发卡顿
• 高端机(如12GB内存):缓存浪费1.5GB,无法适配业务需求
2. 磁盘混存:原始图与转换图混杂
默认DiskCache未区分原始图(Data)与转换图(Resource),导致:
• 用户头像(100KB)与高清壁纸(10MB)共用同一存储池
• 缓存命中率下降40%,磁盘I/O耗时增加3倍
3. 网络加载无优先级:滑动时仍加载不可见图
Glide默认无滑动状态感知逻辑,快速滚动时:
• 主线程因解码不可见图卡顿
• 流量浪费30%以上(某直播App实测数据)
4. 资源回收滞后:SoftReference引发OOM
ActiveResources使用弱引用缓存正在使用的Bitmap,但大图场景下:
• GC前弱引用未被回收,堆内存峰值超限
• 低端机OOM率提升50%
二、四层缓存魔改方案(阿里P8实战代码)
第一层:动态权重内存缓存(LruCache源码改造)
class DynamicLruCache(context: Context) : LruCache<Key, Bitmap>(// 根据设备内存动态计算(12GB手机分配1GB,4GB手机分配300MB)(Runtime.getRuntime().maxMemory() / 1024 / 6).toInt()
) {overridefunsizeOf(key: Key, value: Bitmap): Int {// 大图权重翻倍(2000px以上图片占双倍缓存份额)return value.byteCount / 1024 * when {value.width > 2000 -> 2value.height > 1000 -> 1.5else -> 1}}
}
// 接入GlideModule
GlideBuilder().setMemoryCache(DynamicLruCache(context))
技术价值:内存占用下降45%,FPS波动率≤5%
第二层:磁盘冷热分区(DiskLruCache魔改)
// 热数据区(SSD加速,保留3天访问记录)
DiskCachehotCache= DiskLruCacheWrapper.create(newFile("/ssd/hot"), 100 * 1024 * 1024// 100MB
);
// 冷数据区(HDD大容量,LFU淘汰算法)
DiskCachecoldCache= DiskLruCacheWrapper.create(newFile("/hdd/cold"), 500 * 1024 * 1024// 500MB
);
// 根据URL路由存储
if (url.contains("/avatar/")) return hotCache;
if (url.contains("/history/")) return coldCache;
技术亮点:磁盘空间利用率提升60%
第三层:网络预加载智能降级
Glide.with(context).load(url).apply(RequestOptions()// 滑动速度>3000px/s时加载缩略图.override(if (scrollSpeed > 3000) 100 else SIZE_ORIGINAL) // 滑动中降级为NORMAL优先级.priority(when (scrollSpeed) {in 0..2000 -> HIGHin 2001..5000 -> NORMALelse -> LOW}))
技术效果:流量节省35%,首屏加载速度提升40%
第四层:BitmapPool硬件级复用
// 开启RGB_565硬解码(内存占用减少50%)
GlideBuilder().setDefaultRequestOptions(RequestOptions().format(DecodeFormat.PREFER_RGB_565) .set(Downsampler.ALLOW_HARDWARE_DECODE_CONFIG, true)
);
// 复用池扩容(防止大图重复解码)
val bitmapPool = LruBitmapPool(Runtime.getRuntime().maxMemory() / 8
)
核心原理:利用GPU纹理复用技术,显存占用下降70%
三、高频面试题破解(P8考官视角)
问题1:Glide如何生成缓存Key?为什么同一图片不同尺寸会生成多个Key?
答案深度:
• Key由8个参数哈希生成:URL、宽、高、Transformation等
• 关键源码定位:Engine.load()→KeyFactory.buildKey()
• 优化方案:重写hashCode()合并相似尺寸(如将100x100与102x98视为相同Key)
问题2:LruCache如何实现线程安全?LinkedHashMap参数true的作用?
源码级解析:
• 线程安全实现:LinkedHashMap+同步锁
• LinkedHashMap(true)表示按访问顺序排序,最近访问元素移至链表头
• 淘汰逻辑:trimToSize()时删除链表尾部元素(LRU算法)
问题3:如何防止加载10MB大图导致OOM?
阿里P8级方案:
// 1. 强制限制解码尺寸(硬件加速)
.override(screenWidth, screenHeight)
// 2. 分块加载(类似地图应用瓦片加载)
.set(Option.memory(BitmapDecoder.PREFER_SUBSAMPLING), true)
// 3. 启用Native内存分配(Android 8.0+)
if (Build.VERSION.SDK_INT >= 26) {imageView.setLayerType(View.LAYER_TYPE_HARDWARE, null)
}
四、性能优化核武器(生产级解决方案)
-
1. 监控体系搭建
• 内存泄漏检测:MemoryCache.addOnEntryRemovedListener接入LeakCanary
• 磁盘命中率统计:重写DiskCache记录Key访问日志
-
2. 动态预热策略
// 充电时预加载次日所需图片(JobScheduler)
JobInfo jobInfo = new JobInfo.Builder(1, PreloadService.class).setRequiresCharging(true).setPeriodic(6 * 60 * 60 * 1000) // 每6小时.build();
3. OOM防护兜底
// 全局Bitmap加载拦截器(超过屏幕尺寸2倍则降级)
Glide.init(context,GlideBuilder().addBitmapPreprocessor { bitmap ->if (bitmap.allocationByteCount > maxMemory / 4) {return Bitmap.createScaledBitmap(bitmap, screenWidth, screenHeight, true)}bitmap}
)
扩展:
一、Glide缓存机制深度解剖(面试必考点)
1.1 三级缓存架构核心原理
Glide默认采用内存缓存(ActiveResources+MemoryCache) + 磁盘缓存(DiskCache) + 网络加载的三级架构:
• ActiveResources:强引用缓存,存储正在展示的图片(防GC回收)
• MemoryCache:LRU内存缓存,默认占App可用内存的1/8
• DiskCache:LRU磁盘缓存,支持DATA(原始数据)和RESOURCE(解码后数据)两种策略
1.2 默认配置的四大致命缺陷
-
1. 内存缓存僵化:固定比例分配,无法适配不同机型(如6GB与12GB内存手机)
-
2. 磁盘缓存混存:原始数据和转换后数据混杂,空间利用率低30%
-
3. 网络加载粗暴:无优先级管理,快速滑动时仍加载不可见图
-
4. 资源回收滞后:SoftReference导致GC不及时,引发OOM
二、三级缓存改造实战手册
2.1 内存缓存动态扩容(LruCache魔改)
痛点:低端机内存吃紧时频繁GC,高端机内存浪费
解决方案:
class DynamicLruCache(context: Context) : LruCache<Key, Bitmap>( // 根据设备内存动态计算 (Runtime.getRuntime().maxMemory() / 1024 / 8).toInt()
) { // 增加权重计算(大图占用更多缓存份额) overridefunsizeOf(key: Key, value: Bitmap): Int { return value.byteCount / 1024 * when { value.width > 2000 -> 2value.height > 1000 -> 1.5else -> 1} }
} // 配置到GlideModule
builder.setMemoryCache(DynamicLruCache(context))
关键技术点:
• 引入Bitmap尺寸权重系数
• 结合DisplayMetrics动态调整maxSize
2.2 磁盘缓存分区优化(DiskLruCache改造)
痛点:用户头像与高清大图混合存储,缓存命中率低
分层存储方案:
// 创建不同存储池
DiskCachesmallImageCache= DiskLruCacheWrapper.create( newFile(context.getCacheDir(), "small"), 20 * 1024 * 1024// 20MB
); DiskCachelargeImageCache= DiskLruCacheWrapper.create( newFile(context.getCacheDir(), "large"), 100 * 1024 * 1024// 100MB
); // 根据URL特征路由
if (url.contains("/avatar/")) { return smallImageCache;
} elseif (url.contains("/wallpaper/")) { return largeImageCache;
}
技术亮点:
• 按业务场景划分存储池
• 采用AES-256加密敏感缩略图
2.3 网络预加载智能降级
痛点:快速滑动时仍加载不可见图,浪费流量
智能加载策略:
Glide.with(context) .load(url) .apply( RequestOptions() // 根据滑动速度动态调整优先级 .priority( when (scrollSpeed) { in0..2000 -> Priority.HIGH in2001..5000 -> Priority.NORMAL else -> Priority.LOW } ) // 开启智能降级 .override( if (scrollSpeed > 3000) 100else Target.SIZE_ORIGINAL ) )
核心逻辑:
• 基于RecyclerView滑动速度动态调整优先级
• 高速滑动时加载缩略图,停止后替换高清图
三、性能优化核武器:混合预加载策略
3.1 内存预热黑科技
// 在Application初始化时预加载关键资源
Glide.with(context) .load(Urls.CRITICAL_IMAGES) .preload(200, 200); // 结合JobScheduler在充电时预热
JobSchedulerscheduler= (JobScheduler) context.getSystemService(JOB_SCHEDULER_SERVICE);
JobInfojobInfo=newJobInfo.Builder(1, newComponentName(context, PreloadService.class)) .setRequiresCharging(true) .build();
scheduler.schedule(jobInfo);
技术价值:
• 首屏加载速度提升40%
• 利用系统空闲时段更新缓存
3.2 磁盘缓存冷热分离
• 热数据区:保留最近3天访问记录(SSD加速)
• 冷数据区:存储历史数据(HDD大容量)
• 淘汰策略:热区用LRU,冷区用LFU
四、高频面试题深度破解
Q1:Glide如何防止加载大图导致OOM?
标准答案+优化方案:
- 1. 默认方案:
• 根据ImageView尺寸自动计算采样率
• 采用BitmapPool复用内存
-
2. 进阶方案:
/ 强制限制解码尺寸
.override(deviceWidth, deviceHeight)
// 开启硬件加速解码
.format(DecodeFormat.PREFER_RGB_565)
// 大图分块加载
.set(Downsampler.ALLOW_HARDWARE_DECODE_CONFIG, true)
Q2:LruCache和DiskLruCache如何实现线程安全?
实现原理:
- 1. LruCache:
• 使用LinkedHashMap+同步锁
• trimToSize()时计算权重
- 2. DiskLruCache:
• 通过Journal日志文件保证原子性
• 采用Double-check Locking优化读写锁
从原理到实践的跨越
通过三级缓存改造,我们在某电商App中实现:
• 内存占用下降45%:DynamicLruCache动态调节
• 磁盘空间利用率提升60%:冷热分区+业务隔离
• FPS波动率降低至5%以内:智能预加载策略
立即行动:
-
1. 在GlideModule中接入MemoryCache监控
// 添加内存泄漏检测
MemoryCache.addOnEntryRemovedListener { LeakCanary.detectLeak(it.bitmap)
}
2. 使用Android Studio的Memory Profiler抓取缓存快照
扩展追问:
面试题目1:解释Glide的缓存机制是如何工作的?
解答:
Glide的缓存机制包括内存缓存和磁盘缓存,以提高图片加载的性能和减少网络请求。
1、 内存缓存:
-
Glide使用
LruResourceCache来实现内存缓存,它会根据最近最少使用(LRU)算法来管理内存中的图片资源。 -
当内存不足时,会自动清除最久未使用的图片资源。
2、 磁盘缓存:
-
Glide使用
DiskLruCache来实现磁盘缓存,它会将图片资源存储在设备存储中。 -
磁盘缓存可以避免重复的网络请求,并且即使应用被关闭,图片资源仍然可以被保留。
3、 缓存键值:
-
Glide通过图片的URL和图片的尺寸等信息生成一个唯一的键值,用于在缓存中查找和存储图片资源。
4、 缓存大小:
-
Glide会根据设备的可用内存动态计算内存缓存的大小,通常限制在可用内存的一定比例内。
面试题目2:如何自定义Glide的缓存行为?
解答:
通过DiskCacheStrategy枚举,可以自定义Glide的缓存行为:
1、 DiskCacheStrategy.ALL:
-
缓存原始图片和转换后的图片到磁盘缓存。
2、 DiskCacheStrategy.NONE:
-
不使用磁盘缓存。
3、 DiskCacheStrategy.RESOURCE:
-
只缓存转换后的图片到磁盘缓存。
4、 DiskCacheStrategy.DATA:
-
只缓存原始图片到磁盘缓存。
自定义缓存行为的示例代码:
Glide.with(context).load(imageUrl).diskCacheStrategy(DiskCacheStrategy.ALL).into(imageView)
面试题目3:Glide如何处理并发请求?
解答:
Glide使用请求队列来管理并发请求,确保以最佳顺序加载图片。
1、 请求队列:
-
当多个图片请求被触发时,Glide会将这些请求添加到一个队列中。
2、 请求合并:
-
如果同一个图片资源被多次请求,Glide会合并这些请求,避免重复的网络请求和磁盘缓存写入。
3、 优先级设置:
-
可以为每个图片请求设置优先级,Glide会根据优先级顺序处理请求。
4、 生命周期管理:
-
Glide会根据Activity或Fragment的生命周期自动暂停或恢复图片加载请求。
面试题目4:如何使用Glide实现渐进式图像加载?
解答:
Glide支持渐进式图像加载,即先加载低分辨率的图片,然后逐渐加载更高分辨率的图片。
1、 使用progressiveLoad()方法:
-
在
RequestBuilder中调用progressiveLoad()方法来启用渐进式加载。
示例代码:
Glide.with(context).load(imageUrl).progressiveLoad().into(imageView)
2、 配置渐进式加载参数:
-
可以配置渐进式加载的间隔时间和动画效果。
面试题目5:如何监控Glide的图像加载性能?
解答:
Glide提供了日志记录和性能监控的功能,可以跟踪图像加载过程和性能。
1、 开启日志记录:
-
通过设置Glide的日志级别,可以输出详细的日志信息,帮助调试和监控性能。
2、 使用RequestListener:
-
实现
RequestListener接口,监听图片加载的成功和失败事件。
3、 性能监控:
-
可以使用Android的Profiler工具监控Glide的内存使用和CPU占用。
示例代码:
Glide.with(context).load(imageUrl).listener(object : RequestListener<Drawable> {override fun onLoadFailed(e: GlideException?, model: Any?, target: Target<Drawable>?, isFirstResource: Boolean): Boolean {// 处理加载失败return false}override fun onResourceReady(resource: Drawable?, model: Any?, target: Target<Drawable>?, dataSource: DataSource, isFirstResource: Boolean): Boolean {// 处理加载成功return false}}).into(imageView)
希望这篇文章可以对你的Android学习有帮助!!!
感谢观看!!!
相关文章:
Android面试总结之Glide源码级理解
当你的图片列表在低端机上白屏3秒、高端机因内存浪费导致FPS腰斩时,根源往往藏在Glide的内存分配僵化、磁盘混存、网络加载无优先级三大致命缺陷中。 本文从阿里P8级缓存改造方案出发,结合Glide源码实现动态内存扩容、磁盘冷热分区、智能预加载等黑科技&…...
Pyside6 开发 使用Qt Designer
使用Qt Designer 在Scripts目录下打开pyside6-designer.exe 分别将姓名、年龄、爱好对应的输入框的ObjectName 设置为 uname、uage、ulike 提交按钮Object设置为 btnSubmit 点击保存文件 ,命名为student.ui 将.ui文件编程成.py文件 pyside6-uic student.ui -o st…...
PyQt6实例_批量下载pdf工具_使用pyinstaller与installForge打包成exe文件
目录 前置: 步骤: step one 准备好已开发完毕的项目代码 step two 安装pyinstaller step three 执行pyinstaller pdfdownload.py,获取初始.spec文件 step four 修改.spec文件,将data文件夹加入到打包程序中 step five 增加…...
局域网共享失败?打印机/文件夹共享工具
很多时候,在办公或家庭环境中,我们需要进行打印机和文件夹的共享,以便更高效地协作和处理文件。然而,寻找对应版本的共享设置或是不想花费太多时间去进行复杂的电脑设置,总是让人感到头疼。今天,我要向大家…...
DeepSeek-V3-250324: AI模型新突破,性能超越GPT-4.5
DeepSeek 于 3 月 25 日宣布完成 V3 模型的小版本升级,推出 DeepSeek-V3-250324 版本。新版本在推理能力、代码生成、中文写作及多模态任务上实现显著优化,尤其在数学和代码类评测中得分超越 GPT-4.5,引发行业高度关注。 DeepSeek-V3-250324…...
第R9周:阿尔兹海默症诊断(优化特征选择版)
🍨 本文为🔗365天深度学习训练营 中的学习记录博客🍖 原作者:K同学啊 文章目录 1、导入数据2、数据处理2.1 患病占比2.2 相关性分析2.3 年龄与患病探究 3、特征选择4、构建数据集4.1 数据集划分与标准化4.2 构建加载 5、构建模型6…...
19726 星际旅行
19726 星际旅行 ⭐️难度:困难 🌟考点:Dijkstra、省赛、最短路问题、期望、2024 📖 📚 import java.util.*;public class Main {static int N 1005;static ArrayList<Integer>[] g new ArrayList[N]; // …...
DeepSeek大模型应用开发新模式
DeepSeek大模型应用全景技术架构 DeepSeek大模型 VS 主流大模型 DeepSeek大模型系统提示词 VS 主流大模型 DeepSeek大模型迭代版本 DeepSeek专业化模型分类 DeepSeek大模型部署所需显存资源 DeepSeek不同参数模型及应用场景 DeepSeek大模型安装部署技术选型...
代码随想录动态规划05
74.一和零 视频讲解:动态规划之背包问题,装满这个背包最多用多少个物品?| LeetCode:474.一和零_哔哩哔哩_bilibili 代码随想录 给你一个二进制字符串数组 strs 和两个整数 m 和 n 。 请你找出并返回 strs 的最大子集的大小&#…...
Next.js 深度解析:全栈React框架的架构哲学与实践精髓
Next.js 作为 React 生态中最流行的全栈框架,已经超越了简单的SSR工具,发展成为完整的Web开发解决方案。以下从八个维度进行深度剖析: 一、核心架构设计 双引擎驱动模型 页面路由系统:基于文件系统的约定式路由渲染引擎ÿ…...
Node.js Express 处理静态资源
目录 1. 什么是静态资源? 2. 安装 Express 3. 目录结构 4. 创建 server.js 5. 创建 public/index.html 6. 创建 public/style.css 7. 创建 public/script.js 8. 运行服务器 9. 结语 1. 什么是静态资源? 静态资源指的是 HTML、CSS、JavaScript、…...
2025企业级项目设计三叉戟:权限控制+错误监控+工程化提效实战指南
一、权限系统设计:动态路由与按钮级控制的终极方案 1. 权限系统架构设计痛点 路由权限滞后:传统方案需页面加载后动态计算路由表,导致首屏白屏时间增加30%按钮颗粒度不足:基于角色的权限控制(RBAC)无法满…...
DeepSeek-V3新版本DeepSeek-V3-0324
中国人工智能初创公司深度求索(DeepSeek)2025年3月24日深夜低调上线了DeepSeek-V3的新版本DeepSeek-V3-0324,参数量为6850亿,在代码、数学、推理等多个方面的能力再次显著提升,甚至代码能力追平美国Anthropic公司大模型…...
108回回目设计
由于108回完整目录篇幅极长,我将以分卷缩略核心回目详解形式呈现,既保证完整性,又避免信息过载。以下是凝练后的完整框架与部分代表性回目: 第一卷:京口草鞋摊的野望(1-36回) 核心矛盾…...
探索:如何构建一个自我的AI辅助的开发环境?
构建支持AI的开发辅助环境并实现全流程自动化,需要整合开发工具链、AI模型服务和自动化流水线。以下是分步实施指南,包含关键技术栈和架构设计: 一、开发环境基础架构 1. 工具链集成平台 #mermaid-svg-RFSaibQJwVEcW9fT {font-family:"…...
国产RISC-V车规芯片当前现状分析——从市场与技术角度出发
摘要 随着汽车产业的智能化、电动化转型加速,车规级芯片的战略地位日益凸显。RISC-V指令集凭借其开源、灵活、低功耗等优势,成为国产车规芯片的重要发展方向。本文从市场与技术两个维度出发,深入分析国产RISC-V车规芯片的现状。通过梳理国内…...
华为eNSP-配置静态路由与静态路由备份
一、静态路由介绍 静态路由是指用户或网络管理员手工配置的路由信息。当网络拓扑结构或者链路状态发生改变时,需要网络管理人员手工修改静态路由信息。相比于动态路由协议,静态路由无需频繁地交换各自的路由表,配置简单,比较适合…...
数据分析中,文件解析库解析内容样式调整(openpyxl 、tabulate)
CSV文件:使用Python标准库中的csv模块,通过简单的文本解析来读取数据。 Excel文件:使用专门的库(如openpyxl、xlrd)来解析复杂的文件格式,或者使用pandas库来简化读取过程。 openpyxl openpyxl 是一个 Pyt…...
时尚界正在试图用AI,创造更多冲击力
数字艺术正以深度融合的方式,在时尚、游戏、影视等行业实现跨界合作,催生了多样化的商业模式,为创作者和品牌带来更多机会,数字艺术更是突破了传统艺术的限制,以趣味触达用户,尤其吸引了年轻一代的消费群体…...
ai画图comfyUI 精准定位gligen。允许指定图像中多个对象的位置和大小
基础功能下,outpainting是内容填充,拉近拉远镜头,自动填充旁边物体。嵌入模型也需要单独下载,演示完示例后推荐模型站有更直观效果介绍和用法。选中精确定位。看一眼坐标,直接默认出一张图。然后修改定位,和…...
Python @property 装饰器深度使用教程
一、基础概念与核心原理 1. 装饰器本质 property 是 Python 内置的属性管理装饰器,它将类方法转换为类属性访问接口。其核心价值在于: 封装性:隐藏属性操作的具体实现可维护性:在不改变外部接口的前提下修改内部逻辑安全…...
#VCS# 关于 +incdir+xxx 编译选项的注意点
前段时间,工作中遇到百思不得其解的坑。 按照以往的理解,没有找到任何可能问题点。今天总结下来。 学习目标: +incdir+ 是 VCS 编译器中用于指定 包含文件(include files) 搜索路径的重要选项,主要用于指定 `include 指令的搜索目录。 一 基本功能 作用:添加 Verilog/S…...
DeepSeek 助力 Vue3 开发:打造丝滑的表格(Table)之添加行拖拽排序功能示例7,TableView16_07 列拖拽排序示例
前言:哈喽,大家好,今天给大家分享一篇文章!并提供具体代码帮助大家深入理解,彻底掌握!创作不易,如果能帮助到大家或者给大家一些灵感和启发,欢迎收藏+关注哦 💕 目录 DeepSeek 助力 Vue3 开发:打造丝滑的表格(Table)之添加行拖拽排序功能示例7,TableView16_07 列…...
JAVA学习-练习试用Java实现“实现一个Hadoop程序,对大数据集中的文本数据进行自然语言处理和关键词筛选”
问题: 使用java语言,实现一个Hadoop程序,对大数据集中的文本数据进行自然语言处理和关键词筛选。 解答思路: 使用Java语言和Hadoop实现自然语言处理和关键词筛选,你需要创建一个MapReduce程序。以下是一个简单的示例&…...
使用idea开发spark程序
新建scala 项目 创建lib目录 将spark jars/ 路径下所有jar 复制到 lib目录 添加依赖 创建scala 程序 package sparkimport org.apache.spark.{SparkConf, SparkContext}object WordCount {def main(args: Array[String]): Unit {val conf new SparkConf().setAppName(&q…...
看懂roslunch输出
自编了一个demo 第一步:创建功能包 cd ~/catkin_ws/src catkin_create_pkg param_demo roscpp第二步:写 main.cpp 创建文件:param_demo/src/param_node.cpp #include <ros/ros.h> #include <string>int main(int argc, char*…...
洛谷题单1-B2005 字符三角形-python-流程图重构
题目描述 给定一个字符,用它构造一个底边长 5 5 5 个字符,高 3 3 3 个字符的等腰字符三角形。 输入格式 输入只有一行,包含一个字符。 输出格式 该字符构成的等腰三角形,底边长 5 5 5 个字符,高 3 3 3 个字符…...
学习日记0327
A cross-domain knowledge tracing model based on graph optimal transport 我们使用gnn来学习这些节点的特征。在此基础上,我们使用显式分布距离度量对齐来自两个不同域的特征向量,旨在最小化域差异,实现最大的跨域知识转移。 AEGOT-CDKT…...
CSS学习笔记6——网页布局
目录 一、元素的浮动属性、清除浮动 清除浮动的其他方法 1、使用空标签清除浮动影响 2、使用overflow属性清除浮动 3、使用伪元素清除浮动影响 原理 overflow属性 二、元素的定位 1、相对定位 2、绝对定位 编辑 3、固定定位 z-index层叠等级属性 一、元素的浮动…...
dubbo http流量接入dubbo后端服务
简介 dubbo协议是基于TCP的二进制私有协议,更适合作为后端微服务间的高效RPC通信协议,也导致dubbo协议对于前端流量接入不是很友好。在dubo框架中,有两种方式可以解决这个问题: 多协议发布【推荐】,为dubbo协议服务暴…...
