技术人员转型技术管理拙见

前沿

搞技术已经10年了,按照自己的职业规划,以及开始慢慢转型技术管理。当然自己还有很长的路要走,很多方面要学习,总结一下自己的经历,自勉、他勉!

一、自我驱动
1、自我要求,对自己开发的东西以一个架构师、产品经理、老板的角度来要求自己。
2、扩展思维,主导横向、纵向扩展思维,以求更完善自己的工作
3、万事准备工作,在任何可预知即将或发生的事情之前做好准备工作,如果会议前的准备,项目开发前的知识储备。
4、主动推进工作,别等着产品经济给你讲产品才做,别等着领导催你了才赶,别等着
5、自我情绪管理,无论因为个人还是公司层次对自己情绪造成影响,学会控制自己的情绪,不要把自己的情绪传染给团队,学会道歉。
二、扩展知识面
1、扩展和了解你的合作团队的知识,作为理科出身的技术人员,你比其他人更有优势了解其他知识:产品、运营、市场、财务、等等,他们要了解技术难,而你了解他们的皮毛相对容易。如果你不懂产品,运营、市场的猫腻,你是我发评估出技术到底实现到什么程度才是他们的,更不说技术驱动!
2、多语言多技能,很多java出身的程序员跻身管理以后,如果新的语言架构不是java,那么他就更倾向于把诸如php、python等开发的系统修改为java的,美其名曰降低团队学习成本,在全栈工程师发展的今天,这是一种说辞,每种语言有合适的业务场景和适应的环境,自我开发的成本和质量不一定有别的语言开发的开源的好。如disucz和cms等!其实服务端开发的你得懂客户端,客户端开发的你得懂服务端,你都不了解怎么做好配合和团队协作。推动团队向全栈发展是趋势,包括你自己!

三、处理人际关系
1、和领导做同事,把自己的位置提升到老板和领导的位置,想想他们出发点和目标,帮助他们完成目标!
2、和同事做朋友,无论工作和悠时间,首先要和你的团队打成一片,了解他们的关注点、爱好。现在很多公司团建除开吃饭喝酒就是吃饭喝酒,那是老一套的拉关系的方式,让团队成员自己决定团建方式和目标!
四、管理方式
1、为上级和下级梳理流程,制定目标计划。和上级开会讨论的时候,作为技术team的leader,首先得梳理领导和同事提出的想法和计划是否可以可行,是否时间足够。然后梳理出优先级,特别是初创公司,更要如此,将有限的团队资源用于构建mvp的产品。其实针对接到的人任务和工作,进行分工细化,确保每个团队成员都了解自己的工作和时间计划,让团队有序推进工作!其次针对工作时间的问题,需要根据优先级和重视程度,酌情考虑团队如果正常运行和加班高速运转的完成时间,不要一尘不变的评估工作时间!
2、合理安排工作,安排工作首先要考虑团队成员的能力,避免一个人干重复性工作,交叉交换,让团队每个人都了解整个系统。避免因为一个人离职而造成人员空缺!
3、制定共同的目标,技术管理和别的管理不一样,把公司、项目的目标当作他们的目标,他们不一定有归属感,所以您需要根据团队成员的实际情况,针对每个员工制定符合他们的职业规划,有目的的让他们去学习和了解一些未知的事物,(当然你得知道他们的发展目标)。如果我面试邀请新同事入职总会说的一句话,我不能保证你在公司赚到多少钱,但是我能保证你在公司能学习到很多东西,为你下一家公司晋升做好铺垫。只要将这种学习文化建设起来了,团队的效率、积极性能提起来,大家也不会轻易离职,因为他们总会觉得能学到东西,而且整体技术水平也能得到极高的提升!
3、团队文化,上一小节在共同目标已经很直接的形成了团队*学习文化*,其次建立简单可以依赖的文化,这也是百度的文化,团队成员之间不要允许办公室文化存在,技术团队只有*技术文化*,技术战争。如果一旦有这种人毫不留情的予以开除团队,确保你的团队纯洁。
4、绩效考核,也许你的公司没有kpi考核,技术也是一棒子规则,无论有或者无,你都需要在自己心中有一个评分体系,来衡量团队成员的短期、长期的工作表现。
五、危机感
作为一个leader,你需要学习和了解技术最前瞻的东西,来引导产品方向,了解互联有什么最新、流行的技术、工具来改善你的团队!了解和学习产品、市场…等其他部门的业务和知识,更总要的你要更了解你自己,了解你的不足,不断针对性的学习和完善自己不足的地方!

架构规划

简单聊了下什么是架构,还将架构划分为三个阶段:规划阶段、设计阶段和构建阶段,构建阶段其实也是架构实现的阶段。其实,三个阶段的界限并不明显,而占比最多的是设计阶段;而且,规划和构建阶段其实也会有设计。也可能因此,当我们谈到架构的时候,更多是在谈架构设计。但仔细想想,三个阶段的划分确是合理的。本文先聊聊架构规划。

架构规划

架构规划做什么呢?我觉得主要是规划好下个阶段架构设计的边界。而影响架构边界的,其实就是需求。需求形成了对架构的约束条件,从而也对架构设计形成了边界。那么,有哪些需求呢?可以分为三大类:商业需求、功能需求和质量需求。

商业需求

商业需求是最高层次的需求,对其含义,我比较赞同温昱在《软件架构设计》中提到的解释:它关注从客户群、企业现状、未来发展、预算、立项、开发、运营、维护在内的整个软件生命周期涉及的商业因素,包括了商业层面的目标、期望和限制等。商业需求一般对架构的影响比较大,对架构产生限制的商业因素也比较多,在此列举一些比较常见的:

上市时间:上市时间限定了系统从设计、开发、测试到上市的时间边界。之前我跟进过一个垂直于大学生市场的应用,上市时间就要求在新生入学前,不然就会错过推广的最佳时期,预留给开发的时间只有两个月。因此,我们只好大部分重用前个项目的元素,包括重用服务端的一些模块,还包括客户端的架构和界面。当然,一般情况下,预留给开发的时间不会这么短,但也不会特别长。架构师需要根据时间长短,平衡各方面需求,做好架构选型。
成本预算:成本预算就限定了能使用的资源边界。不同架构的开发成本肯定不同,要满足更多功能需求和更多质量需求的架构成本也更高,在预算有限的情况下,只能权衡各种需求,优先满足重要程度高的需求。
人力现状:100人的开发团队和10人的开发团队,软件的架构会有很大不同。另外,开发团队人员所掌握的技术也会对架构选型有影响。例如,团队里还没有人会用React Native,那现阶段就不适合选择React Native作为App架构的技术基础。
与外围系统的集成:当需要与外围系统集成时,需要认真考虑集成方法,尤其是外围系统比较老的时候,集成难度可能更高。另外,外围系统的不可控因素一般也比较多,因此,对架构处理这些不可控风险的要求相对也高。
开放性:封闭的私有系统和开放式系统对架构的要求也不同,一个系统如果选择了开放,那对架构的质量要求更高,对安全性、扩展性、性能等质量属性都应该比封闭时高。
目标市场:目标用户10万、100万、1000万,不同级别的目标市场,架构也是大有不同。另外,大众市场和垂直的专门市场,架构也同样有区别,较大的专门市场一般都采用产品线的规划方案。
多端支持:现在移动端普遍支持Android、iOS、Wechat,管理端通常则支持PC Web,如果管理端也要支持Android、iOS、Wechat,或者移动端和管理端还要再支持WindowsPhone、黑莓,甚至再支持VR,则需要投入更多时间和人力,架构上相应也需要做出调整。
期望的系统生存期:从主观上说,谁都希望自己的系统可以生存很久,但生存期越长,意味着系统的可修改性、可扩展性、可移植性等需要更高。但是,受上市时间、成本预算等因素的制约,再加上软件本身的变化快,所以,客观上,一般也不会期望其生存期太长。当系统不能满足渐增的需求时,基本通过重构来解决。
阶段性计划:每一个大平台系统普遍都是分阶段完成的,因此,前期阶段的架构设计时就需要考虑好重用性、扩展性、伸缩性、移植性等特性。但因为每个阶段经过市场验证后,需求有可能会变化,所以又不能过度设计,否则就会造成设计浪费,还可能加大了后续阶段架构调整的难度。
国际化:如果走国际化路线,那架构上就要考虑好对多国语言的支持。
竞争对手:产品要比竞争对手优秀,那就要在一些关键的功能或质量上超越对方,也意味着在这些方面的架构需要投入更多。
法律法规:比如,对某些关键字要进行过滤屏蔽,这是天朝独有的,大家懂的。
商业需求多种多样,有些需求还可能会相互矛盾,比如,上市时间和成本预算就会和期望的系统生存期可能产生矛盾,期望的生存期越长其成本就会越高,需要投入的时间就会越多,那么,就有可能拖延上市时间。因此,做架构规划时,必须梳理清楚哪些需求是能够被满足的,能被满足的程度如何,需要在各个需求间权衡利弊。另外,商业需求因为是最高层次的需求,因此,相对于功能需求和质量需求,其优先级一般也比较高。

功能需求

功能需求描述了系统应该提供的服务,包括为用户提供的服务,也包括为其他系统提供的服务。而架构主要就是为功能服务的,而功能需求基本与具体的业务相关。因此,要做好功能需求这块的架构,就必须对该业务领域足够了解,这样才能更好地抽象建模。对功能需求的架构规划,主要就是建立业务领域模型。领域模型定下来后,下个阶段的设计必须与领域模型保持一致。

而对功能需求进行领域建模之前,还需先梳理下需求的优先级。因为受商业需求的影响,功能需求也需要权衡。比如,上市时间紧、成本预算低、人力资源也不是很充足的情况下,功能需求只能少不能多。而需要与外围系统集成的时候,也意味着这部分功能不需要自己实现了;但是,如果外围系统无法完全满足需求时,则还需要自己再实现缺失的需求。因此,现阶段需要满足哪些功能需求?需要满足到什么程度?这两个问题确定了之后才能更有效地进行领域建模。

领域建模主要就是要分析清楚每个领域模型和模型之间的关系。还是直接用一个例子来说明吧。假设现在要做一个支持O2O(Online To Offline)的电商平台,以下是经过梳理后的几个关键的功能需求:

商家可以在平台发布商品,可以是实体类商品,也可以是服务类商品。
实体类商品支持快递,服务类商品只能到商家门店兑换消费。
用户购买实体类商品时需提供收货信息。
用户购买每个商品时对应生成一个订单。
用户购买的是实体类商品时,可以查看商品的物流信息。
用户购买的是服务类商品时,可以用订单的兑换码到商家门店兑换消费。
根据以上需求,可以初步得到相关的领域概念有:商家、商品、实体类商品、服务类商品、物流信息、门店、用户、收货信息、订单、兑换信息。理清这些领域概念之间的关系之后,可以得到类似于下面的领域模型视图:

当然,这只是一个很小的例子,实际上的领域模型会比这个例子复杂得多。领域模型确定之后,系统中有多少业务领域、各领域概念之间的关系如何就一清二楚了。

质量需求

质量需求是三类需求中,需求层次最低的,但却是大部分架构师最关注的。纵览那么多架构技术,就会发现,大部分都是为了解决某个或某些质量属性优化的问题。

质量属性常见的有以下这些:

性能(Performance):性能无疑是一个非常重要的特性,尤其在计算资源有限的情况下。但也无需过分追求高性能,从而牺牲其他更重要的特性。关于过度关注性能的问题,这篇文章说得很好:架构之路(二):性能。
安全性(Security):安全性一般会和性能相互制约,最明显的例子就是HTTPS,使用HTTPS提高了安全性,但性能就会有所牺牲。很难做到既满足高安全又高性能,因此需要根据具体需求平衡两方面的特性。
可用性(Availability):也有人称为有效性,一般定义为:可用性 = 系统正常工作时间 / (系统正常工作时间 + 故障维修时间)。此定义就说明了可用性与系统故障有关,故障率高,可用性就低,故障率低,可用性才高。另外,高可用性还说明了系统对故障维修的时间也很短。
易用性(Usability):易用性很容易和可用性混淆,可用性关注的是系统长时间无故障运行的能力,而易用性关注的则是系统易于使用的能力。
鲁棒性(Robustness):也称为健壮性、容错性,是指系统在出现了用户非法操作、或软硬件的缺陷导致的异常情况下,系统依然能够正常运行的能力。比如说,系统在输入错误、磁盘故障、网络过载或有意攻击情况下,能否不死机、不崩溃,就是该软件的鲁棒性。
可伸缩性(Scalability):可伸缩性是指当用户量和数据量增加时,系统维持高服务质量的能力。比如,当并发量为1W时,系统响应时间为1秒,那如果并发量增加到100W时,只要通过增加服务器数量,而无需对代码进行修改即可达到系统响应时间依然为1秒,就说明该系统的可伸缩性高。
互操作性(Interoperability):互操作性反映了本系统与其他系统交换数据和服务的难易程度。
可扩展性(Extensibility):也称为灵活性,反映了系统应对变化的能力。在软件开发过程中,需求变更是常有的事,尤其在移动互联网时代,变化是非常频繁的,也因此,可扩展性是移动互联网产品重点考虑的质量需求。
可理解性(Understandability):可理解性是指开发人员通过源代码和相关文档,了解程序功能、结构和运行方式的难易程度。遵从好的开发规范一般都可以提高可理解性。另外,单一职责原则运用得好,也能大大提高可理解性,所谓“简单就是美”,简单才容易理解。
可测试性(Testability):简单点说,可测试性就是测试和诊断软件错误的难易程度。比如进行单元测试的难易程度。如果程序包含了复杂的处理逻辑、数据结构、模块关系,可测试性的设计更显得尤为重要。
可复用性(Reusability):可重用性表明了一个软件组件可以在其他程序中使用的难易程度。一般需要将一个组件抽离成通用性的组件时,对可复用性的要求就会比较高。
可移植性(Portability):可移植性表明了将软件系统从一个运行环境转移到另一个不同的运行环境的难易程度。
可维护性(Maintainability):可维护性是指理解、改正、改动、改进软件的难易程度。我觉得,可维护性是保证一个软件系统能够长期生存的最重要的特性,没有之一。对一个可维护性差的系统,久而久之,不断变得牵一发而动全身,变得不可维护,慢慢只能宣布灭亡。
理想情况下,谁都希望所有属性都是高质量的,但谁都清楚这是不可能的事。要提高更多质量属性,实现的难度更大,需要付出的成本更高。而且,不同质量属性之间还存在制约关系,比如,提高安全性,一般就会减低性能;提高了性能,还可能减低了可维护性。因此,在实际做架构规划时,必须根据具体需求在各质量属性间权衡优先级。

写在最后

现在有不少公司,尤其是创业型的公司,为了快,直接从需求跳到开发,没有架构规划,也没有架构设计。这样的系统,就等于一栋没有打地基的建筑物,其风险自不用说。架构就是软件系统的地基。有一句话说得好,“基础不牢,地动山摇”。

什么是架构

最近在思考架构方面一些最基本的问题,比如什么是架构?如何评价一个架构的好坏?是否有一些通用的基本原则指引架构设计?在面向对象设计方面,有单一职责、里氏替换、依赖倒置、接口隔离、迪米特、开闭原则等等基本原则;那么,在架构设计方面是否也有类似的基本原则呢?本文就先聊聊第一个问题。

什么是架构

关于什么是架构,业界从来没有一个统一的定义。Martin Fowler在《企业应用架构模式》中也没有对其给出定义,只是提到能够统一的内容有两点:

最高层次的系统分解;
系统中不易改变的决定。
《软件架构设计》一书则将架构定义总结为组成派和决策派:

组成派:架构=组件+交互:软件系统的架构将系统描述为计算组件及组件之间的交互。
决策派:架构=重要决策集:软件架构是在一些重要方面所作出的决策的集合。
而架构的概念最初来源于建筑,因此,我想从建筑的角度去思考这个问题。Wikipedia中,对架构,即Architecture的定义如下:

Architecture is both the process and the product of planning, designing, and constructing buildings and other physical structures.

简单翻译就是:架构是规划、设计和构建建筑物或其他物理构筑物的过程和结果。

从上面的定义中可知,首先,架构的最终目标是为了产出建筑物或其他物理构筑物,构筑物可以只是一套房子,也可以是一栋楼盘,抑或是一个小区、商业区,甚至是一个城市。构筑物越大,其架构必然也越复杂。

其次,产出建筑物之前需要经过三个阶段:规划(planning)、设计(designing)和构建(constructing)。这三个阶段其实也是架构的核心了。比如,开发商要建一个住宅小区,首先肯定要对该小区有一个整体的规划吧:小区的建设选址、建设的规模、建设的内容、投资估算、建设周期等等。接着,就要对小区的各方面进行设计了,最高层次的应该是小区的总体布局设计,拆分开的话就是各楼盘的设计、绿化的设计、各种配套设施的设计等等,再细化下去就是各种户型的设计、楼盘内和小区内各种走道的设计等等。最后,构建阶段也就是施工阶段了,是将之前所有的想法转为实际的建筑物的阶段。

最后,架构包含了以上的过程和结果。也就是说,对小区总体规划的过程是架构,规划的结果方案也是架构,小区总体布局的设计、楼盘的设计、户型的设计等等的每个过程也都是架构,每个过程产出的设计方案也是架构,构建阶段的施工图也是架构,可以说,产出建筑物期间的每个过程和结果都是架构。

那么,如果将建筑物换成了软件,那就变成对软件架构的定义了:软件架构是规划、设计和构建软件的过程和结果。

相应地,软件架构的最终目标就是为了产出软件,可以是一个App,也可以是一个平台,如SaaS、PaaS、BaaS等等,甚至还可以是智慧城市这样庞大的生态系统,地球人都知道,越庞大复杂的系统,架构越难。规划阶段更多考虑的是软件的需求,包括业务上的功能性需求和技术上的非功能性需求,如可靠性、可扩展性、可维护性等;此阶段的架构一般为系统架构。设计阶段的工作更多的就是拆分细化,以满足各种需求;此阶段的架构一般为逻辑架构。构建阶段主要就是对软件的实现和部署了;此阶段的架构一般为物理架构。

写在最后

其实,对架构的每种定义都没有错,就像《软件架构设计》一书也说过的,只是每个人所看的角度不同而已。从上面的定义中也可知,架构涵盖了软件研发的方方面面,很难有人能够全部都懂,大部分架构师懂得的只是其中的某些方面。一栋高楼大厦也不是一个人完成的。

思考完什么是架构之后,那接下来,就要思考架构怎么做了?这个问题留待后文继续思考。

Elasticsearch备份迁移

yum install fuse sshfs

在其中一个机器上

sshfs root@192.168.0.4:/7890/backup /7890/backup -o nonempty

在所有节点上

path.repo: [“/7890/backup”]

创建备份目录

curl -XPUT http://192.168.0.4:19200/_snapshot/backup -d ‘{“type”:”fs”,”settings”:{“location”:”/7890/backup/”}}’

备份

curl -XPUT  http://192.168.0.4:19200/_snapshot/backup/coolook_es_20160401.tar.gz?wait_for_completion=true

查看备份

curl -XGET http://192.168.0.4:19200/_snapshot/backup/snapshot_test/_status

删除备份

curl -XDELETE http://192.168.0.4:19200/_snapshot/backup/coolook_es_20160401.tar.gz

恢复备份

curl -XPOST  http://192.168.0.4:19200/_snapshot/backup/coolook_es_20160401.tar.gz/_restore

压缩打包

nohup tar -jcvf backup.tar.bz2 backup/* &
nohup tar -jxv -f backup.tar.bz2 &

TF-IDF算法

TF-IDF(TERMFREQUENCY-INVERSE DOCUMENT FREQUENCY)算法,该算法的两个主要目的:计算词的TF值、 计算词的IDF值

其中一篇文档中词W的TF值的计算公式为:

TF(W) = {W的出现次数} / N

其中N为该篇文档中出现的所有分词(不考虑停用词)

因为对于一篇文档,只是单纯的根据每个分词的词频来确定该词对该文档的重要程度

有一个大的缺陷,例如:一个词在很多文档中都出现过,那么我们可以认为该词对不

同文档的区分度不是很明显,所以还需要计算该词的IDF值,该值能够表征某个词的

特异性(即根据这个词可以很容易区分文档的类别)。

IDF值得计算公式为:

IDF(W) = LOG( {语料库中的总文档数} / (语料库中的文档含有W的总文档数 + 1))

之后就可以得到某个词的 TF-IDF值:

TF-IDF(W) = TF(W) * IDF(W)

PS: 因为TF-IDF算法并没有考虑到词的位置,所以一般会使用改进的TF-IDF算法,大致过程就是对于标题出现的分词、对文档中每段开始一句的所有分词给予更大的权重。
目前ANSJ是基于TF-IDF算法的中文处理框架