阅读本文大概需要 9 分钟。
每周完成一个 ARTS:
Algorithm 来源 LeetCode 42. Trapping Rain Water
Review 阅读了 Medium 上的一篇关于 写技术博客的重要性 的文章
Tip 总结自己项目中关于 Qt/C++ 中控制线程的一些方法
Share 分享 一个 GitHub 上有趣的、入门级开源项目的月刊
又到周末啦,大家该吃该喝该玩,同时也不要抽点时间忘了学习呀。
下面更新 ARTS 第 十 周的内容。
1.Algorithm
LeetCode 42. Trapping Rain Water 链接 难度:[Hard]
【题意】
Given n non-negative integers representing an elevation map where the width of each bar is 1, compute how much water it is able to trap after raining.
The above elevation map is represented by array [0,1,0,2,1,0,1,3,2,1,2,1]. In this case, 6 units of rain water (blue p) are being trapped. Thanks Marcos for contributing this image!
Example 1:
1 | Input: [0,1,0,2,1,0,1,3,2,1,2,1] |
【思路】
这道题题面描述地很清楚了,感觉也有点意思,那么第一眼看到这道题的时候,首先想到的是贪心,那么怎么贪心,不难想到,我们先以 O(n) 复杂度遍历一遍数组,找到最高的柱子,同时记录下它的位置和高度,接下来,分别从两边向该位置遍历
- 从左边开始向中间遍历,对于遍历的每一个柱子的时候,当有后面的柱子比它高度更高的时候,更新一下当前最高的柱子高度,同时将后面的柱子高度减去前面的柱子高度便是可以蓄水的量。
- 从右边开始向中间遍历的思路跟上面一样。
- 最后输出从左边遍历计算的结果与从右边遍历计算得到的结果之和便是答案。
时间复杂度 O(n),空间复杂度 O(1)。
【参考代码】
1 | #include <bits/stdc++.h> |
2.Review
The Importance of Tech Blogging(英文)
本次 Review 阅读了 Medium 上的一篇关于 写技术博客的重要性 的文章。
觉得写得很不错,分享给大家。
先说明一下,我对作者的整体的观点是赞同的,写博客不仅是对自己学习过的东西一个总结和归纳,更是一个对自己的反思和复盘!
那么来让我们来看看作者在这篇文章里主要强调了什么吧?
作者在文章里主要提到了以下几点
1.写博客的重要性?
作者认为有以下几点
第一点:最重要的一个原因在于,写博客能扩大我们的影响力,作为一名软件工程师,我们在全球范围内运营着很多工作/项目,但我们正在与全世界竞争。
我们应该拥有的是一个全球化的思考力和行动! 科技世界的简历几乎已经死了。 这就是曝光很重要的原因。
人们会找到你,通过阅读你的博客知道你正在做的事情,这样通常会在以后为你提供一些东西。
第二点:作者认为我们要学会抓住机会而不是傻傻的等待机会的来临。
2.什么时候开始写?
作者提供了一个建议,你可以写下你最近做过的有趣的事情,或者写一些你想要更好理解的事情。 不要等待找到一个完美的时间,因为时间都是挤出来的。
3.最后,作者介绍了写博客选择的一些平台
比如 WordPress ,GHost,etc。
个人 review
对于技术博客的重要性,最重要的一个原因,我认为,写博客能扩大我们的影响力,什么意思呢?只有你提高自己的能力和经历后,别人才会对你有一定的信任,才会觉得你靠谱,才会给你机会。而这个信任需要用你的能力和经历填补。比如你经常输出,帮助别人解决难题,做事严谨,又或者有好的头衔背书。
另外在写博客方面,坚持不懈是关键!
共勉~
3.Tip
踩坑记~
Qt/C++ 中控制线程的一些方法
在 Qt 中,如果一个线程运行完成,就会结束。可很多情况并非这么简单,由于某种特殊原因,当线程还未执行完时,我们就想中止它。
不恰当的中止往往会引起一些未知错误。比如:当关闭主界面的时候,很有可能次线程正在运行,这时,就会出现如下提示:
QThread: Destroyed while thread is still running
这是因为次线程还在运行,就结束了 UI 主线程,导致事件循环结束。这个问题在使用线程的过程中经常遇到,尤其是耗时操作。
在此问题上,常见的两种方法:
1.直接忽略此问题。
2.强制中止 - terminate()。
大多数情况下,当程序退出时,子线程也许会正常退出。这时,虽然抱着侥幸心理,但隐患依然存在,也许在极少数情况下,就会出现 Crash。
正如前面提到过 terminate(),比较危险,不鼓励使用。线程可以在代码执行的任何点被终止。线程可能在更新数据时被终止,从而没有机会来清理自己,解锁等等。。。总之,只有在绝对必要时使用此函数。
所以,我们应该采取合理的措施来优雅地结束线程,一般思路:
1.发起线程退出操作,调用 quit() 或 exit()。
2.等待线程完全停止,删除创建在堆上的对象。
3.适当的使用 wait()(用于等待线程的退出)和合理的算法。
下面介绍两种方式:
一.QMutex互斥锁 + bool成员变量。
这种方式是 Qt4.x 中比较常用的,主要是利用 “QMutex互斥锁 + bool成员变量” 的方式来保证共享数据的安全性(可以完全参照下面的 requestInterruption() 源码写法)。
为什么要加锁?很简单,是为了共享数据段操作的互斥。
何时需要加锁?在形成资源竞争的时候,也就是说,多个线程有可能访问同一共享资源的时候。
当主线程调用 stop() 更新 m_bStopped的时候,run() 函数也极有可能正在访问它(这时,他们处于不同的线程),所以存在资源竞争,因此需要加锁,保证共享数据的安全性。
二.Qt5以后:
requestInterruption() + isInterruptionRequested()
这两个接口是 Qt5.x 引入的。
4.Share
HelloGitHub 中文
最近发现了一个特别棒的网站!
一个分享 GitHub 上有趣的、入门级开源项目的月刊,每个月 28 号发布。
想要搜索不同编程语言下的不同的开源项目的时候,使用这个网站吧!简直不能太方便!
爱学习,爱技术