20180928
1、字符串去重有序输出
一个字符串的去重和排序有很多方法,下面介绍两种
通过将每个字符转换成对应的ASC码存储到一个数组中,如果相同则会覆盖,最后遍历输出不为0的完成顺序输出。
正常想法是循环遍历字符串,使用List的contains方法去重后添加到一个新的list中,使用Collections的sort方法排序输出。
也想过用set方法天然的去重,在添加排序就可以
2、Handler机制原理
在主线程中创建Handler,然后通过Handler给MessageQueue发送Message,该MessageQueue是在程序启动的时候ActivityThread在Main方法中调用Looper.prepareMainLooper()创建的,一个线程只有一个Looper,一个MessageQueue,Looper通过ThreadLocal存储在当前的线程中。Looper会使用loop方法不断的从MessageQueue中取Message,通过Message的taget来把消息分发到相应的Handler中进行处理。
https://www.jianshu.com/p/12db39650356
3、view的事件分发
ViewGroup会遍历所有子View去寻找能够处理点击事件的子View(可见,没有播放动画,点击事件坐标落在子View内部)最终调用子View的dispatchTouchEvent方法处理事件
当子View处理了事件则mFirstTouchTarget 被赋值,并终止子View的遍历。
如果ViewGroup并没有子View或者子View处理了事件,但是子View的dispatchTouchEvent返回了false(一般是子View的onTouchEvent方法返回false)那么ViewGroup会去处理这个事件(本质调用View的dispatchTouchEvent去处理)
4、okhttp的优点
???
5、rxjava中的flatmap和map的区别
共同点:
都是依赖FuncX(入参,返回值)进行转换(将一个类型依据程序逻辑转换成另一种类型,根据入参和返回值)
都能在转换后直接被subscribe
区别:
map返回的是结果集,flatmap返回的是包含结果集的Observable(返回结果不同)
map被订阅时每传递一个事件执行一次onNext方法,flatmap多用于多对多,一对多,再被转化为多个时,一般利用from/just进行一一分发,被订阅时将所有数据传递完毕汇总到一个Observable然后一一执行onNext方法(执行顺序不同)>>>>(如单纯用于一对一转换则和map相同)
map只能单一转换,单一只的是只能一对一进行转换,指一个对象可以转化为另一个对象但是不能转换成对象数组(map返回结果集不能直接使用from/just再次进行事件分发,一旦转换成对象数组的话,再处理集合/数组的结果时需要利用for一一遍历取出,而使用RxJava就是为了剔除这样的嵌套结构,使得整体的逻辑性更强。)
flatmap既可以单一转换也可以一对多/多对多转换,flatmap要求返回Observable,因此可以再内部进行from/just的再次事件分发,一一取出单一对象(转换对象的能力不同)
使用场景:
map适用于一对一转换,当然也可以配合flatmap进行适用
flatmap适用于一对多,多对多的场景
6、touch event在回调方法和重写方法的区别
View的onTouchEvent会直接消费掉事件,
2018-09-27 朗播
1、HashMap
HashMap实现了Map接口,继承AbstractMap.
默认的初始容量为16,默认的加载因子是0.75。当元素数量等于数组长度*加载因子时就会rehash扩容两倍。
默认的初识容量必须为2的幂,并且小于2的30次方,如果过大则被2的30次方替换。
HashMap中的kay-value是存储在Entry数组中的
Entry实际上就是一个单向链表
key为null的元素都放在了table的位置0处,有单独的方法处理key和value的方法
使用键值对的形式存储数据,HashMap底层实现还是数组,只是数组的每一项都是一条链,HashMap是一个散列表。
HashMap的实现不是同步的,所以是线程不安全的。
key和values都可以为null
HashMap的映射是无序的
通过“拉链法”解决hash冲突
HashCode
static int hash(int h){
h^=(h>>>20)^(h>>>12);
return h^(h>>>7)^(h>>>4);
}
进行低位&运算时,值总是与原来hash值相同,而进行高位运算时,其值等于其低位值。
所以说当length = 2^n时,不同的hash值发生碰撞的概率比较小,
这样就会使得数据在table数组中分布较均匀,查询速度也较快。
https://www.cnblogs.com/chenssy/p/3521565.html
(e.getKey()==null?0:e.getKey().hashCode())^(e.getValue()==null?0:e.getValue().hashCode())
2、ArrayList
ArrayList继承List
默认初始值为10,最大值为Integer最大值-8,需要预留一些保留字
扩容公式为((旧容量*3)/2) 当大于默认值为此扩容,小于默认值不扩容
允许多个null元素
ArrayList底层为Object数组实现,使用copyOf覆盖原数组
执行add方法时,会自增size,如果大于原底层数组长度,则以适当长度新建一个原数组的拷贝,并修改原数组,指向新数组。
执行remove方法时,会自减size
ArrayList是自动扩容,数组容量固定
ArrayList相交数组效率低,ArrayList存储数据为Object,不可以存int,必须存Integer
ArrayList是基于动态数组的数据结构,LinkedList是基于双向链表的数据结构
对于随机访问get和set,ArrayList优于LinkedList,因为LinkedList要移动指针
对于新增和删除操作add和remove,LinkedList占优势,ArrayList要移动数据
Vector是线程安全的,扩容为一倍
3、自定义View
重写构造方法
onMeasure用于测量视图的大小,setMeasureDimension
onLayout用于给视图进行布局
onDraw用于对视图进行绘制,不要做耗时操作和逻辑处理
onTouchEvent用于触屏动作事件
onAttachedToWindow用于将视图添加到窗口
onDetachedFromWindow用于从窗口分离视图
自定义属性后,在xml文件中使用需要指定命名空间
对attr的获取不能使用switch-case的语句,要使用if-else
View,普通的view,与宿主窗口共享一个绘图表面,UI在主线程中绘制
在有无硬件加速的情况下都能工作
SurfaceView,继承自View,绘制和显示的效率高,拥有独立的绘图表面
UI在一个独立的线程中绘制,不占用主线程资源,需要结合SurfaceHodler一起使用
TextreView,继承自View,与SurfaceView相比不会创建一个独立的绘图表面
必须在硬件开启加速的窗口才能正常工作
4、滑动冲突
同方向的滑动冲突一般是ScrollView嵌套ListView
不同方向滑动冲突一般是ViewPager嵌套ScrollView或者相反
从外部拦截机制考虑:正常情况下父控件会优先接收到touch事件,
可以在OnInterceptTouchEvent中做处理
判断xy坐标的移动,返回false不拦截,返回true拦截
MotionEvent.ACTION_DOWN
MotionEvent.ACTION_MOVE
MotionEvent.ACTION_UP
从内容逆向思维分析:如果无法修改父控件中的代码时,设置子View不让父View拦截
在子View的onTouchListener中执行
childView.getParent().requestDisallowInterceptTouchEvent(true)
父View设置为false
自定义View可以在onTouchEvent中设置以上方法
可以配合ScrollView的onScrollChanged判断滑动位置设置是否拦截
5、Picasso和Glide对比
Picasso只有100k,840个方法,Glide有500k,2678个方法
Picasso是2级缓存,Glide是3级缓存
Picasso加载图片质量高,默认格式是ARGB-8888,一个像素点占16位
Glide加载图片默认Bitmap格式位RGB-565,一个像素点占32位,但是省内存
Glide支持GIF、video