打卡给人的感觉就是每周都有一个压力在身上,有无数双眼睛盯着你,看着你,鼓励着你,激励着你,你想不去做,就会有负罪感。这都还是被动的学习,等到真正的领悟到主动学习,那打卡,就只是一个形式罢了。我打卡,我快乐。
所谓ARTS:每周至少做一个LeetCode的算法题;阅读并点评至少一篇英文技术文章;学习至少一个技术技巧;分享一篇有观点和思考的技术文章。(也就是Algorithm、Review、Tip、Share 简称ARTS)这是第四期打卡。
罗马数字转换
(https://leetcode.com/problems/roman-to-integer/submissions/)
题目描述:罗马数字包含以下七种字符: I, V, X, L,C,D 和 M。
字符 数值
I 1
V 5
X 10
L 50
C 100
D 500
M 1000
例如, 罗马数字 2 写做 II ,即为两个并列的 1。12 写做 XII ,即为 X + II 。27 写做 XXVII, 即为 XX + V + II 。
通常情况下,罗马数字中小的数字在大的数字的右边。但也存在特例,例如 4 不写做 IIII,而是 IV。数字 1 在数字 5 的左边,所表示的数等于大数 5 减小数 1 得到的数值 4 。同样地,数字 9 表示为 IX。这个特殊的规则只适用于以下六种情况:
I 可以放在 V (5) 和 X (10) 的左边,来表示 4 和 9。 X 可以放在 L (50) 和 C (100) 的左边,来表示 40 和 90。 C 可以放在 D (500) 和 M (1000) 的左边,来表示 400 和 900。 给定一个罗马数字,将其转换成整数。输入确保在 1 到 3999 的范围内。
解题思路:其实小编之所以会用Map,是因为吃了打卡第一期的亏,不知道有Map这么好用的东西。一开始,小编还是死死的用硬编码去循环,我去,痛定思痛呀,前面吃过的亏在第一次提交的时候还是吃了,罪过罪过,同一个错误竟然出现了两次。
好在小编及时悬崖勒马,看到通过的时候,发现时间消耗贼大,坑次坑次捣鼓了半天才想第一期的打卡算法。这里面的循环也是一个关键,需要用前后两个值去比较,才能判断是相加还是相减,你看出门道了吗?相信你比我强,早就看出来了吧。
public static int romanToIntNew(String s) {
Map<String, Integer> map = new HashMap<>();
map.put("I", 1);
map.put("V", 5);
map.put("X", 10);
map.put("L", 50);
map.put("C", 100);
map.put("D", 500);
map.put("M", 1000);
int length = s.length();
String[] aStringArr = s.split("");
int result = 0;
for (int i = 0; i < length - 1; i++) {
if (map.get(aStringArr[i]) < map.get(aStringArr[i+1])) {
result -= map.get(aStringArr[i]);
} else {
result += map.get(aStringArr[i]);
}
}
result += map.get(aStringArr[aStringArr.length - 1]);
return result;
}
Writing Change Friendly Code
(https://medium.com/@tapsmuzira/writing-change-friendly-code-e41d3707bf85)
因为自己曾经是一名Android程序员,所以对Android还是情有独钟。这次,还是看一篇关于Android的文章,但是虽然列举的是Android的运用,其实看题目也知道,这是作者在整理如何写出优雅高效的代码。
作为Android程序员(或任何软件工程领域)最有用和最省钱的技能之一是编写易于适应未来变化的代码。随着工作项目的规模和复杂性的增加,这项技能变得更有价值。
所以,根据这个要求,文中作者通过Android上的两个比较典型的例子,Andorid Recyclerview和Dagger2依赖注入框架为例,让读者更好地了解如何通过数据封装和集中式依赖管理技术使代码更友好。这也是这篇文章的精华所在,也是困扰很多程序员的纠结所在,小编尤其感慨深刻。
小编之前所在的项目组,因为运气好,一进去就碰到程序整体重构,只是用了之前代码的思想。然后,小编坑次坑次写了很多代码,一开始的时候,都是根据规范一个一个来的,写的逻辑也还有点清楚。但是到后来,随着人员的增加,功能的增加,最后连自己写的代码都不认识了,而且代码耦合性很高,封装性也差。那时候还没有很流行框架的概念,都是靠自己写的功能。随着这几年Android的发展迅猛,以及世界上对Android开源的框架越来越频繁,很多功能都从自己写代码到了依赖框架,代码短小精悍。
但是方便归方便,文中也列举了如何更好的使用框架。最近也在学设计模式,知道了部分精髓。不是简单的封装就是封装,要对扩展开放,对修改关闭等等原则,在现实编写的项目里,如果有一点点注重,那么整个项目思路就会清晰起来。会写代码只是第一步,会写优雅的代码才是关键,会写扩展性高,易于使用的代码才是优秀的人才。
上次打卡,是持续学习了极客时间的《Java核心技术36讲》,做了点笔记,这次继续把笔记优化出来。这次给大家带来26讲的内容,如何监控和诊断JVM堆内和堆外内存使用。
如何监控和诊断JVM堆内和堆外内存使用?典型回答
堆外内存中的直接内存,前面的工具基本不适用,可以使用JDK自带的Native Memory Tracking(NMT)特性,它会从JVM本地内存分配的角度进行解读
按照通常的GC年代方式划分,Java堆内分为:
为什么在标记垃圾的时候,需要stop the world 以cms为例,它有不同的mark:initial mark,conc mark,remark;conc 时候不需要stw,其他需要短暂stw,这样引用关系才不变,另外效率更高
继续设计模式的学习执行,更新到观察者模式