专栏首页程序员小跃Dimple在左耳听风 ARTS打卡(第四期)

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 一篇有观点和思考的技术文章

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

本文分享自微信公众号 - 奔跑吧攻城狮(runningdimple),作者:DimpleXu

原文出处及转载信息见文内详细说明,如有侵权,请联系 yunjia_community@tencent.com 删除。

原始发表时间:2019-04-18

本文参与腾讯云自媒体分享计划,欢迎正在阅读的你也加入,一起分享。

我来说两句

0 条评论
登录 后参与评论

相关文章

  • 答知友困惑:Java零基础如何入门,不知道怎么学,迷茫ING

    几个星期之前,我在知乎上看到一个提问,说是:对于完全没有经验零基础自身的数学底子也很弱学习Java应该怎么学习呢?想着类似的问题我也有过回答,并且反馈还是蛮好的...

    程序员小跃
  • 设计模式之装饰者模式(二)

    愉快的假期结束了,大家假期过的咋样呢。小编反正在家睡了一天半,出去玩了一天。收心了收心了,继续学习吧。

    程序员小跃
  • 想成为一个好程序员?学学如何写作吧

    不管你是有多年编程经验的程序员,亦或是你刚刚开始学习编程,如果你在读这篇文章,那么你已经有了另一门语言的技能:英语技能。

    程序员小跃
  • 程序员写出这样的代码,能不挨骂吗?

    针对接口输入参数,没有进行严格校验,尤其是要插入数据库库的参数,一路透传到底(数据库层面),数据库就报数据插入异常。

    一猿小讲
  • 使用 Python 伪造数据

    0 前言 某些时刻,因为个人数据不想泄露出去,所以需要伪造一下数据;也有使用爬虫的时候需要换一下 user agent ,一个用到旧会被发现,最后就是被封结尾...

    伪君子
  • 两分钟带你快速搭建Flutter开发环境(Mac)

    在这篇文章中,将带着大家一起在Mac平台上快速搭建Flutter的开发环境,同时会将搭建Flutter开发环境中的一些技巧和经验分享给大家。

    CrazyCodeBoy
  • 剑指offer之面试题2:实现Singleton模式

    在上述代码中,Singleton1的静态属性Instance中,只有在instance为null的时候才创建一个实例以避免重复创建。

    Vincent-yuan
  • shell脚本快速入门之-----正则三剑客之三awk用法大全!!!

    awk是一种编程语言,用于在linux/unix下对文本和数据进行处理。数据可以来自标准输入、一个或多个文件,或其它命令的输出。它支持用户自定义 函数和动态正则...

    不吃小白菜
  • 《Node.js在CLI下的工程化体系实践》成都OSC源创会分享总结

    腾讯NEXT学位
  • 如何使用HAProxy实现HiveServer2服务的LDAP和Kerberos认证负载均衡

    温馨提示:要看高清无码套图,请使用手机打开并单击图片放大查看。 Fayson的github:https://github.com/fayson/cdhproje...

    Fayson

扫码关注云+社区

领取腾讯云代金券