ARTS打卡:第十周
每周完成一个ARTS:
- Algorithm:每周至少做一个 leetcode 的算法题
- Review:阅读并点评至少一篇英文技术文章
- Tip:学习至少一个技术技巧
- Share:分享一篇有观点和思考的技术文章
Algorithm
66. Plus One(Easy)
Given a non-empty array of digits representing a non-negative integer, plus one to the integer.
The digits are stored such that the most significant digit is at the head of the list, and each element in the array contain a single digit.
You may assume the integer does not contain any leading zero, except the number 0 itself.
Example 1:
Input: [1,2,3]
Output: [1,2,4]
Explanation: The array represents the integer 123.Example 2:
Input: [4,3,2,1]
Output: [4,3,2,2]
Explanation: The array represents the integer 4321.
题意:
给定一个由整数组成的非空数组所表示的非负整数,在该数的基础上加一。
最高位数字存放在数组的首位, 数组中每个元素只存储一个数字。
你可以假设除了整数 0 之外,这个整数不会以零开头。
解题思路:
这道题就非常简单了,利用数学的加法运算思想,倒序遍历数组,如果当前值不等于9,直接加1,然后返回数组,若等于 9,9 + 1 = 10,需要进位,把当前值设为 0,继续遍历数组,依次类推,若最后数组能遍历完,则表明输入数组的值全为9,+1 后,位数发生变化,结果一定是首位为 1,余位为 0 的数组, 所以要重新创建一个数组 result,大小为输入数组的长度 +1,result[0] 设为 1,然后返回数组 result。
代码如下:
1 | class Solution { |
结果:
Runtime: 0 ms, faster than 100.00% of Java online submissions for Plus One.
Memory Usage: 34.2 MB, less than 100.00% of Java online submissions for Plus One.
复杂度分析:
时间复杂度:O(n)
空间复杂度:O(n)
283. Move Zeroes(Easy)
Given an array
nums
, write a function to move all0's
to the end of it while maintaining the relative order of the non-zero elements.Example:
Input: [0,1,0,3,12]
Output: [1,3,12,0,0]Note:
You must do this in-place without making a copy of the array.
Minimize the total number of operations.
题意:
给定一个数组 nums,写一个函数将所有 0
移动至数组末尾,同时保持数组内非零元素的相对顺序。
注意:
- 必须在原数组上操作,不能拷贝额外的数组
- 尽量减少操作次数
解题思路:
由于题目要求要在原数组上操作,不能用额外的数组空间,那我们可以先从如何复用原数组空间出发,结合要求,去解题。
因为要将所有 0 移动至数组末尾且不可改变非零元素的相对位置,那么逐步交换 0 与非零元素的位置即可实现;考虑到要复用原数组空间且减少操作步骤,我们可以不交换位置,逐步将非零元素覆盖 0,直至所有 0 都被覆盖,最后末尾补零即可。
细节请参看代码实现
代码实现:
1 | public static void moveZeroes(int[] nums) { |
结果:
Runtime: 0 ms, faster than 100.00% of Java online submissions for Move Zeroes.
Memory Usage: 36.8 MB, less than 99.94% of Java online submissions for Move Zeroes.
复杂度分析:
时间复杂度:O(n)
空间复杂度:O(1)
Review
本周阅读是:《Introduction to Concurrency in Spring Boot》
作者在文中提供了一些在 Spring Boot 中的处理多线程的实用建议,以及如何避免它可能产生的问题。
- Spring Boot 并发基础知识
在考虑Spring Boot应用程序中的并发性时,值得考虑的关键领域是:- 最大线程数:分配给应用处理请求的最大线程数。
- 共享外部资源:调用外部共享资源,例如数据库。
- 异步方法调用:这些方法调用在等待响应时将线程释放回线程池。
- 共享内部资源:调用内部共享资源,例如缓存和潜在的应用共享状态。
- Spring Boot Application 中的最大线程数
首先我们应该注意,正在处理的线程是有限的。
如果使用的是tomcat,你可以使用属性server.tomcat.max-threads
去控制希望允许多少线程,缺省值是 0,意味着使用 Tomcat 的缺省值 200。 - 使用异步方法调用去解决共享外部资源花费大量等待时间的问题
- 在 Spring Boot 中进行异步调用
在主程序类中的注解@SpringApplication
之上加注解@EnableAsync
,加上之后,可以在你的 Service 方法上加@Asyn
,并将返回结果改为CompletableFuture<>
,这样@Asyn
的方法将后台线程池中运行,合理使用,可以降低性能损耗,提高服务效应效率。 - 控制内部资源,避免与共享相关问题的最佳建议是不要共享它们。
- 如果要共享某些状态,以下是一些建议:
- 处理不可变的对象,如果对象是不可变的,将会避免许多并发问题。如果你需要改变一些东西,那就创建一个新的对象。
- 了解你的集合是否是线程安全的,如果需要并发访问,请使用
ConcurrentHashMap
或者其他线程安全的解决方法。 - 不要假设第三方库是线程安全的。大多数代码都不是,并且必须控制对共享状态的访问。
想要了解更多细节的小伙伴们,请点击原文,查看详情。
Tip
本周分享一个在梁大的知识星球中看到的,有关 lombok 的知识点,不知道 lombok 的小伙伴们,可以查看ARTS 第二周分享中 Tip 那小节。
Share
本周分享:《基于支付场景下的微服务改造与性能优化》,深度好文。