Nicksxs's Blog

What hurts more, the pain of hard work or the pain of regret?

拖更原因

这篇年终总结本来应该在农历过完年就出来的,结果是对没有受疫情影响的春节放假时间空闲情况预估太良好,虽然公司调了几天假,但是因为春节期间疫情状况比较好,本来酒店都不让接待聚餐什么的,后来统统放开,结果就是从初一到初六每天要不就是去亲戚家,要不就是去酒店饭店吃饭,计划很丰满,现实很骨感,时间感觉一下就没了,然后年后感觉有点犯懒了,所以才拖到现在。

生活-健身跑步

去年(19 年)的时候跑步突破了 300 公里,然后20 年给自己定了个 400 公里的目标,结果意料之中的没成功,原因可能疫情算一点吧,后面买了跑步机之后,基本周末回家都能跑一下,但是最后还是只跑了300 多公里,总的keep 记录跑量也没超过 1000 公里,所以跑步这个目标还是没成功的,不过还算是比去年多跑一点,这样也算后面好突破点,后面的目标就不定的太高了,每年能比前一年多一点就好,其实跑步已经从一种减肥方式变成一种习惯了,一周一次的跑步已经比较难有效减重了,但是对于保持精力和身体状态还是很有效和重要的,只是对于目前的体重还是要多减下去一些跑步才好,太重了对膝盖负担太大了,可惜还是时间呐,游泳骑车什么的都需要更苛刻的条件和时间,饮食呢控制起来比较难(贪吃
终于在 3 月底之前跑到了 1000 公里,迟了三个月,不过也总算达到了,只是体重控制还是不行,有试着走走楼梯,但是感觉对膝盖负担比较大,得再想想用什么方式

技术成长

一直提不起笔来写这篇年终总结还有个比较大的原因是觉得20 年的成长不如预期,大小目标都没怎么完成,比如深入了解 jvm,是想能有些深入的见解,而不再是某些点的比较片面的理解,系统性的归纳总结也比较少,每个方向或多或少有些看法和理解,但是不全面,一些东西看过了也会忘记,需要温故而知新,比如 AQS 的内容,第一次读其实理解比较浅,后面就强迫自己去读,去写,才有了一些比之前更深入的理解,因为很多文章都是带有作者思路的引导,适不适合自己都要看是否能从他的思路把它看懂,有些就差别很大,这个跟看书也一样,有些书大众一致推荐,一般情况下大多是经典的好的,但是也有可能是不太适合自己的,可能有时候机缘巧合看到的反而让人茅塞顿开,在 todo 里已经积攒了好多的点和面需要去学习实践,一方面是自己懒,一方面是时间也相对偏少,看看 21 年能不能有所提升,加强“时间管理”,哈哈

技术上主要是看了 mysql 的 mvcc 相关内容,rocketmq 的,redis 的代码,还有 mybatis 等,其实每一个都能写很多,也有很多值得学习的,需要全面系统学习,之前想好好画一个思维导图,将整个技术体系都梳理下,还只做了一点点,方式也有点问题,应该从大到小,而不是深度优先,细节有很多,每一个方面都有自己比较熟悉擅长的,也有不太了解的,可以做一个评分,这个也是亟待改善的,希望今年能完成。

博客

博客方面 20 年一年整是写了 53 篇,差不多是一周一篇的节奏,这个还是不错的,虽然博客质量参差不齐,但是这个更新频率还是比较好的,并且也定了个潜规则,可以一周技术一周生活,这样能缓解水文的频率,提高些技术文章的质量,虽然结果并没有好多少,不过感觉还是可以这么坚持的,能提高一些技术文章的质量那就更好了

top 命令在日常的 Linux 使用中,特别是做一些服务器的简单状态查看,排查故障都起了比较大的作用,但是由于这个命令看到的东西比较多,一般只会看部分,或者说像我这样就会比较片面地看一些信息,比如默认是进程维度的,可以在启动命令的时候加-H进入线程模式

1
2
3
-H  :Threads-mode operation
Instructs top to display individual threads. Without this command-line option a summation of all threads in each process is shown. Later
this can be changed with the `H' interactive command.

这样就能用在 Java 中去 jstack 中找到对应的线程
其实还有比较重要的两个操作,
一个是在 top 启动状态下,按c键,这样能把比如说是一个 Java 进程,具体的进程命令显示出来
像这样
执行前是这样

执行后是这样

第二个就是排序了

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
SORTING of task window

For compatibility, this top supports most of the former top sort keys. Since this is primarily a service to former top users, these commands
do not appear on any help screen.
command sorted-field supported
A start time (non-display) No
M %MEM Yes
N PID Yes
P %CPU Yes
T TIME+ Yes

Before using any of the following sort provisions, top suggests that you temporarily turn on column highlighting using the `x' interactive com‐
mand. That will help ensure that the actual sort environment matches your intent.

The following interactive commands will only be honored when the current sort field is visible. The sort field might not be visible because:
1) there is insufficient Screen Width
2) the `f' interactive command turned it Off

< :Move-Sort-Field-Left
Moves the sort column to the left unless the current sort field is the first field being displayed.

> :Move-Sort-Field-Right
Moves the sort column to the right unless the current sort field is the last field being displayed.

查看 man page 可以找到这一段,其实一般 man page 都是最细致的,只不过因为太多了,有时候懒得看,这里可以通过大写 M 和大写 P 分别按内存和 CPU 排序,下面还有两个小技巧,通过按 x 可以将当前活跃的排序列用不同颜色标出来,然后可以通过<>直接左右移动排序列

事情源于周末来回家发生的两件事情,先是回去的时候从高铁下车要坐公交,现在算是有个比较好的临时候车点了,但是可能由于疫情好转,晚上都不用检查健康码就可以进候车点,但是上公交的时候还是需要看健康码,一般情况下从高铁下来的,各个地方的人都有,而且也不太清楚这边上公交车需要查验健康码,我的一个看法是候车的时候就应该放个横幅告示,或者再配合喇叭循环播放,请提前准备好健康码,上车前需要查验,因为像这周的情况,我乘坐的那辆车是间隔时间比较长,而且终点是工业开发区,可能是比较多外来务工人员的目的地,正好这部分人可能对于操作手机检验健康码这个事情不太熟悉,所以结果就是头上几个不知道怎么搞出来健康码,然后让几乎有满满一整车的人在后面堵着,司机又非常厌烦那些没有提前出示健康码的,有位乘客搞得久了点,还被误以为没刷卡买票,差点吵起来,其实公共交通或者高铁站负责的在公交指引路线上多写一句上车前需要查验健康码,可能就能改善比较多,还有就是那个积水的路,这个吐槽起来就一大坨了,整个绍兴像 dayuejin 一样到处都是破路。
第二个就是来杭州的时候,经过人行横道,远处车道的公交车停下来等我们了,为了少添麻烦总想快点穿过去,但是这时靠近我们的车道(晚上光线较暗,可见度不佳)有一辆从远处来的奥迪 A4 还是 A5 这种的车反而想加速冲过去,如果少看一下可能我已经残了,交规考的靠近人行道要减速好像基本都是个摆设了,杭州也只有公交车因为一些考核指标原因会主动礼让,人其实需要有同理心,虽然可能有些人是开车多于骑车走路的,但是总也不可能永远不穿人行道吧,甚至这些人可能还会在人行道红灯的时候走过去。这个事情不是吐槽公共交通的,只是也有些许关系,想起来还有一件事也是刚才来杭州的时候看到的,等公交的时候看到有辆路虎要加塞,而目标车道刚好是辆大货车,大货车看到按了喇叭,路虎犹豫了下还是挤进去了,可能是对路虎的扛撞性能非常自信吧,反正我是挺后怕的,这种级别的车,被撞了的话估计还是鸡蛋撞石头,吨位惯性在那,这里再延伸下,挺多开豪车的人好像都觉得这路上路权更大一些,谁谁都得让着他,可能实际吃亏的不多,所以越加巩固了这种思维,当真的碰到不管的可能就会明白了,路权这个事情在天朝也基本没啥人重视,也没想说个结论,就到这吧

题目介绍

You are given an array prices where prices[i] is the price of a given stock on the ith day.

You want to maximize your profit by choosing a single day to buy one stock and choosing a different day in the future to sell that stock.

Return the maximum profit you can achieve from this transaction. If you cannot achieve any profit, return 0.

给定一个数组 prices ,它的第 i 个元素 prices[i] 表示一支给定股票第 i 天的价格。

你只能选择 某一天 买入这只股票,并选择在 未来的某一个不同的日子 卖出该股票。设计一个算法来计算你所能获取的最大利润。

返回你可以从这笔交易中获取的最大利润。如果你不能获取任何利润,返回 0

简单分析

其实这个跟二叉树的最长路径和有点类似,需要找到整体的最大收益,但是在迭代过程中需要一个当前的值

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
int maxSofar = 0;
public int maxProfit(int[] prices) {
if (prices.length <= 1) {
return 0;
}
int maxIn = prices[0];
int maxOut = prices[0];
for (int i = 1; i < prices.length; i++) {
if (maxIn > prices[i]) {
// 当循环当前值小于之前的买入值时就当成买入值,同时卖出也要更新
maxIn = prices[i];
maxOut = prices[i];
}
if (prices[i] > maxOut) {
// 表示一个可卖出点,即比买入值高时
maxOut = prices[i];
// 需要设置一个历史值
maxSofar = Math.max(maxSofar, maxOut - maxIn);
}
}
return maxSofar;
}

总结下

一开始看到 easy 就觉得是很简单,就没有 maxSofar ,但是一提交就出现问题了
对于[2, 4, 1]这种就会变成 0,所以还是需要一个历史值来存放历史最大值,这题有点动态规划的意思

最近看了下这本垃圾回收算法手册,看到了第三章的标记-整理回收算法,做个简单的读书笔记

双指针整理算法

对于一块待整理区域,通过两个指针,free 在区域的起始端,scan 指针在区域的末端,free 指针从前往后知道找到空闲区域,scan 从后往前一直找到存活对象,当 free 指针未与 scan 指针交叉时,会给 scan 位置的对象特定位置标记上 free 的地址,即将要转移的地址,不过这里有个限制,这种整理算法一般会用于对象大小统一的情况,否则 free 指针扫描时还需要匹配scan 指针扫描到的存活对象的大小。

Lisp 2 整理算法

需要三次完整遍历堆区域
第一遍是遍历后将计算出所有对象的最终地址(转发地址)
第二遍是使用转发地址更新赋值器线程根以及被标记对象中的引用,该操作将确保它们指向对象的新位置
第三次遍历是relocate最终将存活对象移动到其新的目标位置

引线整理算法

这个真的长见识了,

可以看到,原来是 A,B,C 对象引用了 N,这里会在第一次遍历的时候把这种引用反过来,让 N 的对象头部保存下 A 的地址,表示这类引用,然后在遍历到 B 的时候在链起来,到最后就会把所有引用了 N 对象的所有对象通过引线链起来,在第二次遍历的时候就把更新A,B,C 对象引用的 N 地址,并且移动 N 对象

单次遍历算法

这个一直提到过位图的实现方式,

可以看到在第一步会先通过位图标记,标记的方式是位图的每一位对应的堆内存的一个字(这里可能指的是 byte 吧),然后将一个存活对象的内存区域的第一个字跟最后一个字标记,这里如果在通过普通的方式就还需要一个地方在存转发地址,但是因为具体的位置可以通过位图算出来,也就不需要额外记录了

0%