Skip to content

Commit

Permalink
Merge pull request #2 from Blankj/master
Browse files Browse the repository at this point in the history
pull newest to merge
  • Loading branch information
zhanzengyu committed Oct 15, 2019
2 parents f5da679 + 9c26b5e commit 15a2d0a
Show file tree
Hide file tree
Showing 11 changed files with 626 additions and 337 deletions.
12 changes: 12 additions & 0 deletions .github/FUNDING.yml
@@ -0,0 +1,12 @@
# These are supported funding model platforms

github: # Replace with up to 4 GitHub Sponsors-enabled usernames e.g., [user1, user2]
patreon: # Replace with a single Patreon username
open_collective: # Replace with a single Open Collective username
ko_fi: # Replace with a single Ko-fi username
tidelift: # Replace with a single Tidelift platform-name/package-name e.g., npm/babel
community_bridge: # Replace with a single Community Bridge project-name e.g., cloud-foundry
liberapay: # Replace with a single Liberapay username
issuehunt: # Replace with a single IssueHunt username
otechie: # Replace with a single Otechie username
custom: https://raw.githubusercontent.com/Blankj/AndroidUtilCode/master/art/donate.png
9 changes: 9 additions & 0 deletions .github/ISSUE_TEMPLATE.md
@@ -0,0 +1,9 @@
* 面试模块:<!-- Android -->
* 面试题目:<!-- RecyclerView 性能优化 -->
* 作者:<!-- [Blankj](https://github.com/Blankj) -->
* 参考答案:

<!-- 答案写入下方 -->


<!-- P.S:如果要提交 pr,务必确保和我当前文章格式一致,文章中不要参有和文章无关的链接 -->
64 changes: 41 additions & 23 deletions README.md
@@ -1,6 +1,6 @@
# 安卓 offer 收割基

为了方便广大 Android 开发者们做面试准备,故建立此库,本着我的一些微不足道的开发经验来整理和收集 Android 题库,内容会逐渐完善,有兴趣的可以一起加入进来,如果火起来的话我会把内容放进星球号里,届时邀请大家加入
为了方便广大 Android 开发者们做面试准备,故建立此库,本着我的一些微不足道的开发经验来整理和收集 Android 题库,内容会逐渐完善,有兴趣的可以一起加入进来,把你认为总结得不错的面试题通过 [提 issue](https://github.com/Blankj/AndroidOfferKiller/issues/new) 来加入此库


## 摘要
Expand All @@ -26,7 +26,7 @@

| Title | Author |
| :--------------------------------------- | :--------------------------------------- |
| [LeetCode 题解][LeetCode 题解] | [Blankj][Blankj] |
| [LeetCode 题解][LeetCode 题解] | [Blankj][Blankj] |


#### 1.2 计算机网络
Expand All @@ -40,7 +40,7 @@

| Title | Author |
| :--------------------------------------- | :--------------------------------------- |
| | |
| [线程池][线程池] | [Blankj][Blankj] |


### 3 Java 虚拟机
Expand All @@ -56,6 +56,7 @@
| :--------------------------------------- | :--------------------------------------- |
| [App 启动过程(含 Activity 启动过程)][App 启动过程(含 Activity 启动过程)]| [Blankj][Blankj]|
| [RecyclerView 性能优化][RecyclerView 性能优化]| [Blankj][Blankj]|
| [EditText 搜索优化][EditText 搜索优化] | [Blankj][Blankj]|


### 5 设计模式
Expand All @@ -70,59 +71,69 @@

| Title | Author |
| :--------------------------------------- | :--------------------------------------- |
| | |
| [你的缺点是什么][你的缺点是什么] | [Blankj][Blankj] |


### 7 简历模板

| Title | Author |
| :--------------------------------------- | :--------------------------------------- |
| [技术人员的 Markdown 简历][技术人员的 Markdown 简历] | [Blankj][Blankj] |
| [技术人员的 Markdown 简历][技术人员的 Markdown 简历] | [Blankj][Blankj] |


### 8 面经集合

| Title | Author |
| Title | Author |
| :--------------------------------------- | :--------------------------------------- |
| [Facebook 面经记][Facebook 面经记] | [Blankj][Blankj] |
| [阿里巴巴面经记][阿里巴巴面经记] |[Blankj][Blankj] |
| [阿里巴巴面经记][阿里巴巴面经记] | [Blankj][Blankj] |


### 9 内推通道

| Company | Email |
| :--------------------------------------- | :--------------------------------------- |
| [阿里巴巴][阿里巴巴] | blankj@qq.com |
| [51 信用卡][51 信用卡] | blankj@qq.com |
| [二维火][二维火] | blankj@qq.com |
| [亿咖通科技][亿咖通科技] | blankj@qq.com |
| [深圳市大疆创新科技有限公司][深圳市大疆创新科技有限公司] | 553838510@qq.com |
| Company |Position | Email |
| :--------------------------- |:---------------------------- | :----------------------------- |
| [字节跳动][字节跳动] | [字节跳动职位][字节跳动职位] | blankj@qq.com |
| [阿里巴巴][阿里巴巴] | [阿里巴巴职位][阿里巴巴职位] | blankj@qq.com |
| [51 信用卡][51 信用卡] | [51 信用卡职位][51 信用卡职位] | blankj@qq.com |
| [二维火][二维火] | [二维火职位][二维火职位] | blankj@qq.com |
| [亿咖通科技][亿咖通科技] | [亿咖通科技职位][亿咖通科技职位] | blankj@qq.com |
| [深圳市大疆创新科技有限公司][大疆]| [大疆职位][大疆职位] | 553838510@qq.com |


## 打个小广告

欢迎加入我的知识星球「**[基你太美](https://t.zsxq.com/FmeqfYF)**」,我会在星球中分享 [AucFrame](https://blankj.com/2019/07/22/auc-frame/) 框架、大厂面经、[AndroidUtilCode](https://github.com/Blankj/AndroidUtilCode) 更详尽的说明...一切我所了解的知识,你可以通过支付进入我的星球「**[基你太美](https://t.zsxq.com/FmeqfYF)**」进行体验,加入后优先观看星球中精华的部分,如果觉得星球的内容对自身没有收益,你可以自行申请退款退出星球,也没必要加我好友;**如果你已确定要留在我的星球,可以通过扫描如下二维码(备注:基你太美+你的星球昵称)加我个人微信,方便我后续拉你进群(PS:进得越早价格越便宜)。**

![我的二维码](https://raw.githubusercontent.com/Blankj/AndroidUtilCode/master/art/wechat.png)


[Blankj]:https://github.com/Blankj
[AndroidTraveler]:https://github.com/nesger
[Blankj]: https://github.com/Blankj
[AndroidTraveler]: https://github.com/nesger

<!-- 1.1 -->
[LeetCode 题解]: https://github.com/Blankj/awesome-java-leetcode

<!-- 1.2 -->
[TCP 与 UDP 的区别]: https://github.com/Blankj/AndroidOfferKiller/blob/master/net/TCP%20%E4%B8%8E%20UDP%20%E7%9A%84%E5%8C%BA%E5%88%AB.md
[TCP 与 UDP 的区别]: ./net/TCP%20与%20UDP%20的区别.md

<!-- 2 -->
[线程池]: ./java/线程池.md

<!-- 3 -->
[运行时数据区域]:https://github.com/Blankj/AndroidOfferKiller/blob/master/jvm/%E8%BF%90%E8%A1%8C%E6%97%B6%E6%95%B0%E6%8D%AE%E5%8C%BA%E5%9F%9F.md
[运行时数据区域]: ./jvm/运行时数据区域.md

<!-- 4 -->
[App 启动过程(含 Activity 启动过程)]: https://github.com/Blankj/AndroidOfferKiller/blob/30d48a03d792679ce25718aee1d0ea6d22325fdd/android/App%20%E5%90%AF%E5%8A%A8%E8%BF%87%E7%A8%8B%EF%BC%88%E5%90%AB%20Activity%20%E5%90%AF%E5%8A%A8%E8%BF%87%E7%A8%8B%EF%BC%89.md
[RecyclerView 性能优化]: https://github.com/Blankj/AndroidOfferKiller/blob/cff6e99919e5212981a8e5169c54e0de233bd021/android/RecyclerView%20%E6%80%A7%E8%83%BD%E4%BC%98%E5%8C%96.md
[App 启动过程(含 Activity 启动过程)]: ./android/App%20启动过程(含%20Activity%20启动过程).md
[RecyclerView 性能优化]: ./android/RecyclerView%20性能优化.md
[EditText 搜索优化]: ./android/EditText%20搜索优化.md

<!-- 5 -->
[单例模式]: https://blankj.com/2016/04/21/really-use-singleton
[责任链模式]: ./design-patterns/责任链模式妙用.md
[单例模式]: ./design-patterns/单例模式.md
[责任链模式]: ./design-patterns/责任链模式.md

<!-- 6 -->
[你的缺点是什么]: ./hr/你的缺点是什么.md

<!-- 7 -->
[技术人员的 Markdown 简历]: https://github.com/Blankj/resume
Expand All @@ -132,8 +143,15 @@
[阿里巴巴面经记]: https://blankj.com/2018/09/26/alibaba-interview

<!-- 9 -->
[字节跳动]: https://job.bytedance.com
[字节跳动职位]: https://job.bytedance.com/society
[阿里巴巴]: https://www.alibabagroup.com
[阿里巴巴职位]: https://job.alibaba.com/zhaopin/index.htm
[51 信用卡]: https://www.u51.com
[51 信用卡职位]: https://social.u51.com/apply/u51
[二维火]: https://www.2dfire.com
[二维火职位]: https://www.lagou.com/gongsi/j22013.html
[亿咖通科技]: http://www.ecarx.com.cn
[深圳市大疆创新科技有限公司]: https://www.dji.com/cn
[亿咖通科技职位]: http://ecarx.gllue.com/portal/socialposition
[大疆]: https://www.dji.com/cn
[大疆职位]:https://we.dji.com/zh-CN
84 changes: 84 additions & 0 deletions android/EditText 搜索优化.md
@@ -0,0 +1,84 @@
# EditText 搜索优化

## 描述

设计一个 EditText 的文本监听器,停止输入 1s 后,如果文本发生变化则触发监听器。

例子:
文本内容是 111,111 -> 1111 -> 11111,连续输入都小于 1s,在输完后的 1s 触发监听器为 11111;
文本内容是 111,111 -> 1111 -> 111,连续输入都小于 1s,在输完后的 1s 不触发监听器;

类似微信的客户端搜索,不同的是微信在 111 -> 1111 -> 111 是会触发改变的。

<!-- more -->

效果如下所示,注意观察 title 文本的改变:

![demo.gif](http://ww1.sinaimg.cn/large/b75b8776ly1g6prj25wgsg206k0dwaod.gif)

## 参考答案
代码很简单,结合注释参考即可,小功能从构思到编码到完成到优化,其实也是要花不少时间的,希望可以帮到你们哈。
```java
public class SearchEditText extends EditText {

private static final long LIMIT = 1000;

private OnTextChangedListener mListener;
private String mStartText = "";// 记录开始输入前的文本内容
private Runnable mAction = new Runnable() {
@Override
public void run() {
if (mListener != null) {
// 判断最终和开始前是否一致
if (!StringUtils.equals(mStartText, getText().toString())) {
mStartText = getText().toString();// 更新 mStartText
mListener.onTextChanged(mStartText);
}
}
}
};

public SearchEditText(Context context) {
super(context);
}

public SearchEditText(Context context, AttributeSet attrs) {
super(context, attrs);
}

public SearchEditText(Context context, AttributeSet attrs, int defStyleAttr) {
super(context, attrs, defStyleAttr);
}

/**
* 在 LIMIT 时间内连续输入不触发文本变化
*/
public void setOnTextChangedListener(OnTextChangedListener listener) {
mListener = listener;
}

@Override
protected void onTextChanged(final CharSequence text, int start, int lengthBefore, int lengthAfter) {
super.onTextChanged(text, start, lengthBefore, lengthAfter);
// 移除上一次的回调
removeCallbacks(mAction);
postDelayed(mAction, LIMIT);
}

@Override
protected void onDetachedFromWindow() {
super.onDetachedFromWindow();
removeCallbacks(mAction);
}

public interface OnTextChangedListener {
void onTextChanged(String text);
}
}
```



## 结语

我正在打造一个帮助 Android 开发者们拿到更好 offer 的面试库————**[安卓 offer 收割基](https://github.com/Blankj/AndroidOfferKiller)**,欢迎 star,觉得不错的可以持续关注,有兴趣的可以一起加入进来和我一同打造。
4 changes: 2 additions & 2 deletions android/RecyclerView 性能优化.md
Expand Up @@ -15,14 +15,14 @@ mTextView.setText(Html.fromHtml(data).toString());

## 数据优化

分页拉取远端数据,对拉取下来的远端数据进行缓存,提升二次加载速度;对于新增或者删除数据通过 `DiffUtil` 来进行局部刷新数据,而不是一味地全局刷新数据
分页拉取远端数据,对拉取下来的远端数据进行缓存,提升二次加载速度;对于新增或者删除数据通过 `DiffUtil` 来进行局部刷新数据,而不是一味全局地刷新数据


## 布局优化

### 减少过渡绘制

减少布局层级,例如使用 `ConstraintLayout`或者用一个自定义 View 来代替 ItemView
减少布局层级,可以考虑使用自定义 View 来减少层级,或者更合理地设置布局来减少层级,不推荐在 RecyclerView 中使用 `ConstraintLayout`,有很多开发者已经反映了使用它效果更差,相关链接有:[Is ConstraintLayout that slow?](https://www.reddit.com/r/androiddev/comments/7ylbz3/is_constraintlayout_that_slow/)[constraintlayout 1.1.1 not work well in listview](https://issuetracker.google.com/issues/112000722)


### 减少 xml 文件 inflate 时间
Expand Down
100 changes: 100 additions & 0 deletions design-patterns/单例模式.md
@@ -0,0 +1,100 @@
# 单例模式

## 单例模式的特点:

1. 单例类只能有一个实例;
2. 单例类必须自己创建自己的唯一实例;
3. 单例类必须给所有其他对象提供这一实例。


## 懒汉类

```java
// 懒汉式单例类,在第一次调用的时候实例化自己
public class Singleton {
private Singleton() {
}

private volatile static Singleton singleton = null; // 声明成 volatile

// 静态工厂方法
public static Singleton getInstance() {
if (singleton == null) {
synchronized (Singleton.class) {
if (singleton == null) {
singleton = new Singleton();
}
}
}
return singleton;
}
}
```


## 饿汉类

``` java
// 饿汉式单例类,在类初始化时,已经自行实例化
public class Singleton {
private Singleton() {
}

private static final Singleton single = new Singleton();

// 静态工厂方法
public static Singleton getInstance() {
return single;
}
}
```

但当单例类当实现了 `Serializable` 接口后,反序列化时单例会被破坏,此时需要重写 `readResolve`,才能保证其反序列化依旧是单例,如下所示:

``` java
private Object readResolve() throws ObjectStreamException {
return single;
}
```


## 内部静态类

```java
public class Singleton {
private static class LazyHolder {
private static final Singleton INSTANCE = new Singleton();
}

private Singleton() {
}

public static Singleton getInstance() {
return LazyHolder.INSTANCE;
}
}
```


## 枚举类

``` java
public enum Singleton {
INSTANCE;

public void whateverMethod() {
}
}
```

枚举类是 Effective Java 作者 Josh Bloch 提倡的方式,它不仅能避免多线程同步问题,而且还能防止反序列化重新创建新的对象,可谓是很坚强的壁垒,不过在实际工作中,我很少看见有人这么写过。


## 结论

工作中我基本都是用内部静态类,具有懒加载和线程安全的效果,如果涉及到反序列化创建对象时我会试着使用枚举的方式来实现单例,如果每次书写嫌麻烦的话,可以在 Android Studio 中设置 `Preferences -> Editor -> Live Templates` 来快速创建出自己需要的单例。


## 结语

我正在打造一个帮助 Android 开发者们拿到更好 offer 的面试库————**[安卓 offer 收割基](https://github.com/Blankj/AndroidOfferKiller)**,欢迎 star,觉得不错的可以持续关注,有兴趣的可以一起加入进来和我一同打造。

0 comments on commit 15a2d0a

Please sign in to comment.