最后
光有这些思路和搞懂单个知识的应用是还远远不够的,在Android开源框架设计思想中的知识点还是比较多的,想要搞懂还得学会整理和规划:我们常见的**Android热修复框架、插件化框架、组件化框架、图片加载框架、网络访问框架、RxJava响应式编程框架、IOC依赖注入框架、最近架构组件Jetpack等等Android第三方开源框架,**这些都是属于Android开源框架设计思想的。如下图所示:
这位阿里P8大佬针对以上知识点,熬夜整理出了一本长达1042页的完整版如何解读开源框架设计思想PDF文档,内容详细,把Android热修复框架、插件化框架、组件化框架、图片加载框架、网络访问框架、RxJava响应式编程框架、IOC依赖注入框架、最近架构组件Jetpack等等Android第三方开源框架这些知识点从源码分析到实战应用都讲的简单明了。
由于文档内容过多,篇幅受限,只能截图展示部分
整理不易,觉得有帮助的朋友可以帮忙点赞分享支持一下小编~
你的支持,我的动力;祝各位前程似锦,offer不断!!!
网上学习资料一大堆,但如果学到的知识不成体系,遇到问题时只是浅尝辄止,不再深入研究,那么很难做到真正的技术提升。
一个人可以走的很快,但一群人才能走的更远!不论你是正从事IT行业的老鸟或是对IT行业感兴趣的新人,都欢迎加入我们的的圈子(技术交流、学习资源、职场吐槽、大厂内推、面试辅导),让我们一起学习成长!
throw new IllegalArgumentException();
}
count = i;
putIndex = (i == capacity) ? 0 : i;
} finally {
lock.unlock();
}
}
从三个构造方法中可以看出主要是capacity、fair这两个的不同参数
capacity:设置容量,必传值
fair:是否公平,默认值为false,是设置ReentrantLock是公平锁还是非公平锁的
预备知识
ReentrantLock是一个支持响应中断、超时、尝试获取锁,可关联多个条件队列,是个可重入的公平锁和非公平锁。
Condition这个主要是用来实现ReentrantLock的wait和notify的功能
增删改查
入队操作
public void put(E e) throws InterruptedException {
//检验元素是否为空,为null就抛出空指针异常
checkNotNull(e);
//拿到当前的锁
final ReentrantLock lock = this.lock;
//进行锁的抢占
lock.lockInterruptibly();
try {
//当队列长度等于数组长度,表示队列已满,这里使用while来循环等待被唤醒
while (count == items.length)
//put操作时让当前线程处于等待状态
notFull.await();
//当队列没有满并且获取到锁时就进行enqueue入队操作
enqueue(e);
} finally {
//完成锁的释放
lock.unlock();
}
}
private static void checkNotNull(Object v) {
if (v == null)
throw new NullPointerException();
}
private void enqueue(E x) {
// assert lock.getHoldCount() == 1;
// assert items[putIndex] == null;
final Object[] items = this.items;
//设置当前数组putIndex位置的元素为x,这里是尾部插入
items[putIndex] = x;
//putIndex++,然后如果putIndex的大小等于数据的长度,则设置putIndex=0,这里是循环队列的思想
if (++putIndex == items.length)
putIndex = 0;
//元素的个数+1
count++;
//put操作结束,唤醒其他正在处于等待状态的线程
notEmpty.signal();
}
另外offer()函数也可以入队,思路也差不多,也可以了解一下,总结一下入队操作,先检查,然后判断队列没有满并且拿到锁进行入队操作进行设置数组相关位置的值,设置完成,唤醒其他处于等待状态的线程
删除元素
remove()具体元素的出队
public boolean remove(Object o) {
//出队的元素为null,直接返回失败
if (o == null) return false;
//得到数据
final Object[] items = this.items;
//拿到锁
final ReentrantLock lock = this.lock;
//进行锁住操作
lock.lock();
try {
if (count > 0) {
final int putIndex = this.putIndex;
int i = takeIndex;
//循环查找i位置的数据释放就是要删除出队的数据,如果是就进行删除
do {
if (o.equals(items[i])) {
removeAt(i);
return true;
}
if (++i == items.length)
i = 0;
} while (i != putIndex);
}
//元素个数没有大于0直接返回失败
return false;
} finally {
//锁的释放
lock.unlock();
}
}
void removeAt(final int removeIndex) {
// assert lock.getHoldCount() == 1;
// assert items[removeIndex] != null;
// assert removeIndex >= 0 && removeIndex < items.length;
final Object[] items = this.items;
//待删除的下标等于读取的下标
if (removeIndex == takeIndex) {
// removing front item; just advance
//设置数组对应下标的值为null
items[takeIndex] = null;
if (++takeIndex == items.length)
takeIndex = 0;
//元素的个数-1
count–;
//通知所有迭代器头节点出队
if (itrs != null)
itrs.elementDequeued();
} else {
// an “interior” remove
// slide over all others up through putIndex.
final int putIndex = this.putIndex;
//从待删除的下标开始循环查找并设置数据i位置的数据
for (int i = removeIndex;😉 {
int next = i + 1;
if (next == items.length)
next = 0;
if (next != putIndex) {
items[i] = items[next];
i = next;
} else {
items[i] = null;
this.putIndex = i;
break;
}
}
count–;
//通过所有迭代器有内部节点出队
if (itrs != null)
itrs.removedAt(removeIndex);
}
//唤醒其他等待的线程
notFull.signal();
}
take()是队列头数据出队,poll()方法也是一样的
public E take() throws InterruptedException {
final ReentrantLock lock = this.lock;
//尝试去获取锁,如果锁被其他线程占用,那么当前线程就属于等待状态
lock.lockInterruptibly();
try {
//如果元素个数为0,就让当前线程等待,并且释放锁
while (count == 0)
notEmpty.await();
//如果队列不为空,则进行出队,从队列头部取元素
return dequeue();
} finally {
//完成锁的释放
lock.unlock();
}
}
private E dequeue() {
// assert lock.getHoldCount() == 1;
// assert items[takeIndex] != null;
final Object[] items = this.items;
@SuppressWarnings(“unchecked”)
//获取takeIndex位置的元素并将其转换为泛型
E x = (E) items[takeIndex];
//设置takeIndex位置数据为null,便于gc回收
items[takeIndex] = null;
if (++takeIndex == items.length)
takeIndex = 0;
count–;
//通知所有迭代器做相关清理工作
if (itrs != null)
itrs.elementDequeued();
//唤醒其他等待线程
notFull.signal();
return x;
}
上面涉及到了Itrs的两个方法:elementDequeued()、removedAt(),有兴趣的可以看一下具体的实现。
最后
感觉现在好多人都在说什么安卓快凉了,工作越来越难找了。又是说什么程序员中年危机啥的,为啥我这年近30的老农根本没有这种感觉,反倒觉得那些贩卖焦虑的都是瞎j8扯谈。当然,职业危机意识确实是要有的,但根本没到那种草木皆兵的地步好吗?
Android凉了都是弱者的借口和说辞。虽然 Android 没有前几年火热了,已经过去了会四大组件就能找到高薪职位的时代了。这只能说明 Android 中级以下的岗位饱和了,现在高级工程师还是比较缺少的,很多高级职位给的薪资真的特别高(钱多也不一定能找到合适的),所以努力让自己成为高级工程师才是最重要的。
所以,最后这里放上我耗时两个月,将自己8年Android开发的知识笔记整理成的Android开发者必知必会系统学习资料笔记,上述知识点在笔记中都有详细的解读,里面还包含了腾讯、字节跳动、阿里、百度2019-2021面试真题解析,并且把每个技术点整理成了视频和PDF(知识脉络 + 诸多细节)。
以上全套学习笔记面试宝典,吃透一半保你可以吊打面试官,只有自己真正强大了,有核心竞争力,你才有拒绝offer的权力,所以,奋斗吧!骚年们!千里之行,始于足下。种下一颗树最好的时间是十年前,其次,就是现在。
最后,赠与大家一句诗,共勉!
不驰于空想,不骛于虚声。不忘初心,方得始终。
网上学习资料一大堆,但如果学到的知识不成体系,遇到问题时只是浅尝辄止,不再深入研究,那么很难做到真正的技术提升。
一个人可以走的很快,但一群人才能走的更远!不论你是正从事IT行业的老鸟或是对IT行业感兴趣的新人,都欢迎加入我们的的圈子(技术交流、学习资源、职场吐槽、大厂内推、面试辅导),让我们一起学习成长!
(知识脉络 + 诸多细节)。
[外链图片转存中…(img-5Im6lKVm-1715745698004)]
以上全套学习笔记面试宝典,吃透一半保你可以吊打面试官,只有自己真正强大了,有核心竞争力,你才有拒绝offer的权力,所以,奋斗吧!骚年们!千里之行,始于足下。种下一颗树最好的时间是十年前,其次,就是现在。
最后,赠与大家一句诗,共勉!
不驰于空想,不骛于虚声。不忘初心,方得始终。
网上学习资料一大堆,但如果学到的知识不成体系,遇到问题时只是浅尝辄止,不再深入研究,那么很难做到真正的技术提升。
一个人可以走的很快,但一群人才能走的更远!不论你是正从事IT行业的老鸟或是对IT行业感兴趣的新人,都欢迎加入我们的的圈子(技术交流、学习资源、职场吐槽、大厂内推、面试辅导),让我们一起学习成长!