ARTS打卡 - 12
1. Algorithm
19. Remove Nth Node From End of List
这道题题目比较明确,移除链表中倒数第n个节点。解法也应该有多种,例如:遍历一遍,将链表转化为一个数组,然后移除对应下标的元素即可。还有一种解法是先遍历链表,获取链表长度,然后翻转,移除对应的节点。我用的是另一种方法:
- 判断边界条件
- 两个指针,步长为n,即倒数第n个节点。
- 移动指针,当第一个指针与第二个指针相距步长为n的时候,移动第二个指针。
- 第一个指针移动到链表尾节点的时候,刚好第二个指针所在位置的下一个就是要移除的节点
- 将要被移除的节点的前置节点与后置节点相连,得到的就是移除对应节点后的新链表。
1 | public ListNode removeNthFromEnd(ListNode head, int n) { |
2. Review
Android Vitals - What time is it?
这是一个系列文章,作者是LeakCanary的作者。是关于如何监控Android生产环境的表现的文章。这是这一系列的第一篇,文章讲述了如何选择计算时间的方法。在Android中,提供了多种计算时间的方式:
1 | // Milliseconds since Unix epoch (00:00:00 UTC on 1 January 1970) |
它们之间的主要区别是:
System.currentTimeMillis():
这是比较常用的计算时间的方法,但是这个方法获取的事件可以被用户或手机网络改变,可能会出现较大的跳动,因此计算时间间隔应该使用其它的方法。SystemClock.uptimeMillis()
:这个计算方式会在系统进入深度睡眠的时候停止,例如在Thread.sleep()
或者Object.wait(long)
,这个方法很适合计算事件当不需要计算睡眠时。SystemClock.elapsedRealtime()
:与SystemClock.uptimeMillis()
计算逻辑刚好相反,会包括睡眠时间。
在计算App的表现是,更推荐使用SystemClock.uptimeMillis()
或者nanoTime()
。
此外,还比较了SystemClock.uptimeMillis()
和nanoTime()
的性能差异,结论是使用uptimeMillis() 与nanoTime() 在新的Android系统上是一样的,而在旧版的Android系统上,uptimeMillis() 会表现更好。这是因为
在新的系统上刚对``nanoTime()`的实现方式做了修改,所以实现方式二者是一样的。具体的实现文章有详细说明。
所以结论时,当需要在生产环境计算消耗时间的间隔时,最好是使用SystemClock.uptimeMillis()
。
3. Tip
- 可以使用top命令查看系统内存与CPU占用,例如:
adb shell top -m 20
查看内存占用前20的应用,此外还可以加一些参数,例如 -i: 可以指定top输出的时间间隔, -p: 指定进程号。(获取进程号可以通过pidof xxxx, 或者 lsof -i :port),此外,也可以结合pgrep命令过滤出符合条件的信息:top -c -p $(pgrep -d',' -f string_to_match_in_cmd_line)
,其中 -d 表示使用 ‘,’ 分割,-f 表示匹配内容。 - top输出的详细解读:https://juejin.im/post/6844903919588491278
4. Share
-
最近改bug发现了一些超时的错误,其中SocketTimeoutException是比较常见的一种网络超时错误,分为connect timed out 和 read time out。这篇文章比较i详细的讲了在建立Socket连接时从client到jvm到linux底层的一些调用链。