本书主要收录了蔡元培先生给学生授课所用的《华工学校讲义》和《中学修身教科书》,还有数篇关于道德修养的演讲稿,充分体现了蔡元培先生对于现代中国人应具有的道德素养的总体构想。
书中内容,主要是用半白话,半文言文方式写成的。既有中华传统文化,还有欧美进步思想。时隔近百年,仍被蔡元培先生学贯中西,迫切想提升民族道德修养的精神所感动。
先生在书中多次强调,体育、美育、德育的重要作用,我想这也是当下内卷时代最应该“卷”的方向。
如今,我们的物质生活极大丰富,而精神生活却极度匮乏,这部一百年前的书仍有非常重要的指导意义。
何谓“道德”?蔡元培先生认为
人之生也,不能无所为,而为其所当为者,是谓道德。道德者,非可以猝然而袭取也,必也有理想,有方法。吾国圣人,以孝为百行之本,小之一人之私德,大之国民之公义,无不由是而推演之者,故曰唯孝友于兄弟,施于有政,由是而行之于社会,则宜尽力于职分之所在,而于他人之生命若财产若名誉,皆护惜之,不可有所侵毁。行有余力,则又当博爱及众,而勉进公益,由是而行之于国家,则于法律之所定,命令之所布,皆当恪守而勿违。而有事之时,又当致身于国,公而忘私,以尽国民之义务,是皆道德之教所范围,为吾人所不可不勉者也。
如何培养良好的道德?
夫道德之方面,虽个个不同,而行之则在己。知之而不行,犹不知也;知其当行矣,而未有所以行此之素养,犹不能行也。怀邪心者,无以行正义;贪私利者,无以图公益。未有自欺而能忠于人,自侮而能敬于人者。故道德之教,虽统各方面以为言,而其本则在乎修己。修己之道不一,而以康强其身为第一义。身不康强,虽有美意,无自而达也。康矣强矣,而不能启其知识,练其技能,则奚择于牛马;故又不可以不求知能。知识富矣,技能精矣,而不率之以德性,则适以长恶而遂非,故又不可以不养德性。是故修己之道,体育、智育、德育三者,不可以偏废也。
蔡元培先生认为,但使物质生活与精神生活在不可兼得的时候,孔子一定偏重精神方面。他从3个方面观察孔子的精神生活:
除了以上三个方面外,还有2个特点:
最后,他说
以智、仁、勇为范围,无宗教的迷信而又音乐的陶养,这是完全可以为师法的。
先生认为,知识可以解决眼前的问题,而情感可以解决长远问题。
人的一生,不外乎意志的活动,而意志是盲目的,其所恃以为较近之观照者,是知识;所以供远照、旁照之用者,是感情。
当着重要关头,有“富贵不能淫,贫贱不能移,威武不能屈”的气概;甚且有“杀身以成仁”而不“求生以害仁”的勇敢;这种是完全不由知识的计较,而由于感情的陶养,就是不源于智育,而源于美育。
先生建议,我们平时除了工作之外 ,一定要多读书、听音乐。
所以吾人固不可不有一种普通职业,以应利用厚生的需要;而于工作的余暇,又不可不读文学,听音乐,参观美术馆,以谋知识与感情的调和,这样,才算是认识人生的价值了。
蔡元培先生认为,我们要实现民族复兴,需要从以下3个方面入手:
总结起来,还是体育、智育、德育这3个方面。
每个人都有不同程度的自卑感,因为没有一个人对其现时的地位感到满意;对优越感的追求是所有人的通性。然而,并不是人人都能超越自卑,关键在于正确对待职业、社会和性,在于正确理解生活。——阿尔弗雷德·阿德勒
本书成书于1932年,距今将近100年,书中谈到了童年、家庭、学校等方方面面对个人成长的影响,也举了很多案例,虽然感觉不成体系,但是有些观点还是值得反复咀嚼的。
本书一开篇,作者就带着我们探讨生活的意义,他提出人活在地球上,会受到三种限制:
对于个体来说,就是每个人不得不面临的职业
、社交
和性
的问题。几乎所有的失败者,都处理不好这些关系,其根本原因是缺乏归属感和社会兴趣。作者提出,合作才是解决之道,包括在家庭和学校,都要广泛培养孩子的合作能力。
作者否定了遗传决定性格的观念,他认为“人之初,性本善”或“性本恶”的想法是站不住脚的,人们最终选择走向何方,取决于他从环境所接受的感觉和印象,以及他对这些感觉和印象的解释。他还否认卓越出自于天赋,甚至连莫扎特这样的音乐天才,他都不认为是天赋起了决定作用,这个观点与刻意练习的理论不谋而合。
不是说有强烈自卑感的人一定是个显得柔顺、安静、拘束而与世无争的人。愤怒、眼泪、紧张、道歉都可能是自卑的表现。
我们每个人都有不同程度的自卑感,因为我们都想让自己变得更优秀。如果我们勇往直前,通过改进环境,可以逐渐摆脱自卑感。就像作者所说,人类的全部文化都是以自卑感作为基础的,在每件人类的行为之后,都隐藏有对优越感的追求,比如,科学的兴起就是因为人类感到他们的无知,和他们对预测未来的需要,从而努力奋斗的结果。
可是,没有人能长期忍受自卑感,如果暂时摆脱不了自卑感,他的目标仍然是“凌驾于困难之上”,可是他却不再设法克服障碍,反倒用一种优越感来自我陶醉或麻木自己。同时,他的自卑感会愈积愈多,因为造成自卑的情境仍然一成未变,问题也依旧存在。他所采取的每一步都会逐渐将他导入自欺之中,而他的各种问题也会以日渐增大的压力逼迫着他。他不是把自己锻炼得更强壮、更有适应能力,而是训练自己,让自己在自己的眼中显得更强壮。他可以用这种方式来麻醉自己,但是他的自卑感仍然原封未动。
P20
每种生活问题的解决都需要合作的能力,而每种工作也都必须在人类社会的架构下,以能够增进人类福利的方式来予以执行,只有了解生活的意义在于奉献的人,才能够有较大的机会成功地克服困难。如果老师、父母及心理学家们都能了解:赋予生活以某种意义时可能会犯错误,当遇到问题时,我们应该不断努力,而不能把肩上的重担推给别人、口出怨言以博取关怀和同情,或觉得非常丢脸而自暴自弃。我们应该说: “我们必须开拓我们的生活。这是我们的责任,我们也能够对付它。我们是自己行为的主宰。除旧布新的工作,舍我其谁!”假如每个独立自主的人,都能以这种合作的方式来对待生活,那么人类社会的进步必然是无止境的。
P45
争取优越感的动作总是朝向生活中无用的一面,真正的问题却被遮掩起来或避开不谈。个人限制了他的活动范围,苦心孤诣地要避免失败,而不是追求成功。他在困难面前会表现出犹疑、彷徨,甚至是退却的举动。
P134
事实上,不仅是我们的社会生活,我们的整个世界都是如此——那么我们便会认识到:人类都在追求想要成为征服者,想要超越并压垮别人的目标。这种目标是早年训练的结果,也是觉得自己在家庭中未曾受到平等待遇的儿童努力奋斗、拼命竞争的结果。我们要避免这一类的危害,唯一的方法就是给予儿童更多的合作训练。
P142
在我们现行的教育制度下,我们通常会发现:当孩子开始上学时,他们对竞争的准备比对合作的准备更为充分。在他们的学校生活中,对竞争的训练也一直持续不断。对孩子而言,这是一种不幸。假如他击败了别的孩子,遥遥领先,他的不幸并不见得比屈居人后而万念俱灰的孩子少。在这两种情况下,他都会变得只对自己感兴趣。他的目标将不会是奉献和施予,而是夺取能供自己享用之物。正如家庭应该团结一致,每个成员都是团体中平等的一分子一样,班级里的同学也应该如此。只有按照这个方向开展教育,孩子们才会真正彼此感兴趣,并享受到合作的快乐。
P146
现在,有许多精神病学家和心理学家也都殊途同归地得出同样的看法,认为性格中有遗传成分的信念只能称为迷信而已。这种迷信已经存在几千年了。当人们想要逃避责任,并对人类行为采取宿命论的观点时,性格特征是来自遗传的理论便自然而然地出现。它最简单的形式就是“人之初,性本善”或“性本恶”的想法。这种说法显然是站不住脚的,只有逃避责任的欲望很强的人才会坚持它。“善恶”像其他各种性格的表现一样,只有在社会环境中才有意义。它们是在社会环境中和同类相互切磋所得的结果,它们蕴含了一种判断,“顾全他人的利益”,或“违反他人的利益”。在孩子出生之前,他并没有这一类的社会环境。出生之后,他的潜能足以使他往任何一个方向发展。他所选择的途径决定于他从环境和从自己身体所接受的感觉和印象,以及他对这些感觉和印象的解释。
P178
罪犯全部都是懦夫。他们逃避了他们觉得自己的能力不足以应付的问题。除了他们所犯的罪行之外,我们可以在他们面对生活的方式中看出他们的懦弱。即使是在他们所犯的罪行里,我们也可以看到他们的懦弱。他们隐藏在僻静和黑暗中,恐吓过往行人,在行人采取防卫措施之前先亮出了武器。罪犯以为自己是很勇敢的,但是我们绝不可认同他们的想法,否则,我们就被愚弄了。罪行是懦夫模仿英雄行径的表现。他们在追求着一种自己构想出来的个人优越感目标,他们以为自己是英雄,但其实这又是一种错误的统觉表,也是缺少常识的表现。我们知道他们是懦夫,假如他们知道我们对这一点很清楚时,必然会大吃一惊。
P199
我们发现,在形形色色的罪犯之间,在各种不同的失败者之间,他们最主要的共同点就是缺乏合作精神,缺乏对别人及对人类幸福的兴趣。
P212
有些孩子在16岁结束高中学业之时,对自己未来的职业仍然拿不定主意。他们经常是品学兼优的学生,但是对以后的生活却一点主意也没有。如果详加注意,我们会发现这些孩子大多野心勃勃,不过却不肯真正与人合作。
P221
我们应该认识到,婚姻并不是私人的事情,而是全体人类在心灵上和精神上都必须参与的共同事务。结婚之后,双方都必须负起某些责任,这是整个社会对他们的期待。社会希望他们生育健全的子女,并以合作的精神将之抚育成人。因此,在每一桩婚姻中,每一个人都应当乐于合作。原始社会用图腾和其复杂的制度来控制婚姻的方法,在今日看来也许相当可笑,但是它们在当时的重要性则是不容忽视的。它们的真正目的在于增加人类的合作。在生活中会遭遇最大困难,并做出损人利己之事的人,就是对其同胞不感兴趣的人。人类所有的失败者都是从这批人中孕育出来的。各种不同的宗教都以自己的方式鼓励合作。站在我的观点,任何人类的努力,只要是以合作为最高目标的,我都完全赞同。争执、批评和贬抑对方都是不必要的。
P226
忧郁症患者还有以自杀作为报复手段的倾向,因此医生第一件要注意的事,就是避免给他们自杀的借口。我自己解除这种紧张的方法是向他们建议治疗中最重要的规则:“不要做你不喜欢做的任何事情。”这似乎是微不足道的小事,但是我相信它牵涉到整个问题的基础。
P235
我们甚至可以说,要完全解决这种两个人的合作问题,每一个配偶都应该关心对方更甚于关心自己。这是爱情和婚姻成功的唯一基础。我们应该已经能够看出,许多关于婚姻的意见及其改革计划都犯了什么样的错误。如果每一个配偶对于其伴侣的兴趣都高于对自己的兴趣,那么他们之间便会有真正的平等。如果他们都很诚心地奉献出自己,他们便不会觉得自己低声下气或受人压制。只有男女双方都有这种态度,平等才有出现的可能。他们两人都应该努力使对方的生活安适和富裕,这样,他们才会有安全感。他们会觉得自己有价值,他们觉得自己被需要。
P240
最坏的情况是个人只顾及自己利益的时候。如果他受过这种训练,他会终日盘算着:我能从生活中得到什么样的快乐或兴奋?他会一直要求自由和解脱,从不考虑要怎样才能使其伴侣的生活更轻松,更富裕。这是一种不幸的做法。我把它比拟为缘木求鱼。它不是罪恶,而是一种错误的方法。因此,在准备我们对爱情的态度之时,我们不能只图安逸或只想逃避责任。爱情中如果含有犹豫和怀疑,爱情便不会坚固。合作需要有永恒不变的决心;当这种结合中包含有固定不变的决心时,我们才认为它是真正爱情和幸福婚姻的例子。这种决心不仅包括有生儿育女的决心,并且要教育他们,训练他们学会合作,尽我们的力量使他们成为良好的公民,成为人类种族中平等负责的一分子。美好的婚姻是我们养育人类未来一代的最好方法,所有人都应该记住这一点。婚姻其实是一项工作,它有它自己的规则和律法,我们不能只选用其中一部分,规避其他部分,而又不损及地球上的永恒定律——合作。
这本书参考了大量史料,帮我们从多个角度,还原“乾隆盛世”的真相,读时酣畅淋漓,读完回味无穷,值得推荐。
爱新觉罗·弘历(1711年9月25日—1799年2月7日),清朝第六位皇帝,年号“乾隆”,寓意“天道昌隆”,享年89岁,是我国古代最长寿的皇帝,庙号高宗。
乾隆皇帝一生的运势极佳。在康熙和雍正七十三年的治理下,大清天下国泰民安,一派生平之象。乾隆属兔,25岁继位,可以说乾隆是在最佳年龄、最佳时机登上了帝位。他的智商、情商都是寻常帝王难以企及的。他熟读史书,对造成朝局不稳的主要因素,比如朋党、权臣、外戚、宦官等,都了然于胸,立志在自己统治时期,革除这些弊端,超过历代帝王成为最伟大的君主。
乾隆非常勤政,每天早早上朝,六十年如一日。初登帝位,乾隆便一改雍正严苛的治国策略,他化严为宽,一时间,所有人都认为他是一位仁慈善良,甚至有点柔弱的贤君。然而,在乾隆十三年,富察皇后去世后,他像变了个人似的,重回到雍正的老路,甚至比他老爹更甚。他对官员严酷苛刻,虽然对平民百姓十分慈祥,但却大兴文字狱镇压底层百姓。晚年,他精力不济,又回到宽松的治理之路,在禅让大典后,自称“千古完人”,却带着未能平定白莲教起义的遗憾,离开了人世。
乾隆皇帝是中国历史上最伟大的皇帝之一,他统治下的中国,纵向比,是中国几千年历史中人口最多(近三亿,是登基时的2倍)、国力最盛的时期。横向比,是当时世界上最强大、最富庶的国家。然而这个盛世却是饥饿的盛世、恐怖的盛世、僵化的盛世,是基于少数统治者利益最大化而设计出来的盛世。从物质层面来看,虽然GDP占全球三分之一,但人均GDP却少的可怜,民众吃糠咽菜的记载比比皆是。从精神层面看,乾隆时代的中国人,只需有胃肠,不许有头脑,是中国历史上民众权利被剥夺得最干净、意志被压制得最靡弱的时代。
虽然登峰造极,但乾隆的统治并没有任何新意。乾隆盛世不过是文景之治、贞观之治和开元盛世的大总结和大重复。不幸的是,这个盛世出现在不应该出现的时候。乾隆所处的18世纪,是人类历史伟大的转折点。在这以前,人类进步的脚步一直是迟缓的。而从这个世纪起,历史开始跑步前进。英国经过产业革命,科技、生产力得到极大地提升,工农业产值几百倍、成千倍的增加,物质财富滚滚而来。法国资产阶级大革命、美国独立、《论法的精神》发表等事件表明,世界正朝着更文明的方向发展。而乾隆盛世却朝着反方向发展,他沉浸在“盛世”的梦境中不能自拔,想尽一切办法维护他的封建统治,没有赶上世界发展的大潮。后来,这片土地沦为半殖民地半封建的悲惨社会,其实在乾隆时代就已埋下了祸根。而他自己,也在百年之后遭遇坟墓被炸、尸骨无存的惨剧,给后人留下“十全天子骨难全”的慨叹。
P55
皇帝关心的是天下长治久安,一家一姓的统治永远不变;官员们的考虑却没有这么长远。归根结底,天下是皇帝的天下,官员们只是挣份工资。他们更关心的是如何利用政策空子,占皇帝的便宜,为自己和亲人朋友捞取最大好处。官僚集团运转的规律是:在没有利益驱动时,官员们执行皇帝的政策,总是倾向于被动应付,只求形式上能交代,由此导致敷衍塞责、形式主义,甚至弄虚作假。而当他们发现政策的空子时,通常会把个人利益伪装于国家利益之中,刻意把经念歪。基于利益最大化的原理,官员们热衷于编织关系网,相互通风报信,十分默契地协调行动。在他们的集体努力下,国家政治很快会陷入腐败的泥淖,每一位官员都会成为中饱私囊的“硕鼠”,本来属于皇帝或者说国家的“民脂民膏”被大量消耗,国家的治理成本大幅上升,最终出现“官逼民反”这个命定的结局。
P95
从这一年开始,乾隆回到了雍正的老路上。乾隆朝的君臣关系,从此变成了刁钻刻薄的主子与屏息而侍的奴才间的关系,或者说严厉的班主任与小学生的关系。下面的小学生稍有小动作,额头上就会遭到老师的粉笔头。诛杀和折磨大臣,越来越成为乾隆发泄自己不良情绪的主要渠道。
P137
清代皇帝一直以明朝为他们的前车之鉴,而明王朝给他们的最大教训是“水可载舟,亦可覆舟”。谁都知道,清朝得以入关,是捡了个大便宜,明王朝实际上是被饥饿的农民颠覆的。而颠覆的直接原因,就是对农民剥削过重。万历年间加派三饷,每年从农民身上多搜刮一千多万两白银,剜肉补疮,动摇了大明帝国的根基。所以,清代皇帝经常讲,明不是亡于崇祯,而是亡于万历。熟读历史的乾隆知道,饥饿的农民是国家最危险的敌人,而温饱了的农民则是皇权最坚定的支持者。为了江山万代,乾隆必须减轻对农民的剥削,使绝大多数老百姓有饭吃。这是国家政治的重中之重。统治者的自我克制,在乾隆身上表现得比较明显。乾隆一朝鼓励农民开垦荒地不遗余力,但是出发点却仅仅是为了百姓生计,而不是为国家增加税收。
P270
君权像恶性肿瘤一样,是世界上最具扩张性的事物之一,它不允许任何独立的事物存在。专制权力的独占性本质驱使它永远努力冲破一切限制,挣脱所有束缚,深入社会每一个角落,毒化每一个细胞,直至最后整个社会在它的紧紧拥抱中窒息而死。士人的人格追求,在专制达到极峰的清代就成了君权的障碍。
P295
专制政治中,皇帝是整个国家的神经中枢,官僚体系的精神状态就是皇帝一个人精神状态的放大。不但是人亡政息,同一个统治者的心境变化,也可以使国家面貌发生根本变化。
P341
盛世是中华民族的一个梦。生逢盛世,是每一个中国人对时代的最大期望。所谓盛世,就是内无严重的政治腐败,外无迫在眉睫的敌国外患,社会治安良好,老百姓普遍能吃饱饭的时代。在中国古代历史上,这样大规模的盛世出现过三次,即汉文景之治、唐代的贞观开元盛世及清康雍乾盛世。除了这三大盛世,还有过几个小规模的盛世或治世,比如东汉的“光武中兴”、隋代的“开皇之治”、明代的“仁宣之治”。甚至在大分裂的背景下,一些角落里的小王朝也取得过不错的治理成就。比如十六国时期南侵之前的前秦苻坚,南北朝的刘宋文帝时代,以及五代十国的后周南唐统治下的某个时段。
P342
有人统计过,数千年中国古代历史,盛世和治世累计加在一起,不过四百年左右,剩下的都是充斥着灾荒、动乱和腐败的平世和衰世。
P346
事实上,一代帝王的精明强干还不够。盛世的出现,都是几代人的接力努力达到的结果。中国盛世出现的规律是,一个英明强悍的开国帝王为新王朝立定规模,打下基础。开国帝王去世后,往往会出现一个小小的磨合动荡调整期,再由另一个精明强干的子孙打开王朝发展的瓶颈期,将王朝推上盛世。汉代刘邦开国,确立了清静无为的治国思路,但也留下了诸侯分裂的政治隐患。刘邦去世后,出现了吕后、惠帝时期的动荡。直到文帝、景帝,一方面将“与民休息”的治国方略发扬光大,另一方面又成功地打击了同姓王侯的分裂势力,消除了政治体制上的重大隐患,从而催生出武帝时代的极盛。唐代的盛世,经高祖、太宗开基立业,奠定基础,再有高宗、武后、中宗、睿宗的短期动荡调整,直到玄宗时才达到高峰。清代的盛世,也是由多尔衮和顺治打下基础。而康熙继位,解决了权臣和三藩这两个发展的瓶颈问题,由此大清才走上盛世之路。出现一个英明的帝王,在中国历史上本来就是小概率事件,而连续几代帝王都能雄才大略,那就更是如同彩票中奖一样难得,因此中国历史上盛世如此之少也就不难解释了。
P346
盛世难以出现,更难以保持。盛世的前奏是衰世,结局也是衰世。中国历史上的三大盛世,都未能避免“盛极而衰”的结局。
P347
从盛到衰,如此迅速,其原因当然是这些盛世的出现依赖的是人治。中国历史上的几大盛世,只在史书上留下了统治者手腕的精明,人格的强大,却没有留下太多制度性的成就。中国帝王都是人治的信奉者……中国古代的几千年间,专制制度的框架和运转规则没有根本的突破和进步。统治绩效如何,更多地依赖于统治者个人的精神振作与否。没有内外条件的严厉制约,个人的英明与自制无法抵制环境的纵容与腐蚀。由胜而骄,由劳而逸,是人性不变的规律。纵观中国历史,盛世君主往往是英明与昏聩集于一身,理智与膨胀合为一体。他们既是辉煌成绩的创造者,也是王朝衰落的罪魁祸首。
P363
乾隆皇帝治理天下的秘诀就是收紧缰绳,强化控制。在他眼里,任何民间的自发性和主动性都是危险的。整个社会的每一个分子,都要归拢到政权的罗网之内。大清王朝的千秋万代,固若金汤,是他考虑一切问题的根本出发点。虽然重新启用宁波等港口,会给浙江经济带来推动,但是却给帝国的管理增加了不必要的麻烦。
“草”与“禾”分别指代什么?草原文明和华夏文明如何从“双峰对峙”,走向“胡汉难分”,再到“天下一家”?两种文明的冲突、融合,到底有哪些影响因素?作者波音在《草与禾》中,带我们从4000年前的史前文化时代开始,一路走过商周秦汉、三国两晋南北朝、唐宋元明清,也一路走过匈奴、鲜卑、柔然、突厥、回鹘、契丹、女真、蒙古,以多种视角,来观察华夏与草原的演进历史,展现各文明的融合过程,并试着为文明的冲突与融合给出合理的解释。
本书所讲的“草的世界”,主要是指长城以外的区域,以草原为主。“禾的世界”主要是指长城以内的区域,以农耕平原为主。地理环境的不同造就了不同的文明,草与禾,分别指代草原文明和华夏文明。在两大文明融合过程中,出现了几种政权模式:
刚开始,草原文明和华夏文明不热衷于侵占对方的土地,更倾向于划江而治,希望对方能够长治久安。随着文明融合的日益深入,某些政权阴差阳错的拥有了跨文明的疆域,从而变成了混合政权。
P306
统一天下的重任最终由草原背景的族群而非华夏背景的族群来完成,这是因为统一首先要以疆土的统一为基础,草原强大的军事力量是华夏王朝所不具备的、难以抵挡的。当然疆土的统一只是浅层次的统一,甚至在统一之前,经由漫长的混合政权模式的历练,草原背景的族群就已经对不同区域文明的政权组织、生产方式、文化传统有了充分的认知和融合尝试,这是元朝能够实现统一政权的历史背景。
P307
这个统一政权模式之前,中华文明的融合有着强烈的递进关系,从草原、华夏各自群星闪耀的远古文化,到整合为单一政权,再演进到混合政权,最后形成统一政权,即使偶有反复,但大趋势几乎可以认为是必然的结果。
安装Java相对比较简单,网上教程比较多,本文不再赘述。本文采用的JDK版本是1.8.181。
HBase依赖Hadoop,由于是独立部署模式,因此不需要完整的Hadoop,从此处下载适配windows的hadoop2.7.2软件包,解压到合适目录即可。
从HBase官网下载合适的版本,本文采用的版本是hbase-1.3.6。解压到合适的目录后,打开hbase-1.3.6/conf/hbase-site.xml,添加如下配置(注意,根据实际情况修改文件路径,路径不需要提前创建,程序会自动创建)
1 | <configuration> |
依次添加HADOOP_HOME
,HBASE_HOME
,JAVA_HOME
环境变量,效果如下:
然后将%HADOOP_HOME%\bin
,%HBASE_HOME%\bin
,%JAVA_HOME%\bin
添加到PATH
环境变量中,效果如下:
进入hbase-1.3.6/bin目录,双击start-hbase.cmd
,如果控制台无报错信息,打开浏览器,输入地址localhost:60010,看到如下界面,说明HBase启动正常。
在任意路径下,启动cmd或者PowerShell,依次输入命令:
1 | 启动hbase客户端 |
出现如下回显,说明HBase工作正常。
HBase在运行过程中,会产生数据文件、zookeeper文件、日志文件等,如果需要恢复环境,只要将hbase-1.3.6/runtime目录(具体目录依配置而定)删除,重新启动HBase即可,非常方便。
]]>Java提供了多种同步机制,比如AtomicLong、LongAdder、ReentrantLock等,但是他们的性能到底如何?网上也有一些性能测试文章,但是要么同步机制不全,要么场景不全,因此笔者设计了一个性能测试框架,支持多场景、多种同步机制的性能测试,代码请参见locksbenchmark,后续有时间了再通过JMH进行对比测试。
既然是同步测试,当然要使用多线程才行,而且最好覆盖多种场景,总结起来本次测试有以下几个关键点:
CyclicBarrier
保证,所有线程开始工作那一刻才启动计时。通过CountDownLatch
保证,只要有一个线程达成目标,就结束计时,保证计时尽量准确。Counter
类即可,具体实现可以参照类Raw。代码托管在github,使用maven工具构建,具体命令如下:
1 | git clone git@github.com:chenpy228/locksbenchmark.git |
测试环境是Ubuntu 14.04.5 LTS,内核版本是4.4.0-101-generic,CPU是2核,JVM信息如下:
1 | java -version |
最终的测试结果如下,为了方便对比,Raw为没有使用任何同步机制的测试结果:
由于部分同步机制的运行时间相差太大,所以对坐标轴进行了对数化(log10)处理,绘制图表如下(越短越好):
去掉公平锁和读写锁后绘图如下(越短越好):
ReentrantLock(true)
,即上图中的FairReentrantLock,在所有场景下的表现都比较差,所以在实际应用中很少看到它的身影。如果必须要用,一定要经过谨慎测试。ReentrantReadWriteLock
,即上图中的RWLock,在读多写少的场景下表现的比较差,这跟我们的直觉可能不符,所以在java8中又引入了升级版的读写锁StampedLock。当然在写多读少的情况下,表现比较好,基本跟StampedLock
持平。AtomicLong
、LongAdder
和非公平锁ReentrantLock(false)
的表现相差不大,而且AtomicLong
略有优势。按照文档的说法,只有竞争非常激烈的时候,LongAdder
才更有优势,读写比20:20估计还不是竞争激烈的时候,针对这两个类补充测试了读写比为200:200场景,结果显示LongAdder
更胜一筹。目前来看,用AtomicLong
可以满足需求,而且个人认为AtomicLong
的接口更丰富。StampedLock
,在读多写少的场景下,它的乐观锁(即上图中的OptimisticStampedLock)确实更胜一筹,其他场景下悲观锁略好一些。synchronized
,整体跟StampedLock
表现差不多。AtomicLong
和LongAdder
属于第一梯队,synchronized
、StampedLock
和非公平锁ReentrantLock(false)
属于第二梯队,ReentrantReadWriteLock
和公平锁ReentrantLock(true)
属于第三梯队。如果被保护的是基本数据类型,在大多数场景下,建议使用Atomic*
系列锁,如果竞争非常激烈可以使用LongAdder
。如果被保护的是复杂的数据结构,在读多写少的场景下,可以用StampedLock
的乐观锁,在读少写多的场景下,可以用StampedLock
的悲观锁,其他场景直接用ReentrantLock
的非公平锁即可。
哈哈,有点儿标题党。昨天“极客时间”APP给我推送了一份专属的学习报告,看到一个数据很有意思:我全年在这个APP上只学习了39天,但却超过了80%的人。再次证明,以现在大家的努力程度,还真没有到拼智商的时候。2020已经到来,希望自己每天能够坚持学习,不求超越别人,但求每天能看到不一样的自己。
我的学习报告详情如下,很惭愧,订阅了4个专栏,基本都只学习了一半,今年要先把这4个专栏学完,再订阅其他的。
左耳朵耗子(陈皓)在2019-12-13发了一条微博,值得深思。
跟极客时间的运营看了一下后台数据,发现我的专栏第50篇后,就剩下30%的人还在持续学习,能坚持到最后人还不到千分之一。
我也发现,一般专栏刚开始几篇文章的阅读量、评论数都非常多,越往后越少,能坚持到最后的,寥寥无几。所以,人的惰性很难战胜,如果能保持自律,始终坚持做一件事的人,我想过的一定不会太差。共勉!
昨天,微软为基于Chromium内核的Edge浏览器发布了新的logo,新logo很漂亮,变化也很大,可能表明了微软要重新收复失地的决心吧。本文主要介绍一点儿微软浏览器的变迁史,由于个人认知有限,只能称为简史。
IE可能是微软家族在市面上使用最多、吐槽最厉害的老牌浏览器。很多老的系统,尤其是办公系统,只能使用IE。程序员朋友一提起IE,简直就是噩梦。随着win10的推广,IE后面会逐渐收缩,最终会被Edge替代。下面是IE的logo,虽说这些年每个版本都有变化,但是整体样式没有改变过。嗯,熟悉的味道。
自从2015年Windows10系统推出后,系统自带的就是Edge浏览器。Edge是IE的升级版,从使用体验上,更接近“现代”浏览器。logo变化不大,整体上还是字母e,就是去掉了外面的环。个人感觉,这个logo最丑,去掉“环”后,感觉还不如IE,没准是看IE时间长的原因吧。微软想用这款浏览器替代IE,但目前感觉收效甚微。
新logo外形仍然是字母e,但与IE、旧版的Edge差异较大。新logo变得更加圆润且富有现代感,它的形态看上去像是波浪,更有“网上冲浪”的感觉。该logo与以往的相差很大,笔者猜想,微软想让用户彻底忘记过去,重新收复浏览器失地。
目前还尚不清楚,微软何时推出新款的Edge浏览器,但是鉴于全新logo已推出,估计时间不会太远,咱们拭目以待,笔者也会第一时间测评,希望这次不会让人失望。
自从纳德拉接管微软以后,这只巨兽一改以往老态龙钟的形象。微软家族的产品也越来越受欢迎,比如vs code,笔者此时正在用它撰写该博客的markdown文稿。有意思的是,vs code的logo最近也发生了变化,logo更具设计感,也符合微软最新的设计风格。
似乎远离我们的微软又回来了。
最近这几天,沉寂已久的区块链突然火了起来,各种文章铺天盖地,起因是,10月24号习大大把区块链技术提升到国家高度,希望借此技术能够实现弯道超车。说起区块链,不得不提比特币,前几年比特币大火,也带火了区块链技术,笔者还曾长时间跟进一个区块链创新项目storj。当时也简单了解过背后的原理,其实,对于现在的码农来说,区块链技术并不神秘,我们每天在用的git就跟它比较相似。本文就来简单对比下这两种技术的异同。
既然本地保存了完整的数据,当然可以离线访问。
无论是区块链还是git,每个块的唯一标示都是根据块内容算出来的,并且保存了上一个块的信息,如果修改,标示信息会不一致(当然这里可能会有hash碰撞,但是概率极低),所以是无法修改的。
git和区块链在很多方面都很像,不知道谁借鉴的谁,不过从时间上看,git发起于2005年,区块链(比特币)发起于2008年,可能区块链借鉴了git的一些思想。但也不好说,可能世界就是这样奇妙,就像微积分的出现,当年莱布尼兹和牛顿几乎同时发明了这一伟大的工具,可能这就是英雄所见略同。
鉴于笔者对区块链了解不深,如有纰漏,还望批评指正。
近朱者赤,近墨者黑,看一个人经常跟什么人来往,就可以大致推算出这个人的水平。在机器学习领域,有一个采用类似思想实现的算法,那便是KNN(K-Nearest Neighbor),即K近邻算法,其中K是关键参数。该算法比较简单,本文简单介绍如何从零开始实现这个算法,以便加深对算法的理解。
KNN算法的主要实现步骤如下:
1 | import numpy as np |
执行上面代码,输出如下,可以看出,精度是一致的。当然,我的算法没有考虑各种异常,以及大数量下的性能优化,切不可应用在生产环境下。
1 | The accuracy of my knn is 0.9473684210526315. |
曾经一度以为,微软会像摩托罗拉、柯达一样,日薄西山,没想到在第三任CEO纳德拉的带领下竟然获得重生,他做了什么,促使这头大象翩翩起舞?带着这个问题,最近几天阅读了他的第一部著作《刷新》(英文名《Hit Refresh》)。
《刷新》主要分两个部分,第一部分主要讲述微软变革始末,第二部分讲述科技公司面临的挑战。个人觉得第一部分更精彩,让我们看到一家巨头公司是如何转型的。第二部分更多的是开放思考。
曾经的微软是多么的封闭,多么的不可一世,可近几年我们看到,微软Office软件可以在iPhone、Mac上运行、Windows系统集成Linux内核、计算器程序开源、VScode开源、收购最大的开源仓库GitHub、甚至在发布会上掏出iPhone等等,这些动作表明,微软正以积极开放的心态拥抱世界,这在以前是不可想象的。是什么促成了这种转变?
纳德拉在接任CEO时,微软已然患上了大公司病,正如他在书中所写:
他们怀着伟大梦想来到微软,但感觉真正面对的却是处理与高级管理层的关系,执行繁杂冗余的程序,以及会议中无休止的争吵。
这让我想起了网上曾经一度流传比较久的各大公司的组织结构图,拿着枪指着对方的正是微软,
他意识到,是文化出了问题,需要从内到外推动文化变革,才有可能重生,
领导意味着做选择,然后将团队团结在这些选择周围。我的父亲是一名印度高级政府官员,我从他那里学到的一点是,这个世界上没有比打造一个永续的组织更加艰难的任务。对领导者而言,通过命令达成的共识并不是真正的共识。任何机构建设都源于清晰的、既能自上而下也能自下而上推动进步的愿景和文化。
没有任何一名领导者、任何一个团队或任何一名首席执行官能够成为微软复兴的英雄。微软要实现复兴,靠的是我们所有人以及我们所有人的努力。文化转型是缓慢而艰难的,但也是值得的。
而管理者又是变革过程中的关键一环,
一个无可辩驳的事实是,在任何一家大型组织,任何艰难的转型都必须从内部突破。
关键在于,高层管理者不能带给员工恐惧和恐慌,而是帮助员工解决现有问题,并从中吸取教训。
我们需要的是一个能够接纳彼此问题、促进对话和高效率的高级管理团队;我们需要每一个人都将高级管理团队视为他们的最重要的团队,而不仅仅是当做他们参加的另一场会议;我们还需要在使命、战略和文化上保持一致。
我觉得领导者首先要做的事情就是:激发所带团队中成员的信心。
如何推进文化变革?纳德拉认为是重塑同理心和建立成长型思维。
大部分公司都把“以客户为中心”当做自己的核心价值观,可是真正做到的公司究竟有多少?如何才能以客户为中心,我想至少应该站在客户立场上思考问题,其实这就是同理心。纳德拉的儿子身患疾病,这一度让他很难过,不过正像他说的,这对他建立同理心帮助巨大,
我认识到,只有经历过人生起伏,才能培养其同理心;要想不受苦难,或者少受苦难,就必须接纳无常。…。如果你能够深刻地体会无常,那么你会获得更多的宁静,你不会因为人生中的起起落落而反应过于激烈。而只有到那时,你才能对周围的事物产生深远的同理心和慈悲心。
纳德拉引用了卡罗尔·德维克的畅销书《终身成长:重新定义成功的思维模式》中的两种思维模式:成长型思维和固定型思维。他指出建立成长型思维的重要性,
每一个人、每一个组织乃至每一个社会,在到达某一个点时,都应点击刷新——重新注入活力、重新激发生命力、重新组织并重新思考自己存在的意义。
我讲的并不是净利润的增长,而是我们个人的成长。如果我们每个人都能在工作和生活中成长,那么我们作为一家公司也会成长。
微软的变革并不依赖于我个人,甚至也不依赖于和我最密切共事的那几位高层领导者。它依赖于公司中的每一个人,包括我们广大的中层经理,他们必须致力于让每一个人每一天都能取得进步。
曾经的天朝上国,固步自封,国人自认为知晓一切,错过了大航海、工业革命。假使郑和下西洋,不是为了炫耀国威,而是探索地球的奥秘,中国现在不至于处于发展中的状态。
时刻保持同理心,站在客户视角思考问题,同时不断“刷新”自己的认知,这样的公司想不成功都难。
数字世界会面临一些列挑战,其中信任是最为核心的,
言论自由、隐私、安全和主权是永恒的、不容质疑的价值观。
信任就像手里握着一只小鸟。握的太紧,会伤到小鸟;握的太松,小鸟就飞走了。
区分现代人类和穴居人的是信任
这个担心不无道理,作为IT人,我就有这方面的顾虑。在采用某项云服务时,比如说为知笔记
,我首先考虑的不是价格,而是我的信息是如何存储的,是否有人能查看我的数据,比如心存恶意的管理员是否能不经过授权就随意窃取数据等等。随着斯诺登事件的发酵,给云厂商建立信任带来极高的成本,但这件事也是刻不容缓的,因为时至今日,部分国内厂商宁可自建机房,也不愿意将服务、数据放到云上,尽管云会带来更多的好处。
纳德拉在各国政府访问期间,经常被问到如何利用最新的科技浪潮来增加就业机会和经济机会?
,他的答案是,
教育加创新,广泛应用于整个经济,尤其是那些具备比较优势的国家或地区,再乘以科技使用强度,久而久之,就会产生经济增长和生产力。
同时也有人会问,人工智能会导致更多的下岗,他的思考是,
我相信,解决经济冲击的唯一办法,就是确保我们不仅要为走出大学和其他高等教育项目的人提供技能培训,还要为那些正在因为自动化失去工作的人提供培训。
其实,只有拒绝学习的人才有这个担心,比如前段时间收费站被裁撤后,被迫下岗的37岁大姐。人工智能替代了部分岗位,会迫使人类从事其他更有价值的工作。比如,火车替代了马车,虽然马车夫下岗了,但围绕火车会创造更多的岗位,只要肯终身学习,定会找到符合自身价值的岗位,政府需要做的就是及时引导、培训。
如果多个etcd集群的键值不重复,能否将数据合并?能否像数据库一样,将数据从旧库导出,然后在新库插入就万事大吉呢?答案是不能,etcd并没有提供类似功能,倒是有个备份功能,但是多个集群的备份数据却无法直接合并到一起。难道只能写个循环,将老集群的数据遍历出来,然后再插入新集群吗?这样也太土了吧,于是开始在网上找各种资料,可总是无功而返,看来只能老老实实看etcd官方资料了。功夫不负有心人,终于找到一条类似命令make-mirror,这条命令可以实时将一个集群的数据备份到其他集群,感觉跟我上面的想法一致,那么它可以用来做数据合并吗?请看接下来的实验吧!
命令语法如下,详情见命令手册。
1 | ETCDCTL_API=3 etcdctl make-mirror [options] <destination> [flags] |
其中[options]
主要是配置源集群和目的集群证书信息,以及源集群的客户端地址等。<destination>
是目的集群的客户端地址。该命令是单向的,目的集群的变化不会影响源集群。
在windows本地搭建3套etcd集群,名字分别是cluster1、cluster2、cluster3,这里假设将cluster1和cluster2的数据合并到cluster3,为了实验方便,只开放http访问。
启动集群1,并写入测试键/cluster1。为了避免混淆,在官方推荐的2379/2380端口前面加上数字代表不同的集群,例如对于集群1来说,客户端访问端口是12379,集群通信端口是12380。
1 | nohup etcd -name cluster1 \ |
启动集群2,并写入测试键/cluster2。
1 | nohup etcd -name cluster2 \ |
启动集群3,并写入测试键/cluster3。
1 | nohup etcd -name cluster3 \ |
将集群1的数据同步到集群3。
1 | ETCDCTL_API=3 nohup etcdctl make-mirror --endpoints=http://localhost:12379 http://localhost:32379 & |
将集群2的数据同步到集群3。
1 | ETCDCTL_API=3 nohup etcdctl make-mirror --endpoints=http://localhost:22379 http://localhost:32379 & |
查看集群3的数据,可以看到集群1、集群2的键值已经同步到集群3了。
1 | ETCDCTL_API=3 etcdctl --endpoints=http://localhost:32379 get --prefix / |
修改集群2的键值,然后查看集群3的键值信息,发现数据已实时同步。
1 | ETCDCTL_API=3 etcdctl --endpoints=http://localhost:22379 put /cluster2 "renew cluster2" # 修改集群2的值 |
在github上发现了一个repo,里面将常见机器学习python库的用法总结成了N张速查图,可以把这些图当做手册经常翻出来看看,加深记忆。PDF版可以从这里下载。
聚类是机器学习中一种重要的无监督算法,它试图将数据集中的样本划分为若干个通常不相交的子集,每个子集成为一个“簇”(cluster),理论上来说,每一簇对应一个潜在的概念,但这个概念事先并不知道,需要使用者来把握。本文是常见聚类算法的综述,为了加深理解,大部分算法配有动图。
这一最著名的聚类算法,主要基于数据点之间的均值和与聚类中心的聚类迭代而成。它主要的优点是十分的高效,由于只需要计算数据点与聚类中心的距离,其计算复杂度只有O(n)。
1.首先我们需要预先给定聚类的数目同时随机初始化聚类中心。我们可以粗略的观察数据并给出较为准确的聚类数目;
2.每一个数据点通过计算与聚类中心的距离了来分类到最邻近的一类中;
3.根据分类结果,利用分类后的数据点重新计算聚类中心;
4.重复步骤2、3直到聚类中心不再变化。(可以随机初始化不同的聚类中心以选取最好的结果)
这种方法在理解和实现上都十分简单,但缺点却也非常明显:十分依赖于初始给定的聚类数目;同时随机初始化可能会生成不同的聚类效果,所以它缺乏重复性和连续性。
和K均值类似的K中值算法,在计算过程中利用中值来计算聚类中心,使得局外点对它的影响大大减弱;但每一次循环计算中值矢量带来了计算速度的大大下降。
这是一种基于滑动窗口的均值算法,用于寻找数据点中密度最大的区域。其目标是找出每一个类的中心点,并通过计算滑窗内点的均值更新滑窗的中心点。最终消除临近重复值的影响并形成中心点,找到其对应的类别。
1.首先,以随机选取的点为圆心,r为半径做一个圆形的滑窗。其目标是找出数据点中密度最高点并作为中心;
2.在每个迭代后,滑动窗口的中心将向较高密度的方向移动;
3.连续移动,直到任何方向的移动都不能增加滑窗中点的数量,此时滑窗收敛;
4.将上述步骤在多个滑窗上进行以覆盖所有的点。当多个滑窗收敛重叠时,其经过的点将会通过其滑窗聚类为一个类。
下图中每一个黑点都代表一个滑窗的中心,他们最终重叠在每一类的中心;
与K均值相比最大的优点是,我们无需指定指定聚类数目,聚类中心处于最高密度处也是符合直觉认知的结果。但其最大的缺点在于滑窗大小r的选取,对于结果有着很大的影响。
DBSCAN同样是基于密度的聚类算法,但其原理却与均值漂移大不相同:
1.首先从没有被遍历的任一点开始,利用邻域距离epsilon来获取周围点;
2.如果邻域内点的数量满足阈值则此点成为核心点并以此开始新一类的聚类。(如果不是则标记为噪声);
3.其邻域内的所有点也属于同一类,将所有的邻域内点以epsilon为半径进行步骤2的计算;
4.重复步骤2、3直到遍历完所有核心点的邻域点;
5.此类聚类完成,同时又以任意未遍历点开始步骤1到4直到所有数据点都被处理;
6.最终每个数据点都有自己的归属类别或者属于噪声。
这种方法最大的优点在于无需定义类的数量,其次可以识别出局外点和噪声点,并且可以对任意形状的数据进行聚类。
但也存在不可回避的缺点,当数据密度变化剧烈时,不同类别的密度阈值点和领域半径会产生很大的变化。同时在高维空间中准确估计领域半径也是不小的挑战。
通过假设数据点符合均值和标准差描述的高斯混合模型来实现的。下图以二维情况下为例描述了如何利用最大期望优化算法来获取分布参数的过程:
1.首先确定聚类的数量,并随机初始化每一个聚类的高斯分布参数;
2.通过计算每一个点属于高斯分布的概率来进行聚类。与高斯中心越近的点越有可能属于这个类;
3.基于上一步数据点的概率权重,通过最大似然估计的方法计算出每一类数据点最有可能属于这一聚类的高斯参数;
4.基于新的高斯参数,重新估计每一点归属各类的概率,重复2,3步骤直到参数不再变化收敛为止。
在使用高斯混合模型时有两个关键的地方,首先高斯混合模型十分灵活,可以拟合任意形状的椭圆;其次这是一种基于概率的算法,每个点可以拥有属于多类的概率,支持混合属性。
层次聚类法主要有自顶向下和自底向上两种方式。其中自底向上的方式,最初将每个点看做是独立的类别,随后通过一步步的凝聚最后形成独立的一大类,并包含所有的数据点。这会形成一个树形结构,并在这一过程中形成聚类。
1.首先将每一个数据点看成一个类别,通过计算点与点之间的距离将距离近的点归为一个子类,作为下一次聚类的基础;
2.每一次迭代将两个元素聚类成一个,上述的子类中距离最近的两两又合并为新的子类。最相近的都被合并在一起;
3.重复步骤2直到所有的类别都合并为一个根节点。基于此我们可以选择聚类的数目,并根据树来进行选择。
层次聚类无需事先指定类的数目,并且对于距离的度量不敏感。这种方法最好的应用在于恢复出数据的层次化结构。但其计算复杂度较高达到了O(n^3).
sklearn官网(http://scikit-learn.org/stable/modules/clustering.html#clustering) 对常见的聚类算法做了汇总比较,结果一目了然,可以看出DBSCAN在训练时长和结果上均有优异表现,最终效果如下:
实现代码如下:
1 | import time |
最近在将自研算法集成到pyspark生态中,为了降低用户学习成本,计划将接口、最终生成模型都按照pyspark要求来实现,但是在互联网上并没有找到官方的开发指南,所以只能自己一步一步的琢磨,今天就先来看下pyspark最终保存的模型长什么样,后面再全面总结如何融入生态。
首先训练一个模型,本文以逻辑回归为例,代码如下
1 | data = [LabeledPoint(0.0, [0.0, 1.0]), LabeledPoint(1.0, [1.0, 0.0]),] |
生成的结果如下,可以看出模型包含2个文件夹,一个是data,一个是metadata,很明显这两个都是parquet格式的文件,data是DF格式的,metadata是文本格式的。
1 | $ tree lrm_model/ |
尝试用parquet格式读取data下的内容,很显然是DF结构的数据,3个字段,一条记录,主要是逻辑回归的参数。
1 | sqlContext.read.parquet('file:///lrm_model/data').show() |
1 | +--------------------+---------+---------+ |
再解析metadata下的数据,如果再用parquet去读就会报错,用text()方法可以看到是一段文字,但并没有显示完全。
1 | sqlContext.read.text('file:///lrm_model/metadata').show() |
1 | +--------------------+ |
由于是文本,所以直接用cat输出文件内容,可以看出是这个模型的元数据文件,包括类名、版本号及输入数据的特征。
1 | $ cat lrm_model/metadata/part-00000 |
在Python中,获取调用者信息对于调试、打印日志等非常有帮助,本文将介绍获取调用者信息的两种方法。
1 | import sys |
1 | import inspect |
1 | #!/usr/bin/env python |
vi/vim是各Linux发行版默认安装的文本编辑工具,熟练使用它对文本操作效率的提升有很大帮助。但掌握vim并非易事,尤其是数不胜数的快捷键有时会令人抓狂。还好有大牛将快捷键在键盘中的位置标记出来了,生成了一张“键盘图”(类似学习五笔打字时的字根图),我们可以将其打印出来贴在电脑旁边或者设置为桌面,忘记了就瞄一眼,时间长了定能孰能生巧。
该图来源于官网,该网站上还有vim的使用教程,内容非常详细,建议学习下。
中文版如下
通常情况下,我们访问Linux服务器时会使用Putty或者Xshell等SSH客户端工具,但这些工具均需要安装后才能使用,在安全要求不高(如局域网)或者只是开放服务器给其他人体验某种功能时,客户端这种方式略显繁琐。本文将介绍一款开源神器shellinabox,只需要浏览器就可以进行远程访问,相信用过它后,定会爱不释手。
shellinabox使用AJAX技术,通过浏览器提供了原生Shell的外观,并且部署和使用都非常简单。由于shellinabox比较简单,在安全上不如SSH协议,建议不要在安全要求高的场景下使用。
主流的发行版均提供shellinabox包,当然也可以自行编译、安装,具体步骤参考官网。
在Ubuntu上,你可以使用如下命令安装它:
1 | sudo apt-get install shellinabox |
安装后的可执行程序是shellinaboxd,其配置文件为/etc/default/shellinabox,可以按需更改,如修改默认端口号。或者也可以在启动时,通过参数传入配置。
在浏览器中输入https://your-ip:4200
,忽略证书错误,输入用户名、密码就可以使用了,是不是很简单!
在浏览器窗口中单击右键,会弹出一个菜单,前面有对号的表示生效的配置
其中,Copy
复制选中的文字Paste
粘贴通过Copy复制的文字Paste from browser
允许你从浏览器外部粘贴内容到终端Reset
清屏Unicode
字符集,根据情况选择Visual Bell
虚拟蜂鸣器,在输入异常时,屏幕闪烁Onscreen Keyboard
屏幕键盘Blinking Cursor
光标闪烁Secure
是否安全模式,即是否采用https,下次登录有效Black on White
白底黑字White on Black
黑底白字Color Terminal
彩色Monochrome
黑白About
一些版权信息
输入exit退出系统后,窗口并不会关闭,而是弹出一个“Connect”按钮,点击按钮再次登录。
shellinaboxd会启动一个web服务器,当请求到达时会调用login程序进行认证,认证通过后调用bash。多次登录,会启动多个login程序,通过pstree命令可以清晰的看到调用关系。
你是否曾为定位一个内存泄露的BUG而通宵达旦?你是否曾在优化性能时由于无从下手而抓狂?如果你正在为这些问题烦恼,那么请试试Valgrind,它会让你爱不释手!Valgrind是一款开源的,用于调试、分析、优化Linux下程序的利器,可以用来解决内存泄露、踩内存,多线程并发以及性能优化等问题。本文主要介绍Valgrind的功能、安装及使用。
Valgrind主要包含6个有用的子工具,包括Memcheck、Cachegrind、Callgrind、Massif、Helgrind和DRD。下面分别介绍各工具的作用。
Memcheck是最常用的,也是Valgrind默认启动的工具,可以检测内存管理方面的问题,包括:
Cache分析器,它模拟CPU的一级缓存I1,Dl和二级缓存,能够精确地指出程序中Cache的丢失和命中。如果需要,它还能够为我们提供Cache丢失次数,内存引用次数,以及每行代码,每个函数,每个模块,整个程序产生的指令数。这对优化程序有很大的帮助。
Callgrind对Cachegrind进行了扩展,不仅可以用于分析Cache的命中率,还能给出每个函数的调用关系,包括执行时间,以及调用次数。在运行结束时,它会把这些分析数据写入一个文件,使用callgrind_annotate命令可以把文件的内容转化成可读的形式,对于分析性能瓶颈非常有帮助。
堆分析器,它能测量程序在堆中分配了多少内存。Massif能帮助我们减少内存的使用。
Helgrind主要用于检查多线程中出现的竞争问题。它会寻找被多个线程访问,而又没有加锁的内存区域(临界区),这些区域往往是线程之间失去同步的地方,而且会导致难以发掘的错误。注意,该工具只能检测使用pthread实现的线程。
与Helgrind类似,也用于检查多线程中出现的竞争问题,但相较于Helgrind使用更少的内存。注意,该工具只能检测使用pthread实现的线程。
访问Valgrind官网下载最新的源码包,目前版本为3.10.1,然后使用“三板斧”进行安装。
1 | $ tar -jxvf valgrind-3.10.1.tar.bz2 |
valgrind命令的格式如下:
1 | $ valgrind [--tool=tool_name] [valgrind-options] your-program [your-program-options] |
其中,tool_name
指的是子工具的名称,如分析性能,则--tool=callgrind
。如果不指定该项,则默认启动Memcheck工具valgrind-options
取值非常广泛,可以参考man手册your-program
指的是被测程序your-program-options
指的是被测程序的参数
以分析性能为例,常见的命令如下:
1 | $ gcc -g -o test test.c |
注意:
在用C/C++实现字符串处理逻辑时,strtok函数的使用非常广泛,其主要作用是按照给定的字符集分隔字符串,并返回各子字符串。由于该函数的使用有诸多限制,如果使用不当就会造成很多“坑”,因此本文首先介绍那些经常误踩的坑,然后通过分析源代码,解读该函数的诸多隐含特性,以便对该函数有个全面的理解,不再被坑。
目前大部分程序都是在多线程环境下运行的,因此函数的可重入性就显得尤为重要。下面示例的本意是,先按照;分隔句子并输出,然后再按照空格分隔单词并输出,可结果呢?
1 |
|
预期结果如下:
1 | $ gcc test_strtok.c |
可实际结果如下:
1 | $ gcc test_strtok.c |
实际告诉我们:strtok不可重入。
如果一个字符串在我们的监控之外被修改了,那么可能会发生一系列诡异的事,而我们却全然不知。请看如下案例:
1 |
|
预期结果如下:
1 | $ gcc test_strtok.c |
可实际结果如下:
1 | $ gcc test_strtok.c |
实际告诉我们:你传入的字符串会被strtok修改。
如果两个分隔符连续出现,那么在分隔的时候,你是希望分隔出一个空字符串,还是希望strtok忽略掉多余的分隔符呢?请看strtok给我们的答案:
1 |
|
实际结果如下:
1 | $ gcc test_strtok.c |
实际告诉我们:连续出现的分隔符只被处理一次。
你希望将字符串首尾的分隔符忽略掉吗?如果不希望,那么请慎用strtok,请看:
1 |
|
实际结果如下:
1 | $ gcc test_strtok.c |
实际告诉我们:字符串首尾的分隔符会被忽略。
下面的代码取自glibc-2.20的strtok.c
文件,未做任何删改,中文注释为笔者添加,用于说明造成以上坑的原因。
1 |
|