所谓ARTS: 每周至少做一个LeetCode的算法题;阅读并点评至少一篇英文技术文章;学习至少一个技术技巧;分享一篇有观点和思考的技术文章。(也就是Algorithm、Review、Tip、Share 简称ARTS)这是第二期打卡
Algorithm LeetCode算法
整数反转问题reverse-integer (https://leetcode.com/problems/reverse-integer/)
题目描述:『给出一个32位的有符号整数,你需要将这个整数中的每位上的数字进行反转 示例1:输入123,输出321;示例2:输入-123,输出-321;示例3:输入120,输出21。
注意:假设我们的环境只能存储得下32位的有符号整数,则其数值范围为(-2^31-1,2^31-1)请根据这个假设,如果反转后整数溢出那么就返回0』
这题又是一道简单题,呵呵,佩服自己的勇气,一直在刷简单题。主要有两个问题需要注意下,第一个就是题目里的注意事项,有符号整数的边界问题。如果你反转的数据超过了这个边界,那就需要做溢出处理。小编之前没有充分注意,把result = result * 10 first;这句话提前了,导致边界判断无效,失败了,很是遗憾。
第二个就是效率问题,小编还是使用了传统的数值运算,通过最后输出的值来判断是否在边界里,消耗时间肯定又是略多了。官方给的解答,让我恍然大悟,解释如下:
- 如果temp = rev * 10 pop 导致溢出,那么一定有rev >= INTMAX / 10
- 如果rev > INTMAX / 10,那么temp = rev * 10 pop 一定会溢出
- 如果rev == INTMAX / 10,那么只要pop > 7,temp = rev * 10 pop 就会溢出
- 当rev为负数时,可以应用类似的逻辑 醍醐灌顶了没有呢,请看下面的解答:
public static int reverse(int x) {
int result = 0;
while (x != 0) {
int first = x % 10;
if (x > 0 && result > Integer.MAX_VALUE / 10) {
return 0;
}
if (x < 0 && result < Integer.MIN_VALUE / 10) {
return 0;
}
result = result * 10 first;
System.out.println("result = " result);
x = (x - first) / 10;
// 我使用了上一个方案,结果后来才发现,和下面这个结果是一样的,而我还需要多一个减法,肯定还不是最优
// x = x / 10;
}
System.out.println(result);
return result;
}
// 官方给出的方案
public static int reverseOther(int x) {
int rev = 0;
while (x != 0) {
int pop = x % 10;
x /= 10;
if (rev > Integer.MAX_VALUE / 10 || (rev == Integer.MAX_VALUE / 10 && pop > 7)) {
return 0;
}
if (rev < Integer.MIN_VALUE / 10 || (rev == Integer.MIN_VALUE / 10 && pop <-8)) {
return 0;
}
rev = rev * 10 pop;
}
return rev;
}
Review 阅读并点评至少一篇英文文章
https://proandroiddev.com/java-calling-kotlin-3cb3a84bde63 写Android的朋友肯定知道,早在前几年的Google开发者大会上,Google就针对Android开发,不仅仅更新了新的开发工具Android Studio,还将Kotlin推到台前。也就是说,不仅仅Java可以写Android,Kotlin也可以愉快的写Android了。
这篇文章,标题就叫Java Calling — Kotlin,言外之意就是在介绍Java调用Kotlin的使用。之前小小玩弄过Kotlin,但是因为后来专注于Java后端,而忽略了这方面的了解。今天借此机会又重新了解。
现在,我们可以并行使用Kotlin和Java来编写程序了,这也是语言能力的一大进步,也是科技的进步。Kotlin和Java都是使用Java虚拟机(JVM)语言并编译为相同的字节码,以此达到互通的目的。Java和Kotlin,只需要通过注解,就能很好的使用起来。比如
- @file:JvmName*
- @file:JvmMultifileClass*
- @JvmField*
- @JvmStatic*
- @get:JvmName
- @set:JvmName
- @JvmOverloads*
- @Throws
- @JvmWildcard
- @JvmSuppresWildcards
Java通过注解调用Kotlin,达到互通。技术是无边界的,这一大进步,就像跨平台开发一样,一个伟大的进步。而且,Kotlin相比于Java,也有很多天然的优势。小编第一次接触的时候,就知道他是不存在空指针异常的,这在Java程序的世界里,算是松了一口气了吧,没有空指针异常,岂不是可以稍微爽快一点的写代码了呢。
如果你还没有接触过Kotlin,如果你是Java开发,那么,行动起来吧,去拥抱这一语言,Android,Java的世界将给你一大惊喜。不知道现在Kotlin真正使用的有多少,反正之前一出来的时候,还是很多人去GitHub上提交过代码的。Kotlin的优先就是几行代码,实现Java一串代码的功能,小编要去学习啦,你呢?
Tip 一个技术技巧
趁着学习《Android开发高手课》的存储优化课程,总结下Android常用的序列化方法, 在这里只做简单的说明,具体深入研究,可以通过搜索了解。
Android常用的序列化方法 对象的序列化 应用程序中的对象存储在内存中,如果我们想把对象存储下来或者在网络上传输,这个时候就需要用到对象的序列化和反序列化。
对象序列化就是把一个Object对象所有的信息表示成一个字节序列,这包括Class信息、继承关系信息、访问权限、变量类型以及数值信息等。
- Serializable Serializable 是Java原生的序列化机制,在Android中也有被广泛使用。我们可以通过Serializable将对象持久化存储,也可以通过Bundle传递Serializable的序列化数据
- Parcelable 由于Java的Serializable的性能较低,Android需要重新设计一套更加轻量搞笑的对象序列化和反序列化机制。Parcelable正式在这个背景下产生的,它核心的作用就是为了解决Android中大量跨进程通信的性能问题
Parcel序列化和Java的Serializable序列化差别还是比较大的,Parcelable只会在内存中进行序列化操作,并不会将数据存储到磁盘里。
- Serial Serial在序列化和反序列化耗时,以及落地的文件大小都有很大的优势。 从实现原理上看,Serial就像是吧Parcelable和Serializable的优点集合在一起的方案
数据的序列化
- JSON JSON是一种轻量级的数据交互格式,它被广泛使用在网络传输中,很多应用与服务端的通信都是使用JSON格式进行交互
- Protocol Buffers(我目前在用) 相比对象序列化方案,JSON的确速度更快、体积更小。不过为了保证JSON的中间结果是可读的,它并没有做二进制的压缩,也因此JSON的性能还没达到极致
如果应用数据量非常大,又或者对性能有更高的有奥球,此时Protocol Buffers是一个非常好的选择。他是Google开源的跨语言编码协议,Google内部的几乎所有RPC都在使用这个协议
- Google后面还推出了压缩率更高的FlatBuffers
Share 一篇有观点和思考的技术文章
继续设计模式的学习执行,更新到第二篇