Dimple在左耳听风 ARTS打卡(第四期)

打卡给人的感觉就是每周都有一个压力在身上,有无数双眼睛盯着你,看着你,鼓励着你,激励着你,你想不去做,就会有负罪感。这都还是被动的学习,等到真正的领悟到主动学习,那打卡,就只是一个形式罢了。我打卡,我快乐。

所谓ARTS:每周至少做一个LeetCode的算法题;阅读并点评至少一篇英文技术文章;学习至少一个技术技巧;分享一篇有观点和思考的技术文章。(也就是Algorithm、Review、Tip、Share 简称ARTS)这是第四期打卡。

Algorithm LeetCode算法

罗马数字转换

(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;
    }

Review 阅读并点评至少一篇英文文章:

Writing Change Friendly Code  

(https://medium.com/@tapsmuzira/writing-change-friendly-code-e41d3707bf85)

因为自己曾经是一名Android程序员,所以对Android还是情有独钟。这次,还是看一篇关于Android的文章,但是虽然列举的是Android的运用,其实看题目也知道,这是作者在整理如何写出优雅高效的代码。

作为Android程序员(或任何软件工程领域)最有用和最省钱的技能之一是编写易于适应未来变化的代码。随着工作项目的规模和复杂性的增加,这项技能变得更有价值。

所以,根据这个要求,文中作者通过Android上的两个比较典型的例子,Andorid Recyclerview和Dagger2依赖注入框架为例,让读者更好地了解如何通过数据封装和集中式依赖管理技术使代码更友好。这也是这篇文章的精华所在,也是困扰很多程序员的纠结所在,小编尤其感慨深刻。

小编之前所在的项目组,因为运气好,一进去就碰到程序整体重构,只是用了之前代码的思想。然后,小编坑次坑次写了很多代码,一开始的时候,都是根据规范一个一个来的,写的逻辑也还有点清楚。但是到后来,随着人员的增加,功能的增加,最后连自己写的代码都不认识了,而且代码耦合性很高,封装性也差。那时候还没有很流行框架的概念,都是靠自己写的功能。随着这几年Android的发展迅猛,以及世界上对Android开源的框架越来越频繁,很多功能都从自己写代码到了依赖框架,代码短小精悍。

但是方便归方便,文中也列举了如何更好的使用框架。最近也在学设计模式,知道了部分精髓。不是简单的封装就是封装,要对扩展开放,对修改关闭等等原则,在现实编写的项目里,如果有一点点注重,那么整个项目思路就会清晰起来。会写代码只是第一步,会写优雅的代码才是关键,会写扩展性高,易于使用的代码才是优秀的人才。

Tip 一个技术技巧

上次打卡,是持续学习了极客时间的《Java核心技术36讲》,做了点笔记,这次继续把笔记优化出来。这次给大家带来26讲的内容,如何监控和诊断JVM堆内和堆外内存使用。

如何监控和诊断JVM堆内和堆外内存使用?典型回答

  • 可以使用综合性的图形化工具,入JConsole、VisualVM(JDK 9之后,不再JDK安装包中)

  • 也可以使用命令行工具进行运行时查询,入jstat和jmap等工具都提供了一些选项,可以查看堆、方法区等使用数据

  • 或者,也可以使用jmap等提供的命令,生成堆转储(Heap Dump)文件,然后利用jhat或Eclipse MAT等堆转储分析工具进行详细分析

  • 如果你使用的是Tomcat、Weblogic等Java EE服务器,同样提供了内存管理相关功能

堆外内存中的直接内存,前面的工具基本不适用,可以使用JDK自带的Native Memory Tracking(NMT)特性,它会从JVM本地内存分配的角度进行解读

按照通常的GC年代方式划分,Java堆内分为:

  1. 新生代:大部分对象创建和销毁的区域

  2. 老年代:防止长生命周期的对象,通常都是从Survivor区域拷贝过来的对象。普通对象会被分配在TLAB(Thread Local Allocation Buffer)上;如果对象较大 ,JVM会试图直接分配在Eden其他位置上;如果对象太大,完全无法在新生代找到足够长的连续空闲空间,JVM就会直接分配到老年代

  3. 永久代:这部分就是早起Hotspot JVM的方法区实现方式了,储存Java类元数据、常量池、Intern字符串缓存,在JDK8之后就不存在永久代这块儿了
    我们如何利用JVM参数,直接影响堆和内部区域的大小呢?

  • 最大堆体积 -Xmx value

  • 初始的最小堆体积  -Xms value

  • 老年代和新生代的比例 -XX:NewReatio=value 默认情况下,这个数值是2,意味着老年代是新生代的2倍大

  • 当然,也可以不用比例的方式调整新生代的大小,直接指定下面的参数,设定具体的内存大小数值 -XX:NewSize=value

  • Eden和Survivor的大小是按照比例设置的,如果SurvivorRatio是8,那么Survivor区域就是Eden的1/8大小,也就是新生代的1/10,因为YoungGen=Eden + 2*Survivor,JVM参数格式是 -XX:SurvivorRatio=value

  • TLAB当然也可以调整,JVM实现了复杂的适应策略

为什么在标记垃圾的时候,需要stop the world  以cms为例,它有不同的mark:initial mark,conc mark,remark;conc 时候不需要stw,其他需要短暂stw,这样引用关系才不变,另外效率更高

Share 一篇有观点和思考的技术文章

继续设计模式的学习执行,更新到观察者模式

公众号地址:
设计模式之观察者模式(二)

第二栏推荐涛哥的文章,最近热门的话题,996icu和奔驰事件等,他的文章还有抽奖链接哦,今天最后一节,赶紧参与吧

爱生活,爱学习,爱感悟,爱挨踢

640?wx_fmt=jpeg


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

程序员小跃

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值