疯狂加班快4个月,资本家坚持走国际一线的12小时6天的工作强度。
最近在反思一个加班这个事情的好与坏,在若干年前,我并不抵制加班,觉得加班还能给我带来一些收获。因为那时候我还有很多东西不懂,需要学习。
现在不同了,并不是我不需要学习了;而是在反思加班是不是成为一种疲劳战的无意义行为。
首先说一下引发,我这种想法的主要原因:
1,上班地点距离住处有20km+,每天往返需要不少于2小时
2,公司加班对我的吸引太小(没有工资、没有利益、也没有任何有意义的学习收获)
3,资本家纯粹为了压缩成本和排挤人员的一种手段而已。
先看一看现在一些所谓的“大公司”是如何通过诱人的“条件”来吸引员工加班:
1,年终奖(小命在人家手里,呵呵~~~当然还有其他类似的手段)
2,营造“轻松的”气氛(有免费咖啡、有免费晚餐、有娱乐或健身场所)
3,kpi(请参考某厂)
4,虚荣心(各种莫名其妙的头衔,让员工增加对公司的认同感)
5,引入人为的竞争机制
6,企业联盟,形成圈内加班文化
7,其他(各种培训,各种活动;这些是一种调节)
最近头发掉的有点多了,整个人状态也有点不对劲了,不再像之前那样学习和工作效率那么高了。除了一些工作上分工的变化(精力分散),还有就是疲劳战。
目前所待的一家公司是一个小公司,行业前景不错,但老板过于强势以及心心胸狭隘;目前公司虽然走在相对高速发展的路上,但未来很有可能要出大事。
老板为了节约成本,倒逼研发体系能够快速的完成他自己认为的一些所谓的“优秀需求”,提出了加班这个要求。
事实上,加班要加的有效也是一个很难的事情。出工不出力,出力不出正常的力,也是我所遇到的加班情况中比较常见的几种现象。
当宣布进行加班的那天开始,我就在想加班的时候要做点什么好呢?
1,写工作上的代码?
2,看书?
3,娱乐?
4,果断不加班?
首先我否决掉的是1,3,4。原因有几点,老板是做销售出生的人,不懂技术。而做销售出生的人,往往有一种特点,就是急功近利。
情商高的销售,能力强的销售,是解决问题;情商低的销售,能力低的销售,则是为了赚钱不顾一切!从老板强制加班,且不做任何铺垫或者有意义的准备工作上来看,老板应该属于比后者稍强,比前者较弱的一个人。
至于娱乐和不加班,基本不太可能,主要是公司没有提供任何娱乐场所,另外就是除了想跑里,还是只能乖乖的呆在这里熬时间!
因此,我就开始了我的看书计划;一周6天,拿5天来看书,但实际上只有4天在看书。
差不多也看了快半年的书,差不多也快看完2本900多页有一定难度的技术类书籍。直到今天开始,才发现看书效率正在下降,接受和学习能力正在逐渐变弱。
反思得知:
1,疲劳了
2,迷茫了
3,没有当初那么有激情了
4,吸引我的事情正在逐渐淡化了。
就从我本人的性格来看,实际上,只要是不是累的快不行,一般情况下1不会成为主要的问题。就目前来说,更多的还是4和2。所谓身体上的疼痛(腰背疼痛),主要是还是由于情绪所带来的放大或者突出而已。实际上, 现在的人谁身上没几个毛病?
所以今天特意抽个时间,出来反思一下,加班到底有没有用,要不要做出一些改变来。
今天把工程全部转换成了vs 2013,主要是通过vs2013下的一些动静态代码检查功能。转换成vs 2013以后,发现编译器的检查更加严格了。一些警告会被视为异常,例如:
OSVERSIONINFO sInfo;
sInfo.dwOSVersionInfoSize = sizeof(sInfo);
GetVersionEx(&sInfo);
这段代码在vs 2013默认语法检查规则中是编译无法通过的。
查看msdn对GetVersionEx的说明(https://msdn.microsoft.com/zh-cn/library/ms724451(v=vs.85).aspx)
[GetVersionEx may be altered or unavailable for releases after Windows 8.1. Instead, use the Version Helper APIs]
该api由于不安全,在windows 8.1中会有一组函数进行对其替代。同时,对stl和编译预处理的检查将开始更为严格。后续需要对windows 8.1的api和之前windows的api进行差异性了解。通过可得知vs 2013的设计就是为了操作系统而准备的,有意或无意的改变程序员的部分编程习惯。
代码段如下:
#ifdef TEST_FLAG
#define MACRO_TEST_1(x) OutputDebugString(x)
#else
#define MACRO_TEST_1
#endif
static TCHAR g_all[] = _T("test_for_macro\r\n");
TCHAR* test_for_macro()
{
OutputDebugString(_T("call test_for_macro\r\n"));
return g_all;
}
当 TEST_FLAG 被定义和未被定义时,将会出现运行结果。
其实这个是一个老生常谈的问题,关于编译器在对宏的处理情况。
如果堆栈数据空间地址被恶意或无意的修改,导致执行了不该执行或数据段的二进制值指令叫做溢出攻击的话;这类宏的情况,在某些情形下也属于宏攻击。
首先从进程角度去看,内部其实是由一个或者若干个线程组成。因此在理解进程频繁创建和关闭导致的开销问题,只需要理解一个单一线程的频繁创建和关闭即可。
CreateThread、TerminateThread
这两个函数一个用于创建线程,另一个用于关闭线程。
1,先说一下线程创建的过程。对于CreateThread来说,创建的均为用户态线程。尽管创建的是用户态线程,但对于函数被调用者来说,本身还是需要切换到内核态或等待内核态服务线程将线程创建起来。
仅从这一点去看,有了态切换。显然就存在各种开销。
2,在内核创建好线程以后,这个线程将会被纳入windows的线程调度中,同时该线程所占有的内存资源也会被纳入内存调度中。仅从这里去看,又可以看到两个调度器的任务增加,且内存资源在减小。
3,在线程退出后,内核需要对其内存进行回收。在回收过程中,需要对线程的堆栈等系统分配给的内存资源进行校验(退出时的crash生成也在这一步)。检查完成以后,又要将回收回来的内存插回到windows的堆栈管理器里面(不管是crt堆,还是win32堆或者系统堆,都要插回去)。在回插内存的时候,可能还会引发堆内存的合并和子堆往父堆进行归还的过程。
通过以上描述,基本可得知线程的创建和关闭的开销是相当大的事情。
如果再深入一点看的话,可能会更清楚一些。
由于在windows系统以后,系统会“虚拟”出一个system进程,该进程内部其实是一堆辅助线程(有时候创建IO句柄时,也会出现这个进程里面的线程数增加,或者做调试的时候也有可能会出现类似的现象)。
system里面的线程,主要是用于服务在不同IRQL和内核用户态之间。换句话说,相当于一个桥(个人猜测,不负责哈!)。
当一个线程要进行关闭时,该system里面的辅助线程(15级以上),会对线程回收工作进行处理。换句话说,如果一个线程自己是正常退出的,那么自己会抛一个系统请求给system,让system把自己的内存回收掉。这个过程又要走一堆windows服务程序(服务端口),从这一点上看可得知。
一个线程的关闭,势必会激活一个“紧急”任务的进行,且会涉及到一个较长的流程。应此无论是创建还是关闭线程,如果执行频度太过于高,显然是不行的。