面试官:关于Glide常问的几个问题你掌握多少?答对了直接绿卡!

先自我介绍一下,小编浙江大学毕业,去过华为、字节跳动等大厂,目前阿里P7

深知大多数程序员,想要提升技能,往往是自己摸索成长,但自己不成体系的自学效果低效又漫长,而且极易碰到天花板技术停滞不前!

因此收集整理了一份《2024年最新Android移动开发全套学习资料》,初衷也很简单,就是希望能够帮助到想自学提升又不知道该从何学起的朋友。
img
img
img
img
img
img
img

既有适合小白学习的零基础资料,也有适合3年以上经验的小伙伴深入学习提升的进阶课程,涵盖了95%以上Android开发知识点,真正体系化!

由于文件比较多,这里只是将部分目录截图出来,全套包含大厂面经、学习笔记、源码讲义、实战项目、大纲路线、讲解视频,并且后续会持续更新

如果你需要这些资料,可以添加V获取:vip204888 (备注Android)
img

正文

面试官1:Glide的三级缓存有了解过么?

  • 先来了解一下我们常说的图片三级缓存:

一般是强引用,软引用和文件系统,Android系统中提供了LruCache,通过维护一个LinkedHashMap来保存我们需要的各种类型数据,例如我们这里需要的Bitmap。LruCache一般我们会设置为系统最大存储空间的八分之一,而它的机制就是我们常说的最近最少使用原则,如果Lru中的图片大小超过了默认大小,则会把最久使用的图片移除。

当图片被Lru移除时,我们需要手动将图片添加到软引用(SoftRefrence)中。需要维护一个软应用的集合在我们的项目中。

  • 简单概括一下常用的三级缓存的流程:

先去Lru中找,有则直接取。

没有,则去SoftRefrence中找,有则取,同时将图片放回Lru中。

没有的话去文件系统找,有则取,同时将图片添加到Lru中。

没有就走下载图片逻辑,保存到文件系统中,并放到Lru中。

下面介绍一下Glide的缓存结构:

Glide缓存严格意义上说只有内存缓存和磁盘缓存,内存缓存中又分为Lru和弱引用缓存。

所以Glide的三级缓存可以分为:Lru缓存,弱引用缓存,磁盘缓存。

下面我们看一下Glide的读取顺序,这里有一点不同,我用的是Glide4.8版本,跟之前版本的写入顺序稍有不同。

截取部分源码:

@NonNull

Glide build(@NonNull Context context) {

if (memoryCache == null) {

memoryCache = new LruResourceCache(memorySizeCalculator.getMemoryCacheSize());

}

if (engine == null) {

engine =

new Engine(

memoryCache,

diskCacheFactory,

diskCacheExecutor,

sourceExecutor,

GlideExecutor.newUnlimitedSourceExecutor(),

GlideExecutor.newAnimationExecutor(),

isActiveResourceRetentionAllowed);

}

  • memoryCache就是Glide使用的内存缓存,LruResourceCache类继承了LruCache,这部分可以自行查看一下源码。

通过上面可以看到,GLide#build()方法中实例化memoryCache作为Glide的内存缓存,并将其传给Engine作为构造器的入参。

  • Engine.class 截取部分源码

{

//生成缓存key

EngineKey key = keyFactory.buildKey(model, signature, width, height, transformations,

resourceClass, transcodeClass, options);

//从弱应用中读取缓存

EngineResource<?> active = loadFromActiveResources(key, isMemoryCacheable);

if (active != null) {

cb.onResourceReady(active, DataSource.MEMORY_CACHE);

if (VERBOSE_IS_LOGGABLE) {

logWithTimeAndKey(“Loaded resource from active resources”, startTime, key);

}

return null;

}

//从LruCache中读取缓存

EngineResource<?> cached = loadFromCache(key, isMemoryCacheable);

if (cached != null) {

cb.onResourceReady(cached, DataSource.MEMORY_CACHE);

if (VERBOSE_IS_LOGGABLE) {

logWithTimeAndKey(“Loaded resource from cache”, startTime, key);

}

return null;

}

EngineJob engineJob =

engineJobFactory.build(

key,

isMemoryCacheable,

useUnlimitedSourceExecutorPool,

useAnimationPool,

onlyRetrieveFromCache);

jobs.put(key, engineJob);

engineJob.addCallback(cb);

//开启线程池,加载图片

engineJob.start(decodeJob);

}

从上可知,Glide加载过程中使用loadFromActiveResources方法和loadFromCache方法来获取内存缓存的。

大致总结一下:

首先从弱引用读取缓存,没有的话通过Lru读取,有则取,并且加到弱引用中,如果没有会开启EngineJob进行后面的图片加载逻辑。

下面直接看之后的缓存部分代码:

  • Engine#onEngineJobComplete()

public void onEngineJobComplete(EngineJob<?> engineJob, Key key, EngineResource<?> resource) {

Util.assertMainThread();

// A null resource indicates that the load failed, usually due to an exception.

if (resource != null) {

resource.setResourceListener(key, this);

if (resource.isCacheable()) {

activeResources.activate(key, resource);

}

}

jobs.removeIfCurrent(key, engineJob);

}

void activate(Key key, EngineResource<?> resource) {

ResourceWeakReference toPut =

new ResourceWeakReference(

key,

resource,

getReferenceQueue(),

isActiveResourceRetentionAllowed);

ResourceWeakReference removed = activeEngineResources.put(key, toPut);

if (removed != null) {

removed.reset();

}

}

这里可以看到activeResources.activate(key, resource)把EngineResource放到了弱引用中,至于lru的放置逻辑如下:

  • EngineResource#release()

void release() {

if (acquired <= 0) {

throw new IllegalStateException(“Cannot release a recycled or not yet acquired resource”);

}

if (!Looper.getMainLooper().equals(Looper.myLooper())) {

throw new IllegalThreadStateException(“Must call release on the main thread”);

}

if (–acquired == 0) {

listener.onResourceReleased(key, this);

}

}

当acquired变量大于0的时候,说明图片正在使用中,也就应该放到activeResources弱引用缓存当中。而经过release()之后,如果acquired变量等于0了,说明图片已经不再被使用了,那么此时会调用listener的onResourceReleased()方法来释放资源。

  • Engine#onResourceReleased()

@Override

public void onResourceReleased(Key cacheKey, EngineResource<?> resource) {

Util.assertMainThread();

activeResources.deactivate(cacheKey);

if (resource.isCacheable()) {

cache.put(cacheKey, resource);

} else {

resourceRecycler.recycle(resource);

}

}

这里首先会将缓存图片从activeResources中移除,然后再将它put到LruResourceCache当中。这样也就实现了正在使用中的图片使用弱引用来进行缓存,不在使用中的图片使用LruCache来进行缓存的功能。

接下来就是Glide的磁盘缓存,磁盘缓存简单来说就是根据Key去DiskCache中取缓存,有兴趣可以自行看一下源码。

面试官2:为什么选择Glide不选择其他的图片加载框架?

  • Glide和Picasso

前者要更加省内存,可以按需加载图片,默认为ARGB_565,后者为ARGB_8888。

前者支持Gif,后者并不支持。

  • Glide和Fresco

Fresco低版本有优势,占用部分native内存,但是高版本一样是java内存。

Fresco加载对图片大小有限制,Glide基本没有。

Fresco推荐使用SimpleDraweeView,涉及到布局文件,这就不得不考虑迁移的成本。

Fresco有很多native的实现,想改源码成本要大的多。

Glide提供对中TransFormation帮助处理图片,Fresco并没有。

Glide版本迭代相对较快。

Glide的几个显著的优点:

  • 生命周期的管理

GLide#with

@NonNull

public static RequestManager with(@NonNull Context context) {

return getRetriever(context).get(context);

}

@NonNull

public static RequestManager with(@NonNull Activity activity) {

return getRetriever(activity).get(activity);

}

@NonNull

public static RequestManager with(@NonNull FragmentActivity activity) {

return getRetriever(activity).get(activity);

}

@NonNull

public static RequestManager with(@NonNull Fragment fragment) {

return getRetriever(fragment.getActivity()).get(fragment);

}

@Deprecated

@NonNull

public static RequestManager with(@NonNull android.app.Fragment fragment) {

文末

面试:如果不准备充分的面试,完全是浪费时间,更是对自己的不负责!

不管怎么样,不论是什么样的大小面试,要想不被面试官虐的不要不要的,只有刷爆面试题题做好全面的准备,当然除了这个还需要在平时把自己的基础打扎实,这样不论面试官怎么样一个知识点里往死里凿,你也能应付如流啊

网上学习资料一大堆,但如果学到的知识不成体系,遇到问题时只是浅尝辄止,不再深入研究,那么很难做到真正的技术提升。

需要这份系统化的资料的朋友,可以添加V获取:vip204888 (备注Android)
img

一个人可以走的很快,但一群人才能走的更远!不论你是正从事IT行业的老鸟或是对IT行业感兴趣的新人,都欢迎加入我们的的圈子(技术交流、学习资源、职场吐槽、大厂内推、面试辅导),让我们一起学习成长!

uestManager with(@NonNull android.app.Fragment fragment) {

文末

面试:如果不准备充分的面试,完全是浪费时间,更是对自己的不负责!

不管怎么样,不论是什么样的大小面试,要想不被面试官虐的不要不要的,只有刷爆面试题题做好全面的准备,当然除了这个还需要在平时把自己的基础打扎实,这样不论面试官怎么样一个知识点里往死里凿,你也能应付如流啊

网上学习资料一大堆,但如果学到的知识不成体系,遇到问题时只是浅尝辄止,不再深入研究,那么很难做到真正的技术提升。

需要这份系统化的资料的朋友,可以添加V获取:vip204888 (备注Android)
[外链图片转存中…(img-ZjFGeis2-1713385442019)]

一个人可以走的很快,但一群人才能走的更远!不论你是正从事IT行业的老鸟或是对IT行业感兴趣的新人,都欢迎加入我们的的圈子(技术交流、学习资源、职场吐槽、大厂内推、面试辅导),让我们一起学习成长!

  • 24
    点赞
  • 19
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
东南亚位于我国倡导推进的“一带一路”海陆交汇地带,作为当今全球发展最为迅速的地区之一,近年来区域内生产总值实现了显著且稳定的增长。根据东盟主要经济体公布的最新数据,印度尼西亚2023年国内生产总值(GDP)增长5.05%;越南2023年经济增长5.05%;马来西亚2023年经济增速为3.7%;泰国2023年经济增长1.9%;新加坡2023年经济增长1.1%;柬埔寨2023年经济增速预计为5.6%。 东盟国家在“一带一路”沿线国家中的总体GDP经济规模、贸易总额与国外直接投资均为最大,因此有着举足轻重的地位和作用。当前,东盟与中国已互相成为双方最大的交易伙伴。中国-东盟贸易总额已从2013年的443亿元增长至 2023年合计超逾6.4万亿元,占中国外贸总值的15.4%。在过去20余年中,东盟国家不断在全球多变的格局里面临挑战并寻求机遇。2023东盟国家主要经济体受到国内消费、国外投资、货币政策、旅游业复苏、和大宗商品出口价企稳等方面的提振,经济显现出稳步增长态势和强韧性的潜能。 本调研报告旨在深度挖掘东南亚市场的增长潜力与发展机会,分析东南亚市场竞争态势、销售模式、客户偏好、整体市场营商环境,为国内企业出海开展业务提供客观参考意见。 本文核心内容: 市场空间:全球行业市场空间、东南亚市场发展空间。 竞争态势:全球份额,东南亚市场企业份额。 销售模式:东南亚市场销售模式、本地代理商 客户情况:东南亚本地客户及偏好分析 营商环境:东南亚营商环境分析 本文纳入的企业包括国外及印尼本土企业,以及相关上下游企业等,部分名单 QYResearch是全球知名的大型咨询公司,行业涵盖各高科技行业产业链细分市场,横跨如半导体产业链(半导体设备及零部件、半导体材料、集成电路、制造、封测、分立器件、传感器、光电器件)、光伏产业链(设备、硅料/硅片、电池片、组件、辅料支架、逆变器、电站终端)、新能源汽车产业链(动力电池及材料、电驱电控、汽车半导体/电子、整车、充电桩)、通信产业链(通信系统设备、终端设备、电子元器件、射频前端、光模块、4G/5G/6G、宽带、IoT、数字经济、AI)、先进材料产业链(金属材料、高分子材料、陶瓷材料、纳米材料等)、机械制造产业链(数控机床、工程机械、电气机械、3C自动化、工业机器人、激光、工控、无人机)、食品药品、医疗器械、农业等。邮箱:market@qyresearch.com

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值