- 博客(30)
- 收藏
- 关注
原创 NAT类型与P2P游戏
当前绝大部分上网设备都没有自己的公网ip,而是使用端口映射连接到互联网。例如,一台ip+端口为192.168.0.233:233(内网ip+端口)的电脑向外发送数据,经过路由器时ip+端口会被转换为223.89.47.47:666(公网ip+端口),远端服务器收到数据时进行回复,回复数据经过路由器时ip+端口被转换回192.168.0.233:233(内网ip+端口),从而完成通信。以上是理想情况下的端口映射,现实中存在4中NAT类型,分为两大类:请求不同外网地址时的端口映射关系都相同(ABC),即总是
2021-01-24 20:26:45
1917
原创 RxJava3.0入门教程(四)Subject
Observable的特点是在subscribe订阅关系建立的时刻立即发送所有的事件,即事件确定在订阅关系建立之前。Subject可以在建立订阅关系之后再按需随时发送事件,实现了真正的观察者。Subject继承自Observable的同时实现了Observer。继承自Observable是为了成为被观察者,实现Observer是为了省去ObservableOnSubscribe和Emitter。public abstract class Subject<T> extends Observa
2020-12-17 16:54:14
315
原创 RxJava3.0入门教程(三)背压
RxJava另一块比较复杂的部分是背压,其中的难点不在于本身,而是背压的表现可能和我们随意畅想的情景不一样,以至于种种的不可理解。先看一个一个基本用法Observable换成Flowable Observer换成Subscriber ObservableOnSubscribe换成FlowableOnSubscribe ObservableEmitter换成FlowableEmitter 增加一个参数表示背压策略 MISSING ERROR BUFFER DROP LATEST
2020-12-17 16:52:08
812
原创 安卓事件分发机制详解
安卓的事件分发机制非常绕脑,很容易一知半解。其中涉及到四个关键概念,前三个是方法,它们什么时候被调用,返回值起什么作用各不相同,最后一个是一个引用变量,它何时为null何时不为null决定了方法的调用。dispatchTouchEvent onInterceptTouchEvent onTouchEvent mFirstTouchTargetmFirstTouchTarget什么时候不为null当当前ViewGroup的onInterceptTouchEvent不拦截DOWN事件,即on
2020-09-11 17:18:53
293
原创 RxJava3.0入门教程(二)线程切换
RxJava有引以为傲的链式调用、海量的操作符、便捷的线程切换。如果找到一个入口同时了解三者,线程切换再合适不过了,它同时利用了三者的特性,又不至于内容过于琐碎繁杂。RxJava切换线程的操作符总共只有两个:observeOn和subscribeOn:observeOn用于切换观察者Observer的onNext执行线程 subscribeOn用于切换被观察者Observable的subscribe执行线程如下这段代码就是本篇分析的重点,很好地体现了链式调用的特点:不加分号,一点到底。(为了减小
2020-08-23 16:06:30
1251
原创 RxJava3.0入门教程(一)基本使用
入门使用Observable.create(new ObservableOnSubscribe<Integer>() { @Override public void subscribe(ObservableEmitter<Integer> emitter) throws Exception { emitter.onNext(3); emitter.onNext(2); emitter.onNext(1);
2020-08-23 11:47:30
1513
原创 建立TCP连接为什么要进行三次握手
本文试图解释为什么建立TCP连接必须是三次握手,而不是两次或者四次或者不握手。以A向B请求建立TCP连接为例。前提知识1、网络层实现的传输是不可靠的,TCP是可靠传输此处的可靠是非常狭义,有具体所指的可靠。链路层在两个网络节点间传递数据时会使用循环冗余检测检查数据是否在传输过程中有错误,如果有就丢弃数据包,网络层乃至传输层的UDP协议并未对此做什么改变。所以这种传输是不可靠的(丢弃之后...
2020-02-25 21:12:32
1128
原创 Https的简单原理
前提知识1、对称加密只有一个秘钥,同一个秘钥加密同一个秘钥解密,优点是效率高,缺点是服务器和客户端(也可称作浏览器)没法商定秘钥,如果明文发送秘钥容易泄露。2、非对称加密有有一个公钥和一个私钥,公钥加密只能私钥解密,同时私钥加密只能公钥解密,缺点是效率低,优点是不需要商定秘钥,即使明文发送公钥也没有安全问题。3、http不安全的地方在于两处:报文文明文传输,截获就能知晓内容;黑客可能冒...
2020-02-19 18:44:57
215
原创 深入分析RecyclerView源码——ItemTouchHelper
ItemTouchHelper是官方提供的增强RecyclerView的方案,提供侧滑删除和拖动位置的功能,使用上不算特别简单,需要自己实现Callback回调接口。本文略过使用方法主要从整体流程上分析ItemTouchHelper的实现原理。流程概述ItemTouchHelper是通过先行拦截RecyclerView的MotionEvent实现的,ItemTouchHelper先判断是否...
2019-12-13 15:29:54
263
原创 深入分析RecyclerView源码——缓存策略
计算机领域常用的提高效率办法是使用缓存,一级不够就上多级缓存,RecyclerView也采用了缓存策略。缓存的单位是ViewHolder,具体实现是Recycler类,Recycler有五个缓存池用来存放暂时用不到的ViewHolder,下一次使用时会在缓存池中寻找,找不到时才会调用Adapter的onCreateViewHolder创建ViewHolder。加上ChildHelper的mHidd...
2019-12-10 20:41:51
335
原创 深入分析RecyclerView源码——滑动机制
RecyclerView布局之外,最常用的功能应该就是滑动。RecyclerView的事件处理依然是常规的onTouchEvent根据触控事件响应,特别的是RecyclerView采用了嵌套滑动机制,会把滑动事件通知给支持嵌套滑动的父view先做决定,以实现诸如toolBar上划隐藏的效果,还有就是涉及到缓存策略,不过相比布局,滑动的缓存策略要简单的多,仅仅是把划出屏幕的viewHolder存入m...
2019-12-10 11:09:01
488
原创 深入分析RecyclerView源码——布局流程(下)
接着上篇继续分析布局流程。onLayoutChildren所取onLayoutChildren是LinearLayoutManager的方法,RecyclerView把具体的布局交给了布局管理器去做,精简后的代码主要做了三件事:一、确定锚点(updateAnchorInfoForLayout),所谓锚点就是布局的基准点,一般情况下layout子view是从上到下或者从下到上的,但是当子...
2019-12-08 19:55:05
531
原创 深入分析RecyclerView源码——布局流程(上)
开篇简述RecyclerView的源码数量真的是太多啦,第一次解析打算按照分析view的标准方法,先从measure、layout和draw三大流程入手。本篇文章主要着眼于最核心的measure和layout过程。分析后会发现RecyclerView实际上是把两个过程分由三个函数dispatchLayoutStep1,dispatchLayoutStep2和dispatchLayoutStep...
2019-11-23 14:42:55
435
原创 为什么同时需要ip地址和mac地址
理论上说找一个东西需要且只需要一个唯一标识,所以说ip和mac的功能似乎重复了。但是出于便捷和历史原因,他们却共存到了今天。一、有了mac为什么还需要ip有唯一mac固然可以寻址,但是却不方便。mac地址是出厂自带的,至于后续设备到了哪里都是不可控的,所以mac没有规律可循。就好像快递员只用身份证号找人,由于人口是流动的,不一定就待在身份证号上的户籍地址,所以寻找难度过大。ip的优势正在于...
2019-11-19 12:02:11
4763
原创 简单工厂模式、工厂方法模式、抽象工厂模式的区别
今天开始学习设计模式中的三种工厂模式,看了不少博客验证自己的想法,最后分享一下自己的理解。(以下无代码,建议结合其他博客的示例看)首先最重要的是理解这里“工厂”的含义。设计模式的“工厂”和笔者理解的日常生活中的“工厂”是有差异的(如果你理解中没有差异可以略过这一段)。为了区分,以下设计模式的“工厂”称“设工厂”,日常生活中的“工厂”称“日工厂“。笔者认为生活中自己生产产品和“日工厂”生产产品的...
2019-10-30 17:07:14
312
原创 安卓子线程更新UI不闪退的问题
子线程不能更新UI已经是一个常识了,如果两个线程同时更新UI,可能对同一个控件操作造成混乱,而更新UI涉及到整棵View树的遍历,加锁又影响效率,索性在ViewRootIlmpl类中设置一个checkThread()方法,检测当前线程和创建View的线程是否是同一个,如果不是直接Throw Exception,这就是不能在子线程更新UI的原理。但是实测发现在某些情况下可以在子线程中更新UI。一...
2019-09-16 21:39:44
640
原创 详解安卓MeasureSpec及其和match_parent、wrap_content的关系
在安卓View的measure过程中,measureSpec扮演着重要的作用。MeasureSpec是一个32位的int,前2位代表模式,其中00代表UNSPECIFIED,01代表EXACTLY,10代表ATMOST,后30位代表具体大小,例如1073741824模式为EXACTLY,大小为1080。这三种模式的具体意思如下图在ViewGroup中有一个getChildMeasureSp...
2019-09-08 18:30:17
1369
3
原创 为什么安卓Parcelable接口会有一个内部类Creator
Parcelable接口是实现序列化的一种方式,与Serializable相比比较复杂,但胜在运行效率高,在安卓中得到了广泛应用。主要需要实现写入和读出两个功能,写入比较易懂,使用writeToParcel,读出按说也应该是一个方法createFromParcel,但是却将其封装在了Creator类中,这是何故?深入Parcel类的readParcelable方法初步了解读出过程才恍然大悟。...
2019-08-30 21:04:51
1300
原创 【LeetCode】105. Construct Binary Tree from Preorder and Inorder Traversal
已知二叉树的先序遍历和中序遍历,构造该二叉树。一、逐个从头插入想到先序遍历就是常规二叉树的一种构造顺序,但是信息还不完全,挨个插入时,不知道待插入节点应该插在左子树还是右子树上。再借助中序遍历即可分辨,如果待插入节点在中序遍历中比当前节点靠前,就说明在左子树中,深入左子树继续判断,知道到达树的底端插入即可。还有一个问题是如何判断两个节点在中序遍历中的顺序关系,我想到了两种方法,一种是用二分...
2019-08-04 10:46:13
102
原创 【LeetCode】87. Scramble String【分治法】
把一个字符串变成一颗二叉树,如果一个新字符串能由任意交换子树得到,则称为Scramble String。苦思冥想,自知不善于分治,故特别记录下来。如果两个字符串是Scramble String,则必然有它们的两个子串分别互为Scramble String,如此二分下去直到字串长度为1,就只需判断是否相等。能有这种分而治之的思想此题就非常简单了。for (int i = 1; i <...
2019-08-04 10:23:29
147
原创 URLEncoder.encode和getBytes的区别
在Web开发中遇到中文编码问题总是令人头疼,更可怕的是又遇到了似乎很相似似乎又不同,傻傻分不清的URLEncoder.encode和getbytes方法,我试图去解释清二者的区别。举栗,现在有一个中文词“中国”,我们分别用这两种方法进行解码,还原成一串数字。由于utf-8的汉字占三个字节,所以理论应该得到两个三字节的数字,共六个字节。一、getBytes()bytes[] name ...
2019-07-08 21:52:49
1402
2
原创 【LeetCode】85.Maximal Rectangle【单向栈&双向扫描】
在一个0和1组成的矩阵中寻找面积最大的矩形,初看和上一题思路没什么区别,但其实在实现上可以有另一种思路。原题如下:Given a 2D binary matrix filled with 0's and 1's, find the largest rectangle containing only 1's and return its area.Example:Input:[ ...
2019-03-21 22:45:21
306
原创 【LeetCode】84. Largest Rectangle in Histogram【栈】
在直方图中找到面积最大的矩形的面积,第一眼看到此题就觉得和LeetCode的42题接雨水好像,最后也的确如此。原题如下Givennnon-negative integers representing the histogram's bar height where the width of each bar is 1, find the area of largest rectan...
2019-03-16 23:00:59
199
原创 简单易懂ppi和dpi的本质和由来
今天学习安卓的时候又遇到这个问题,第一次认真搜索了一下,看了很多博文说的不太全面或是没有讲到本质,我只是简单说一下对于电子屏幕来说ppi和dpi的区别。一、PPI和DPI的概念 先说普通用户接触较多的ppi,英文全称pixels per inch,又叫像素密度,意思是每英寸上的像素数。如图是我画的垃圾图,凑活看,一块1280*720分辨率的5英寸屏幕,意思是横向...
2019-03-08 16:14:16
2896
原创 【LeetCode】65.Valid Number【有限状态机&正则表达式】
任务只有一句话判断输入的数字是否合法。说真的,看了给的十几个例子我又百度了一下才最终弄清规则。特别需要注意的是诸如+.5和90.这样的数一开始以为不合法,提交错误后才知道是可以的,小数点前或者后可以没有数字。首先只想到了各种ifelse无限嵌套,顿时索然无味一点都不想写,所以以下是百度看到思想后再写的。(以我的代码风格肯定也不会用enum,直接012345就完事了)Validate if a...
2019-02-28 20:54:03
749
2
原创 【LeetCode】42. Trapping Rain Water【双指针&栈】
n个非负整数,数值代表高度,问这样的形状能收集多少雨水。原题的图片有助于理解题意。Given n non-negative integers representing an elevation map where the width of each bar is 1, compute how much water it is able to trap after raining.The...
2019-02-17 21:37:11
563
原创 【LeetCode】32. Longest Valid Parentheses【栈&动态规划】
它的标题基本就是题目了,找出连续的最长有效括号的长度,再看一下原题的两个栗子就更明显了,尤其是第二个栗子中的()()部分,更是此题的一个关键,后面还会经常提起。这道题题意相当简单,思路相当简洁,代码相当简短,但是感觉想起来没有那么简单,做完有一种相当巧妙的感觉,所以分享出来。Given a string containing just the characters '(' an...
2019-02-17 17:46:51
231
原创 【LeetCode】30. Substring with Concatenation of All Words题解
给定一个字符串s和很多相同长度的字符串words,这些字符串可以有相同的,任务是在s里找到一部分正好是words的全部字符串按任意顺序组合起来,输出符合条件的部分在s的起始位置。题意依旧是so easy,几句话搞定的事,初看的时候感觉复杂度好高,这得比到海枯石烂啊,偷偷看了下大佬的DA,分享一下两种解法。先贴原题。You are given a string, s, and a...
2019-02-16 23:55:09
139
原创 【LeetCode】10. Regular Expression Matching【动态规划&递归】
对于p字符串有点、字母、点*、字母*四种元素,点匹配任意一个字母,字母匹配相同的一个字母,点*匹配任意字母(可以是任意不同字母,例如.*匹配abc),字母*匹配连续任意个相同字母,值得注意的是*的任意包括0个。由于*可以匹配任意个,造成检验s和p是否完全匹配的时候难以确定究竟*匹配几个字母合适,这正是本题的关键点。题意简单粗暴,看一下原题,然后分析一下如何处理。Given an...
2019-02-08 23:54:48
1731
1
原创 排序函数qsort和sort用法与区别简谈
qsort和sort是两个编译器自带的快速排序方法,相比自己写一个排序算法,不仅更简单,效率也往往更高。qsort需要引入头文件<stdlib.h>,sort则需要<algorithm>。 先说相对略微简单的sort,原型就不写了,直接举int数组的例子吧int a[10] = {5,8,9,1,4,7,6,3,5,8};sort(a,a+10,com); ...
2018-06-28 10:52:14
1224
空空如也
空空如也
TA创建的收藏夹 TA关注的收藏夹
TA关注的人