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

Algorithm LeetCode算法

合并连个有序链表

(https://leetcode.com/problems/merge-two-sorted-lists/)

题目描述​:将两个有序链表合并为一个新的有序链表并返回。新链表是通过拼接给定的两个链表的所有节点组成的。

示例 1:

输入:1->2->4, 1->3->4
输出:1->1->2->3->4->4

这个题目一看到的时候,吓我一跳,这个给出的链表,对于链表这个结构不是很熟悉的我来说,简直是一脸懵逼。讲真,小编一开始,连一个链表怎么创建都不知道,更不用说来解答了。

怎么办,拿到题目,看也没看,就在文章先写上了,那就只能迎着头皮去做了呗。什么数据结构与算法啊,什么算法导论都搬出来看下,哈哈,或许这就是这个打卡的意义所在吧。

这也给我敲了一个警钟,业务逻辑代码写的怎么样,并不代表编程能力怎么样;有经验的程序员更看重的就是基础的能力吧。大佬也说过,很多程序员都在不停地对业务代码进行bug的修改,没有系统的对基础进行学习,这也是我们要来刷题的目的之一吧。好啦,小编最后这道题是借助了网络能力才解答出来的,并不是真正的解答了,惭愧惭愧。

给出了三个解决方案,前两个是递归,最后一个不是,大家可以细细品味。网上的方法很多,顺带学习了下链表,真的很受用噢。

public static ListNode mergeTwoLists1(ListNode l1, ListNode l2) {
if (l1 == null) return l2;
if (l2 == null) return l1;
ListNode head = (l1.val < l2.val) ? l1 : l2;
ListNode nonhead = (l1.val < l2.val) ? l2 : l1;
head.next = mergeTwoLists1(head.next, nonhead);
return head;
}


public static ListNode mergeTwoLists(ListNode l1, ListNode l2) {
if (l1 == null)
return l2;
if (l2 == null)
return l1;
if (l1.val < l2.val) {
l1.next = mergeTwoLists(l1.next, l2);
return l1;
} else {
l2.next = mergeTwoLists(l1, l2.next);
return l2;
}
}


public static ListNode mergeTwoListsNew(ListNode l1,ListNode l2) {
if (l1 == null) {
return l2;
}


if (l2 == null) {
return l1;
}
ListNode dummy = new ListNode(-1), cur = dummy;
while (l1 != null && l2 != null) {
System.out.println("l1.val = " + l1.val + " l2.val = " + l2.val);
if (l1.val < l2.val) {
cur.next = l1;
l1 = l1.next;
} else {
cur.next = l2;
l2 = l2.next;
}
cur = cur.next;
}
cur.next = (l1 != null) ? l1 : l2;
return dummy.next;
}

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

睡眠质量比任何编程语言任何软件开发方法论都要重要

(https://threadreaderapp.com/thread/1119709859979714560.html?utm_source=wanqu.co&utm_campaign=Wanqu+Daily&utm_medium=website)

不知道怎么的,这篇文章看的有点云里雾里,感觉像是技术文,又感觉不像,尴尬尴尬。

作者率先提出了观点之一就是“你的睡眠质量和压力水平远远超过你使用的语言或你遵循的做法。”看完这个懵逼了,但是文中还有地方说道,如果你们周做50个小时的工作,那么在8到10周之后,你每周的工作效率低于40hpw的人,哈哈,这个和之前说的996.icu很像啊,说明长时间工作,不仅不能提升工作效率,反而还会减少。

文末也提到,没有任何方法,工具,语言,几乎与我们自己的思想一样重要。如果你想写出好的代码,那就要保证自己的健康,没有其他的要求。每每看到科技板块里出现某某人猝死,都时刻提醒自己,要记得锻炼、记得锻炼、记得锻炼。重要的事情说三遍,身体是革命的本钱。

朋友们,你想当一名优秀的程序员吗?你想写好代码吗?你想快乐的工作吗?那请你行动起来,保证好的睡眠,保证健康的身体,那你所想的一切,都会来的。

Tip 一个技术技巧

继续分享《Java核心技术36讲》做的学习笔记,关于内存模型和Java在Docker中运行的情形。

因为自己的主业是Java和Android开发,但是还没到精的地步,所以这些知识对我来说确实是蛮好用的,虽然很多还不明白,但这和读书一样,先把书读薄,再把书读厚,知识的储备就来了,加油加油。

第29讲 | Java内存模型中的happen-before是什么

Java内存模型(Java Memory Model,JMM)

典型回答

它的具体表现形式 ,包括但远不止是我们直觉中的synchronized、volatile、lock操作顺序等方面,例如:


  • 线程内执行的每个操作,都保证happen-before后面的操作,这就保证了基本的程序顺序规则,这是开发者在书写程序时的基本约定
  • 对于volatile变量,对它的写操作,保证happen-before在随后对该变量的读取操作
  • 对于一个锁的解锁操作,保证happen-before加锁操作
  • 对象构建完成,保证happen-before于finalizer的开始动作
  • 甚至是类似线程内部操作的完成,保证happen-before其他Thread.join()的线程等

volatile只保证可见性

第30讲 | Java程序运行在Docker等容器环境有哪些新问题?

典型回答


  • 如果未配置合适的JVM堆和元数据区、直接内存等参数,Java就有可能试图使用超过容器限制的内存,最终被容器OOM kill,或者自身发生OOM
  • 错误判断了可获取的CPU资源,例如Docker限制了CPU的核数,JVM就可能设置不合适的GC并行线程数等

考点分析

有基础的话,可以从操作系统、容器原理、JVM内部机制,软件开发实践等角度,展示系统性分析新问题、新场景的能力。毕竟,变化才是世界永远的主题,能够在新变化中找出共性与关键,是优秀工程师的必备能力

知识扩展

Docker之类容器和向虚拟机非常相似,例如它有自己的shell,能独立安装软件包,运行时与其他容器互不干扰。但是,如果深入分析你会发现,Docker并不是一种完全的虚拟化技术,而更是一种轻量级的隔离技术


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

Dimple在左耳听风ARTS打卡(第七期)_链表