「深度学习福利」大神带你进阶工程师,立即查看>>>
(一)
有时,记忆的碎片会从脑神经的连接中苏醒。
(二)
浏览器,客户端browser,client
服务器server view:jsp(含前端控制器DispatcherServlet) | 表现层(controller/action),业务层持久层(model:po,service,dao) 前端 | 后端 设计模式的优点: 分层设计,实现业务系统各个组件之间的解耦;(单个) 有利于系统的可扩展性、可维护性;(多个) 有利于实现系统的并行开发,提升开发的效率。(多对多) 补充一点,我上面的归纳是根据我的理解编写的,实际情况的逻辑很复杂。毕竟我认为java是关系型分层结构的语言。 (三) 准备工具:eclipse 创建项目:Maven工程 1.properties-java build path 2.project facets-dynamic web module:2.5(servlet规范,3.0不用web.xml文件) 或 Java EE Tools-Generate Deployment Descriptor Stub-->src-main-webapp- WEB-INF -web.xml. 3.deployment assembly:打包的环境 搭建环境(配置文件): 1.pom.xml 4.0.0 com.buff springmvc-work 0.0.1-SNAPSHOT war 4.3.8.RELEASE 1.2 org.springframework spring-core ${spring.version} org.springframework spring-web ${spring.version} org.springframework spring-tx ${spring.version} org.springframework spring-jdbc ${spring.version} org.springframework spring-webmvc ${spring.version} org.springframework spring-aop ${spring.version} org.springframework spring-context-support ${spring.version} jstl jstl ${jstl.version} junit junit 4.12 test org.apache.tomcat.maven tomcat7-maven-plugin 2.1 8080 /springmvc-work UTF-8 tomcat7 2.框架核心配置文件:src/main/resources/anyname.xml(约束) xmlns:context="http://www.springframework.org/schema/context" xmlns:mvc="http://www.springframework.org/schema/mvc" xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-4.0.xsd http://www.springframework.org/schema/mvc http://www.springframework.org/schema/mvc/spring-mvc-4.0.xsd http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-4.0.xsd"> 3.src/main/webapp/WEB-INF/web.xml springmvc-work springmvcfancyname-work org.springframework.web.servlet.DispatcherServlet contextConfigLocation classpath:anyname.xml 1 springmvcfancyname-work *.do index.html index.htm index.jsp default.html default.htm default.jsp 4.src/main/webapp/WEB-INF/jsp/hello.jsp <%@ page language="java" contentType="text/html; charset=UTF-8" pageEncoding="UTF-8"%> Demo hello ${hello} 5.编写controller:相当于struts2中处理请求的action src/main/java/com/buff/controller/DemoController.java @Controller //对表现层的注解。最后,对应spring管理文件中的包扫描。 public class DemoController { /** * hello test * ModelAndView:模型和视图。 * 1.用于设置响应的模型数据; * 2.用于设置响应的视图 * @RequestMapping:设置请求的url */ @RequestMapping("/hello.do")//响应数据响应页面有了之后,需要接受方法:创建对应关系 public ModelAndView hello(){ // 1.创建ModelAndView ModelAndView mav = new ModelAndView(); // 2.设置响应的模型数据 /** * addObject方法:设置模型数据 * 参数: * attributeName:模型数据名称 * attributeValue:模型数据 */ mav.addObject("hello", "world"); // 3.设置响应的视图 /** * setViewName方法:设置响应的视图 * 参数: * viewName:页面的物理路径 */ mav.setViewName("/WEB-INF/jsp/hello.jsp"); return mav; } } 「深度学习福利」大神带你进阶工程师,立即查看>>> Sequence data formats 1. Common sequence data formats including GenBank, FASTA, FASTQ formats. GenBank and FASTA format often represent curated sequencing information. FASTQ often represent experimentally obtained data. (1) GenBank file format GenBank is part of the International Nucleotide Sequence Database Collaboration , which comprises the DNA DataBank of Japan (DDBJ), the European Nucleotide Archive (ENA), and GenBank at NCBI. These three organizations exchange data on a daily basis. More information on GenBank format can be found here When do we use the GenBank format? GenBank format can represent variety of information while keeping this information human-readable. It is not suitable for data-analysis. (2) FASTA format 在生物信息学中,FASTA格式是一种用于记录核酸序列或肽序列的文本格式,其中的核酸或氨基酸均以单个字母编码呈现。该格式同时还允许在序列之前定义名称和编写注释。这一格式最初由FASTA软件包定义,但现今已是生物信息学领域的一项标准。 FASTA简明的格式降低了序列操纵和分析的难度,令序列可被文本处理工具和诸如Python、Ruby和Perl等脚本语言处理。 FASTA is a DNA sequence format for specifying or representing DNA sequences. It does not contain sequence quality information. Reference: Wikipedia FASTA格式 (3) FASTQ file format FASTQ is extended FASTA file format with sequencing quality score (phred score). Please refer to the following references: fasta与fastq格式文件解读 Wikipedia FASTQ格式 (Simplified Chinese) or FASTQ format (English) FASTQ文件中,一个序列通常由四行组成: 第一行以@开头,之后为序列的标识符以及描述信息(与FASTA格式的描述行类似) 第二行为序列信息 第三行以+开头,之后可以再次加上序列的标识及描述信息(可选) 第四行为质量得分信息,与第二行的序列相对应,长度必须与第二行相同 The character '!' represents the lowest quality while '~' is the highest. Here are the quality value characters in left-to-right increasing order of quality (ASCII): !"#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\]^_`abcdefghijklmnopqrstuvwxyz{|}~ Further reading: Differences between FASTA, FASTQ and SAM formats 2. Databases that contain gene sequencing data NCBI GEO : can search datasets (sequencing data from a series of participants) NCBI SRA : can search sequencing data from individual participant ArrayExpress : Experiments are submitted directly to ArrayExpress or are imported from the NCBI Gene Expression Omnibus database. For high-throughput sequencing based experiments the raw data is brokered to the European Nucleotide Archive, while the experiment descriptions and processed data are archived in ArrayExpress. European Nucleotide Archive : Learn more about how to use ENA by reading ENA: Guidelines and Tips . I prefer NCBI GEO and SRA because I can use Aspera to download SRA files, which is super fast. It's best to keep Aspera connect software up-to-date. Install Aspera connect on Ubuntu Linux mkdir -p ~/biosoft/ascp && cd ~/biosoft/ascp wget https://download.asperasoft.com/download/sw/connect/3.7.4/aspera-connect-3.7.4.147727-linux-64.tar.gz tar -zxvf aspera-connect-3.7.4.147727-linux-64.tar.gz bash aspera-connect-3.7.4.147727-linux-64.sh # Installing Aspera Connect # Deploying Aspera Connect (/home/jshi/.aspera/connect) for the current user only. # Unable to update desktop database, Aspera Connect may not be able to auto-launch # Restart firefox manually to load the Aspera Connect plug-in # Install complete. # construct soft link sudo ln -s /home/jshi/.aspera/connect/bin/ascp /usr/bin/ascp ascp -h # help ascp -A # version If you have older version, you need to uninstall before you install newer version of Aspera. Actually, you need to delete related files in the following folder: # ~/.mozilla/plugins/libnpasperaweb.so # ~/.aspera/connect rm ~/.mozilla/plugins/libnpasperaweb_{connect build #}.so yes|rm -rf ~/.aspera/connect 3. How to download SRA files from NCBI SRA database? According to SRA group, they recommand Prefetch program provided in SRAtoolkit . More detail can be found in Download Guide . 1. Download SRA files by using prefetch I don't recommand install SRAtoolkit by using sudo apt-get install sratoolkit because the version might be older. I personally prefer to install the latest softwares. SRA files will be deposited in the default file folder ~/ncbi/public/sra . # Install SRAtoolkit mkdir -p ~/biosoft/sratools && cd ~/biosoft/sratools wget https://ftp-trace.ncbi.nlm.nih.gov/sra/sdk/2.8.2-1/sratoolkit.2.8.2-1-ubuntu64.tar.gz tar -zxvf sratoolkit.2.8.2-1-ubuntu64.tar.gz # You echo 'export PATH=$PATH:/home/jshi/biosoft/sratools/sratoolkit.2.8.2-1-ubuntu64/bin' >> ~/.bashrc source ~/.bashrc Prefetch can use several different way to download SAR files, the default one is Aspera, if you want prefetch to use only Aspera to download, you can use the following code. mkdir -p ~/data/project/GSE48240 && cd ~/data/project/GSE48240 # manually generate SRA file list touch GSE48240.txt for i in $(seq -w 1 3); do echo "SRR92222""$i" >>GSE48240.txt;done # Using efetch to generate SRA file list esearch -db sra -query PRJNA209632 | efetch -format runinfo | cut -f 1 -d ',' |grep SRR >> GSE48240.txt prefetch -t ascp -a "/usr/bin/ascp|/home/jshi/.aspera/connect/etc/asperaweb_id_dsa.openssh" --option-file GSE48240.txt Alternatively, you can use curl , wget or ftp to download from generated download links, but will be as slow as snail. 2. Convert SRA files to FASTQ files on the fly This is a better way if you don't have too much space to save the SRA files. fastq-dump will covert SRA files to fastq files on the fly. cat GSE48240.txt | xargs -n 1 echo fastq-dump --split-files $1 other R中修改个别变量名(reshape包)使用names()函数 names(leadership) names(leadership)[2] <- “testDate” names(leadership)[6:10] <-c(“item1”, “item2”, “item3”, “item4”, “item5”) How do I remove part of a string? https://stackoverflow.com/questions/9704213/r-remove-part-of-string gsub sub_str # install bioawk apt-get install bison cd ~/biosoft git clone https://github.com/lh3/bioawk cd bioawk make sudo cp bioawk /usr/local/bin # Download and unzip the file on the fly. curl http://hgdownload.cse.ucsc.edu/goldenPath/hg38/chromosomes/chr22.fa.gz | gunzip -c > chr22.fa # Look at the file cat chr22.fa | head -4 # Count how many "N" are in chr22 sequence cat chr22.fa | grep -o N | wc -l # Count how many bases are in Chr22? cat chr22.fa | bioawk -c fastx '{ print length($seq) }' ------------------------------------------------------------------------------------------------------- 各基因组的对应关系 首先是NCBI对应UCSC,对应ENSEMBL数据库: GRCh36 (hg18): ENSEMBL release_52. GRCh37 (hg19): ENSEMBL release_59/61/64/68/69/75. GRCh38 (hg38): ENSEMBL release_76/77/78/80/81/82. 可以看到ENSEMBL的版本特别复杂!!!很容易搞混! 但是UCSC的版本就简单了,就hg18,19,38, 常用的是hg19,但是我推荐大家都转为hg38 看起来NCBI也是很简单,就GRCh36,37,38,但是里面水也很深! Feb 13 2014 00:00 Directory April_14_2003 Apr 06 2006 00:00 Directory BUILD.33 Apr 06 2006 00:00 Directory BUILD.34.1 Apr 06 2006 00:00 Directory BUILD.34.2 Apr 06 2006 00:00 Directory BUILD.34.3 Apr 06 2006 00:00 Directory BUILD.35.1 Aug 03 2009 00:00 Directory BUILD.36.1 Aug 03 2009 00:00 Directory BUILD.36.2 Sep 04 2012 00:00 Directory BUILD.36.3 Jun 30 2011 00:00 Directory BUILD.37.1 Sep 07 2011 00:00 Directory BUILD.37.2 Dec 12 2012 00:00 Directory BUILD.37.3 可以看到,有37.1, 37.2, 37.3 等等,不过这种版本一般指的是注释在更新,基因组序列一般不会更新!!! 反正你记住hg19基因组大小是3G,压缩后八九百兆即可!!! 如果要下载GTF注释文件,基因组版本尤为重要!!! 对NCBI: ftp://ftp.ncbi.nih.gov/genomes/H_sapiens/GFF/ ##最新版(hg38) ftp://ftp.ncbi.nlm.nih.gov/genomes/Homo_sapiens/ARCHIVE/ ## 其它版本 对于ensembl: ftp://ftp.ensembl.org/pub/release-75/gtf/homo_sapiens/Homo_sapiens.GRCh37.75.gtf.gz 变幻中间的release就可以拿到所有版本信息: ftp://ftp.ensembl.org/pub/ 对于UCSC,那就有点麻烦了: 需要选择一系列参数: http://genome.ucsc.edu/cgi-bin/hgTables 1. Navigate to http://genome.ucsc.edu/cgi-bin/hgTables 2. Select the following options: clade: Mammal genome: Human assembly: Feb. 2009 (GRCh37/hg19) group: Genes and Gene Predictions track: UCSC Genes table: knownGene region: Select "genome" for the entire genome. output format: GTF - gene transfer format output file: enter a file name to save your results to a file, or leave blank to display results in the browser 3. Click 'get output'. 现在重点来了,搞清楚版本关系了,就要下载呀! UCSC里面下载非常方便,只需要根据基因组简称来拼接url即可: http://hgdownload.cse.ucsc.edu/goldenPath/mm10/bigZips/chromFa.tar.gz http://hgdownload.cse.ucsc.edu/goldenPath/mm9/bigZips/chromFa.tar.gz http://hgdownload.cse.ucsc.edu/goldenPath/hg19/bigZips/chromFa.tar.gz http://hgdownload.cse.ucsc.edu/goldenPath/hg38/bigZips/chromFa.tar.gz 或者用shell脚本指定下载的染色体号: for i in $(seq 1 22) X Y M; do echo $i; wget http://hgdownload.cse.ucsc.edu/goldenPath/hg19/chromosomes/chr${i}.fa.gz; ## 这里也可以用NCBI的:ftp://ftp.ncbi.nih.gov/genomes/M_musculus/ARCHIVE/MGSCv3_Release3/Assembled_Chromosomes/chr前缀 done gunzip *.gz for i in $(seq 1 22) X Y M; do cat chr${i}.fa >> hg19.fasta; done rm -fr chr*.fasta --------------------------------------------------------------------------------------------------------- Tool: fastq-dump Usage: fastq-dump [options] [ ...] fastq-dump [options] Frequently Used Options: General: |
---|
-h | | | --help | Displays ALL options, general usage, and version information. | -V | | | --version | Display the version of the program. | Data formatting: | | | --split-files | Dump each read into separate file. Files will receive suffix corresponding to read number. | | | --split-spot | Split spots into individual reads. | | | --fasta <[line width]> | FASTA only, no qualities. Optional line wrap width (set to zero for no wrapping). | -I | | | --readids | Append read id after spot id as 'accession.spot.readid' on defline. | -F | | | --origfmt | Defline contains only original sequence name. | -C | | | --dumpcs <[cskey]> | Formats sequence using color space (default for SOLiD). "cskey" may be specified for translation. | -B | | | --dumpbase | Formats sequence using base space (default for other than SOLiD). | -Q | | | --offset | Offset to use for ASCII quality scores. Default is 33 ("!"). | Filtering: | -N | | | --minSpotId | Minimum spot id to be dumped. Use with "X" to dump a range. | -X | | | --maxSpotId | Maximum spot id to be dumped. Use with "N" to dump a range. | -M | | | --minReadLen | Filter by sequence length >= | | | --skip-technical | Dump only biological reads. | | | --aligned | Dump only aligned sequences. Aligned datasets only; see sra-stat. | | | --unaligned | Dump only unaligned sequences. Will dump all for unaligned datasets. | Workflow and piping: | -O | | | --outdir | Output directory, default is current working directory ('.'). -Z | | | | | --stdout | --gzip | --bzip2 Output to stdout, all split data become joined into single stream. | Compress output using gzip. | Compress output using bzip2. | Use examples: fastq-dump -X 5 -Z SRR390728 Prints the first five spots (-X 5) to standard out (-Z). This is a useful starting point for verifying other formatting options before dumping a whole file. fastq-dump -I --split-files SRR390728 Produces two fastq files (--split-files) containing ".1" and ".2" read suffices (-I) for paired-end data. fastq-dump --split-files --fasta 60 SRR390728 Produces two (--split-files) fasta files (--fasta) with 60 bases per line ("60" included after --fasta). fastq-dump --split-files --aligned -Q 64 SRR390728 Produces two fastq files (--split-files) that contain only aligned reads (--aligned; Note: only for files submitted as aligned data), with a quality offset of 64 (-Q 64) Please see the documentation on vdb-dump if you wish to produce fasta/qual data. Possible errors and their solution: fastq-dump.2.x err: item not found while constructing within virtual database module - the path '' cannot be opened as database or table This error indicates that the .sra file cannot be found. Confirm that the path to the file is correct. fastq-dump.2.x err: name not found while resolving tree within virtual file system module - failed SRR*.sra The data are likely reference compressed and the toolkit is unable to acquire the reference sequence(s) needed to extract the .sra file. Please confirm that you have tested and validated the configuration of the toolkit. If you have elected to prevent the toolkit from contacting NCBI, you will need to manually acquire the reference(s) here -------------------------------------------------------------------------------------------------------- 下载流程: 1:wget -i ftp://ftp.ncbi.nlm.nih.gov/sra/sra-instant/reads/ByStudy/sra/SRP/SRP000/SRP000001/SRR000001/SRR000001.sra 从NCBI官网下载sra数据文件 2: 使用fastq-dump工具将sra转换成双端fastq 「深度学习福利」大神带你进阶工程师,立即查看>>> 策略模式:可以定义一系列的算法,把这些算法一个个封装起来。 比如,一个游戏对不同等级的会员有不同的充值汇率,钻石会员1元=15个币,铂金会员1元=13个币,黄金会员1元=10个币。使用策略模式就可以把三种会员的三种算法分别封装到单独的实现类中,然后三个实现类实现了同一个接口。 示例代码: 1、创建共同接口: 会员策略接口和充值方法,传入原有剩余的币的值和充值金额 public interface MemberStrategy { public int recharge(int num, int money); } 2、创建三个会员的实现类,并重写充值方法 钻石会员的充值算法,金额*15 + 剩余的币 = 充值后的币 public class DiamondRecharge implements MemberStrategy{ @Override public int recharge(int num, int money) { return money*15 + num; } } 铂金会员的充值算法,金额*13 + 剩余的币 = 充值后的币 public class PlatinumRecharge implements MemberStrategy{ @Override public int recharge(int num, int money) { return money*13 + num; } } 黄金会员的充值算法,金额*10 + 剩余的币 = 充值后的币 public class GoldRecharge implements MemberStrategy{ @Override public int recharge(int num, int money) { return money*10 + num; } } 3、新建会员充值的类 public class MemberRecharge { private MemberStrategy memberStrategy ; public MemberRecharge(MemberStrategy memberStrategy ){ this.memberStrategy = memberStrategy ; } public int executeRecharge(int num, int money){ return memberStrategy .recharge(num, money); } } 4、新建测试类 public class TestStrategy { public static void main(String[] args) { MemberRecharge memberRecharge = new MemberRecharge(new DiamondRecharge()); System.out.println("钻石会员第一次充值1元后剩余的币数量:"+memberRecharge.recharge(0,1)); MemberRecharge memberRecharge = new MemberRecharge(new PlatinumRecharge()); System.out.println("铂金会员第一次充值1元后剩余的币数量:"+memberRecharge.recharge(0,1)); MemberRecharge memberRecharge = new MemberRecharge(new GoldRecharge()); System.out.println("黄金会员第一次充值1元后剩余的币数量:"+memberRecharge.recharge(0,1)); } } 策略模式有良好的扩展性,属于行为型模式,比如新增个白银会员的话也只需新建一个实现 MemberStrategy接口的类即可。 「深度学习福利」大神带你进阶工程师,立即查看>>> 本文主要是继续研读了资深架构师王概凯Kevin执笔的《架构漫谈》系列的《架构漫谈(五):什么是软件》的心得感受。王概凯Kevin结合自己多年的架构经验,通过不同的视角,重新审视架构的本质,从而产生一力作《架构漫谈》系列,作者希望能够抛出自己从实践中得出的一些观点,并引发大家的一些思考,欢迎大家沟通讨论。 如需要阅读原文,请关注公众号“聊聊架构”,从历史文章中获取《架构漫谈》系列。 本文内容结构图: 前几篇重点讲述了,架构产生过程中的三个阶段:Why-How-What。简单给大家回溯下这三个阶段,这样接下来再将这3W阶段的思考,用到软件当中,才会有更深刻的体会。 Why:为何会产生架构 架构本质其实就是解决人的问题,从而满足人不断更高的需求,产生架构的必须动机 : 1. 必须由人执行的工作; 2. 每个人的能力有限; 3. 每个人的时间有限; 4. 人对目标系统有更高的要求; 5. 目标系统的复杂性使得个人独自无法完成这个系统; 复制代码 How:架构中关键步骤 概念认知 :概念是认识沟通这个世界的基础,自然对概念的认知是非常重要的。 1. 概念其实代表其背后解决人的问题而来,不同的概念代表不同的功能,不同的功能解决的问题也不同; 2. 同一事物在不同场景下,解决的问题不同,所代表的功能也不同,从而概念也不同; 复制代码 问题识别 :当找到真正问题时,问题就已解决了80%。 1. 确定问题主体,谁的问题; 2. 确定问题边界,真正的问题是什么; 复制代码 架构切分 :其实就是相关人的利益调整,这就是原动力; 1. 背后的动力,就是每个人自己的利益,这是切分过程中必须要考虑到人的利益; 2. 架构切分最终会反应到组织架构上,形成组织树状; 复制代码 What:架构的本质 架构实际上就是指人们根据自己对世界的认识,为解决某个问题,主动地、有目的地去识别问题,总结得出概念,通过概念作为认识沟通的桥梁,对相关事物进行分解、合并,如:人、利益、问题、组织架构等等,解决这个问题的实践活动。 什么是软件 软件的历史,实际上可以说是用机器模拟人的历史 。不管大家(包括在这个历史过程中的参与者)有没有意识到,我们都有意无意的在计算机上模仿人类的行为。从冯诺依曼结构开始,程序逻辑开始脱离硬件,采用二进制编码。加上存储,配合输入输出,一个简化的大脑就出现了。图灵机则是模拟大脑的计算,用数学的方式把计算的过程定义了出来,著名的邱奇-图灵论题:一切直觉上能行可计算的函数都可用图灵机计算,反之亦然。软硬件两者一结合,一个可编程的大脑出现了,这也是现在为什么我们把计算机叫做电脑。在硬件上编写出的程序,就是软件,是用来控制硬件的行为的。 人们越来越愿意把原来只有人才能做的事情,交给计算机来做。结果就导致软件越来越丰富,能够做的事情也越来越多,成本也越来越低。可以这么说, 成本是我们为什么采用软件的主要动力,可以节省大量的人员培训,减少雇员的数目 。随着互联网的发展,人类社会也开始软件化了。原来必须实体店来进行售卖的,搬到互联网上,开店成本更低,并且能够接触到更多的人。想象一下,一个门店每天的人流达到百万级别是很恐怖的,由实体空间大小来决定。但是在互联网上,访问量千万级别都不算什么。最终的结果就变成,每个人能够负担的工作越来越多,成本越来越低。这也是为什么软件这么热的原因。 有了软件之后,实际上,我们是把我们日常生活中所做的事情,包括我们自己本人都一起虚拟化到了计算机中。 而人则演化成了,通过计算机的输入输出设备,控制计算机中的自己,来完成日常的工作,以及与其他人的沟通 。也就是说, 软件一直以来的动力,始终都是来模拟人和这个社会的 。 不管如何发展,模拟人的所有行为都是一个大的趋势。 也就是说,软件的主要目的,还是把人类的生活模拟化,提供更低成本,高效率的新的生活 。从这个角度来看,软件主要依赖的还是人类的生活知识。软件更多的是扮演一个cost center,这也是为什么会出现很多的软件代工。 软件架构出现 软件工程师是实现这个模拟过程的关键人物,他必须先理解人是怎么在日常生活中完成工作的,才能够很好的把这些工作在计算机中模拟出来 。可是软件工程师需要学习大量的计算机语言和计算机知识,还需要学习各行各业的专业知识。软件工程师本身的培养就比较难,同时行业知识也要靠时间的积累,这样就远远超出了软件工程师的能力了。 所以软件开发就开始有分工了,行业知识和业务的识别,会交给BA,系统的设计会交给架构师,设计的实现交给架构师,实现的检验交给测试,还有很多其他角色的配合 。为了组织这些角色的工作,还有项目经理。 这就把原来一个人的连续工作,拆分成了不同角色的人的连续配合,演化成了不同的软件开发的模式 。然后慢慢演变出专门为别人开发软件的软件公司。 一开始是懵懵懂懂的去写软件,后来慢慢的就有意识的去切分,演变成了不同的架构。 这个背后的动力也是一样的,就是提升参与的人的利益,降低成本。导火索也是软件工程师的任务太重,我们需要把很多工作拆分出来。拆分的原则也是一样的,如何让权责一致 。同样,这个拆分也是需要组织架构的调整,来保证架构的落地。 总结一下 以上通过简单的描述计算机和软件的发展历史,阐明软件的本质, 其实就是通过把人类的日常工作生活虚拟化,减少成本,提升单个人员的生产力,提升人类自己的利益。软件工程师的职责在这个浪潮中,不堪重负,自然而然就分拆为不同的角色,形成了一个独特的架构体系。这一切的背后,仍然是为了提升人类自己的利益,解决人类自己的问题。 作者:猿码道 链接:https://juejin.im/post/5b36ed2af265da597f1c8afe 来源:掘金 著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。 「深度学习福利」大神带你进阶工程师,立即查看>>> 本文主要是继续研读了资深架构师王概凯Kevin执笔的《架构漫谈》系列的《架构漫谈(四):如何做好架构之架构切分》的心得感受。王概凯Kevin结合自己多年的架构经验,通过不同的视角,重新审视架构的本质,从而产生一力作《架构漫谈》系列,作者希望能够抛出自己从实践中得出的一些观点,并引发大家的一些思考,欢迎大家沟通讨论。 如需要阅读原文,请关注公众号“聊聊架构”,从历史文章中获取《架构漫谈》系列。 本文内容结构图: 上一篇已经讲过了如何识别问题,只有在识别出谁的问题之后,才能发现真正的问题,在大部分情况下,问题都会迎刃而解,不需要做额外的动作。 很多时候问题的产生都是因为沟通的误解,或者主观上有很多不必要的利益诉求导致的。 但是总还有一部分确实是有问题的,需要做调整,那么就必须要有所动作,做相应的调整。 这个调整就是架构的切分 。 切分就是利益的调整 要非常的清楚, 所有的切分调整,都是对相关人的利益的调整 。为什么这么说呢,因为维护自己的利益,是每个人的本性,是在骨子里面的,我们不能逃避这一点。 我们已经知道,随着社会的发展,分工是必然的,为什么呢? 这个背后的动力就是每个人自己的利益 。每个人都希望能够把自己的利益最大化,比如:生活的更舒适,更轻松,更安全,占用并享有更多的东西。但是每个人的能力和时间都非常的有限,不可能什么都懂,所以自然需要舍掉一些自己不擅长的东西,用自己擅长的东西去换取别人擅长的东西。 对比一个人干所有的事情,结果就是大家都能够得到更多,当然也产生了一个互相依赖的社会,互相谁都离不开谁。 这就是自然而然而产生的架构切分,背后的原动力就是人们对自己利益的渴望 。人们对自己利益的渴望也是推动社会物质发展的原动力。 在这个模式下,比较有意思的是,每个人必须要舍掉自己的东西,才能够得到更多的东西。有些人不愿意和别人进行交换,不想去依赖于别人,这些人的生活就很明显的差很多,也辛苦很多,自然而然的就被社会淘汰了。 如果需要在这个社会上立足,判断标准就变成了:如何给这个社会提供更好更有质量的服务 。提供更好的更多的服务,自然就能够换取更多的更好的生活必需品。 实际上这就是我们做人的道理 。 为什么需要切分 当人们认识到要主动的去切分一个系统的时候, 毫无疑问,我们不能忘掉利益这个原动力。所有的切分决策都不能够违背这一点,这是大方向 。结合上一篇“识别问题”,一旦确定了问题的主体,那么系统的利益相关人(用现代管理学语言叫:stakeholder)就确定了下来。所发现的问题,会有几种情况: 某个或者某些利益相关人负载太重。 时间上的负载太重。 空间上的负载太重,本质上还是时间上的负载太重。 某个或者某些利益相关人的权利和义务不对等。 切分的原则 情况1是切分的原因,情况2是切分不合理而导致的新的问题,最终还是要回到情况1。 对于情况1,本质上都是时间上的负载 。因为每个人的时间是有限的,怎么在有限的时间内做出更多的事情? 那么只有把时间上连续的动作,切分成时间上可以并行的动作,在空间上横向扩展 。所以切分就要有几个原则: **必须在连续时间内发生的一个活动,不能切分。**比如孕妇怀孕,必须要10月怀胎,不能够切成10个人一个月完成。 **切分出来的部分的负责人,对这个部分的权利和义务必须是对等的。**比方说妈妈10月怀胎,妈妈有权利处置小孩的出生和抚养,同样也对小孩的出生和抚养负责。为什么必须是这样呢? 因为如果权利和义务是不对等的话,会伤害每个个体的利益,分出来执行的效率会比没有分出来还要低,实际上也损害了整体的利益,这违背了提升整体利益的初衷。 **切分出来的部分,不应该超出一个自然人的负载。**当然对于每个人的能力不同,负载能力也不一样,需要不断的根据实际情况调整,这实际上就是运营。 **切分是内部活动,内部无论怎么切,对整个系统的外部应该是透明的。**如果因为切分导致整个系统解决的问题发生了变化,那么这个变化不属于架构的活动。当然很多时候当我们把问题分析的比较清楚的时候,整个系统的边界会进一步的完善,这就会形成螺旋式的进化。但这不属于架构所应该解决的问题。进化的发生,也会导致新的架构的切分。 原则2是确保我们不能违反人性,因为维护自己的利益,是每个人的本性 。只有权利和义务对等才能做到这一点。 从原则2的也可以推理,所有的架构分拆,都应该是形成树状的结果,不应该变成有向图,更不应该是无向图 。很多人一谈架构,必谈分层,但是基本上都没意识到,是因为把一个整体分拆为了一棵树,因为有了树,才有层。 从某种意义上来说,谈架构就是谈分层,似乎也没有错,但是还是知道为什么比较好。 从根节点下来,深度相同的是同一层 。 同样我们看一个组织架构,也可以做一个粗略的判断,如果一个企业的组织架构出现了“图”,比方说多线汇报,一定是对stakeholder的利益分析出现了问题,这就会导致问题2的发生。问题2一旦出现,我们必须马上要意识到,如果这个问题持续时间长,会极大的降低企业的运作效率,对相关stakeholder的利益都是非常不利的,同样对于企业的利益也是不利的。 必须快速调整相关stakeholder的职责,使得企业的组织架构成为一个完美的树状,并且使得数的层数达到尽可能的低 。只有平衡数可以比较好的达到这个效果。 当然如果某个节点的能力很强,也可以达到减小树的高度的结果。 技术的提升,也是可以提升每个节点的能力,降低树的层数 。 很多管理学都在讨论如何降低组织架构的层数,使得管理能够扁平化,原因就在于此,这里就不展开讨论了。 从这里也基本可以得出一个结论,一个好的组织的领导,一定也是一个很好的架构师 。 切分与建模 实际上切分的过程就是建模的过程,每次对大问题的切分都会生成很多小问题,每个小问题就形成了不同的概念 。这也是系列第二篇文章尝试表达的。这些不同的概念大部分时候人们自发的已经建好了, 架构师更多的是要去理解这些概念,识别概念背后所代表的的人的利益 。 比如:人类社会按照家庭进行延续,形成了家族,由于共享一片土地资源,慢慢形成了村庄,村庄联合体,不同地域结合,形成了国家。由于利益分配的原因,形成了政权。 每次政权的更迭,都是利益重新分配的动力所决定的 。 同样对于一个企业也是一样的,一开始一个人干所有的事情。当业务量逐渐变大,就超过了一个人能够处理容量,这些内容就会被分解出来,开始招聘人进来,把他们组合在一起,帮助处理企业的事务。整个企业的事务,就按照原则2,分出来了很多新的概念:营销,售前,售中,售后,财务,HR等等。 企业的创始人的工作就变成了如何组合这些不同的概念完成企业的工作 。如果业务再继续增大,这些分出来的部分还要继续分拆,仍然要按照原则2才能够让各方达到利益最大化。如果某个技术的提升,提高了某个角色的生产力,使得某个角色可以同时在承担更多的工作,就会导致职责的合并,降低树的层数。 切分的输出和组织架构 架构切分的输出实际上就是一个系统的模型,对于一个整体问题,有多少的相关方,每个相关方需要承担哪些权利和义务,不同的相关方是如何结合起来完成系统的整体任务的 。有的时候是从上往下切(企业),有的时候是从下往上合并,有的时候两者皆有之(人类社会的发展)。 而切分的结果最终都会体现在组织架构上,因为我们切分的实际上就是人的利益 。 从这方面也可以看出,任何架构调整都会涉及到组织架构,千万不可轻视 。同样,如果对于stakeholder的利益分析不够透彻,也会导致架构无法落地,因为没有入愿意去损坏自己的利益。一旦强制去执行,人心就开始溃散。这个也不一定是坏事,只要满足原则2就能够很好的建立一个新的次序和新的利益关系,保持组织的良性发展,长久来看是对所有人的利益都有益的,虽然短期内有对某些既得利益者会有损害。 总结一下: 架构的切分的导火索是人的负载太重。 架构的切分实际就是对stakeholder的利益进行切分或合并,使得每个stakeholder的权责是对等的,每个stakeholder可以为自己的利益负责。 架构切分的最终结果都会体现在组织架构上,只有这样才能够让架构落地并推进。 架构切分的结果一定是一个树状,这也是为什么会产生分层。层数越多沟通越多,效率越低,分层要越少越好。尽可能变成一颗平衡树,才能让整个系统的效率最大化。 架构切分=利益调整,利益调整代表了以人为中心,进行的利益在分配。从时间负载、空间负载触发架构切分,而架构切分的原则就是以人的利益为本,也可以说不违背人的本性,切分的过程其实就是分层建模的过程,分层建模就是概念划分的过程,每个概念背后都代表一个问题,最终会形成树状的组织结构,而这种组织结构的调整会涉及到人的组织架构,从而要切实要考虑到人的利益。 作者:猿码道 链接:https://juejin.im/post/5b36eae46fb9a00e4f74dcd7 来源:掘金 著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。 「深度学习福利」大神带你进阶工程师,立即查看>>> 本文主要是继续研读了资深架构师王概凯Kevin执笔的《架构漫谈》系列的《架构漫谈(三):如何做好架构之识别问题》的心得感受。王概凯Kevin结合自己多年的架构经验,通过不同的视角,重新审视架构的本质,从而产生一力作《架构漫谈》系列,作者希望能够抛出自己从实践中得出的一些观点,并引发大家的一些思考,欢迎大家沟通讨论。 如需要阅读原文,请关注公众号“聊聊架构”,从历史文章中获取《架构漫谈》系列。 本文内容结构图: 按照之前的架构定义, 架构就是要不断解决人遇到的问题,然而做好架构首先需要做的就是识别出需要解决的真实问题 。一般来说,如果把真正的问题能够找到,那么问题就已经解决了80%。这个能力基本上就决定了架构师的水平。 一则笑话: 女主人公:老公,把袋子里的土豆切一半下锅。结果老公是把袋子里的每个土豆都削了一半,然后下锅。 当然很多人会说,这个是沟通问题,然后一笑了之。其实,出现这个现象是 由于我们大部分时候过于关注解决问题,急于完成自己的工作,而不关心“真正的问题是什么”而造成的 。当我们去解决一个问题的时候,一定要先把问题搞清楚。 去看看软件开发工作者的时间分配也可以看出,大家大部分时间花在讨论解决方案和实现的细节上, 基本都不会花时间去想“问题是什么” 。或者即使想了一点点,也是一闪而过,凭自己的直觉下判断。 只有真正投入思考问题是什么的工程师,才可能会真正的成长为架构师 。 以这个笑话为例,看看在我们处理问题的时候,都会犯什么样的惯性错误: 被告知要处理一个问题,但是交过来的实际上是一个解决方案,不是问题本身。 被告知要处理一个问题,直接通过直觉就有了一个解决方案,马上考虑解决方案如何落地,或者有几种解决方案,选哪个合适。 如何识别问题主体呢? 所有的概念基本都有一个很大的问题,就是缺乏主语。而我们大家都心照不宣的忽略这个主语,沟通的时候也都以为大家都懂得对方说的主语是谁,结果大家都一起犯错误。 识别问题的一个最大的前提就是要搞清楚:是谁的问题 。这个搞清楚了,问题的边界也就跟着确定了,再去讨论问题才有意义。 以上面切土豆的例子来分析: 女主人提出一个问题,要切土豆下锅煮。 男主人有一个问题,女主人交代了自己必须要完成的一个任务。 每个人都是优先处理自己的问题 ,自然就选择了2,完成了这个任务。这也是大部分软件工程师处理的方式, 以自己认为对的方式完成自己的问题 ,没什么不对啊,也难怪能得到我们的共鸣。这个里面犯的错误是什么呢? 首先,女主人公提出的实际上是解决方案,而不是烧土豆这个问题本身。女主人当时执行这个解决方案可能有困难,就把执行解决方案作为一个任务,委托给了男主人。 其次,男主人得到了一个任务,尽心尽职地把这个任务完成了。 最后的结果是什么呢,每个人都做了很多工作,每个人都认为自己做的是对的,因此没有一个人对结果满意。 因为真正的问题没有被发现,自然也就没有被解决,那么后续还得收拾残局,还要继续解决问题 。事实上自己的工作并没有完成,反而更多了。把原因归结为沟通问题也是可以的,但对于解决问题似乎并没有太多的帮助。因为要改进沟通,这也是一个大问题。 搞明白目标问题“是谁的问题,是什么问题”,当然也是需要沟通的 。为了帮助自己更快的搞明白,首先要做的事是问正确的问题。 架构师应该问的第一个正确的问题就是:目标问题是谁的问题 。 所以得出: 当我们处理问题的时候,如果发现自己正在致力于把自己的工作完成,要马上警惕起来,因为这样下去会演变成没有ownership的工作态度。在面对概念的时候,也会不求甚解,最终会导致没有真正的理解概念。 作为软件工程师或者架构师,我们大部分时候是要去解决别人的问题,“别人”是谁,是值得好好思考的 。在上面故事里面,男主人要解决的,实际上是这个家庭晚餐需要吃土豆的问题, 目标问题的主体实际上是这个家庭的成员 。 如何识别问题边界呢? 明白了问题的主体,这个主体就自然会带来很多边界约束 ,比如土豆是要吃的,要给人吃的,而且还是要给自己的家人吃的。“切土豆下锅”这个问题,因为识别了问题的主体,自然而然的就附带了这么多的信息。 后续如何煮,是否放高压锅煮,放多少水,煮多长时间等等,就自然而然能够问出来其他问题来了,说不定还能够识别出来,女主人给的这个解决方案可能是有问题的 。这个时候才算是真正的明白了问题。可以想象,这样下去最后的结果一定是大家都满意的,因为真正的问题解决了。 只有真正明白了是谁的问题,才能够真正地完成自己的任务,真正地把自己的问题解决掉,而不是反过来 。 由上面的分析可以看出, 找出问题的主体,是做架构的首要问题 。这也是我一再强调的,我们要解决的问题,一定都是人的问题。 进一步,架构师要解决的,基本都是别人的问题,不是自己的问题 。 再进一步,我们一定要明白,任何找上架构师的问题,绝对都不是真正的问题 。为什么呢? 因为如果是真正的问题的话,提问题过来的人肯定都能够自己解决了,不需要找架构师。 架构师都要有这个自觉:发现问题永远都比解决问题来的更加重要 。 当问题的主体离架构师越远,就会让找出问题主体的过程越加困难 ,我们再举一个软件行业比较熟悉的例子:用户给产品经理提出要求,想要一把锤子。这是典型的拿解决方案作为问题的。真正的问题的主体是谁,是用户还是设计师还是施工队? 如果产品经理当成是自己的问题,那么毫无疑问就给了锤子了。 我们需要识别: 用户究竟是二传手,还是问题的真正主体 。如果是设计师,那么问题的边界就变成了设计师的问题,如果是施工队,那么问题就变成了施工队的问题,如果是用户,那么就要看看用户到底有什么困难,绝对不是要一个锤子这么简单。 这也说明了,问题的主体对问题的边界确定有多么的重要 。 当明白了问题的主体,我们才可能真正的认识问题是什么。 因为问题的主体是问题的隐含边界,边界不确定下来,问题就是不确定的 。一旦确定了主体,剩下的就是去搞明白主体有哪些问题。 一般来说, 从问题暴露的点,一点点去溯源查找,一定会找出来谁的问题,以及是什么问题 。最坏情况就是当我们时间或者能力有限,实在是无法定位出是谁的问题的时候,比如系统出故障,也就意味着我们无法根本解决问题。这时最好的办法就是去降低问题发生所带来的成本,尽量去隔离问题影响的范围。给我留出时间和空间去识别真正的问题。 总结一下,要正确的认识问题,需要问两个问题: 这是谁的问题? 有什么问题? 当得到的回答是支支吾吾的时候,我们就知道正确的方向在哪儿,以及需要做哪些事了。 问题1会花比较多的时间,也是支支吾吾最多的地方,因为架构要解决的问题都是人的问题 。但是一旦确定了答案,问题2就会变得非常容易。可以这样说, 架构师的能力大部分会体现在问题1的识别上 。 在实际工作中存在很多的情况,都只是在完成自己的问题或任务,而忽略了问题或任务的根本:谁的问题、什么问题。作为架构师,不仅是架构师,在面对问题时,而 要更多的找出问题是什么,问题的主体是什么,从而只有有了主体,才能够确定问题的边界,最终才会确定出真正的问题所在 。 作者:猿码道 链接:https://juejin.im/post/5b36e55d51882574dc41e948 来源:掘金 著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。 「深度学习福利」大神带你进阶工程师,立即查看>>> 本文主要是继续研读了资深架构师王概凯Kevin执笔的《架构漫谈》系列的《架构漫谈(二):认识概念是理解架构的基础》的心得感受。王概凯Kevin结合自己多年的架构经验,通过不同的视角,重新审视架构的本质,从而产生一力作《架构漫谈》系列,作者希望能够抛出自己从实践中得出的一些观点,并引发大家的一些思考,欢迎大家沟通讨论。 如需要阅读原文,请关注公众号“聊聊架构”,从历史文章中获取《架构漫谈》系列。 本文内容结构图: 如前一篇文章 《架构之缘起》 所述, 架构实际上是解决人的问题,而概念是人认识这个世界的基础,自然概念的认识就非常的重要 。然而,大部分人对于每天都习以为常的概念,都自以为明白了, 但实际上都是下意识的,并不是主动的认识 。 举个栗子: 比如说“什么是桌子?”其实每个人对其的理解描述都是千奇百怪的,这实际上就导致了做架构的时候, 不同角色的沟通会出很多问题 ,那么结果也就可想而知了。 所以, 在架构中对概念的认知,其实是很关键的 ,本文也将尝试讨论下如何认识概念的过程。 首先声明一下,本系列的文章,都是以人的认识为主体去讨论的,解决的都是人的问题,任何没有具体申明的部分,都隐含这一背景,以免大家误解。 概念也属于人认识这个世界并用来沟通的手段 ,包括“概念”这个概念,也是一样的。在古代,不叫“概念”,称之为“名相”。 何为相? 一般我们认为:看到一个东西,比方说杯子,“杯子”就是一个名字,指代的看到的东西就是相,就是事物的相状。我们一听到“杯子”这个词,脑海里就会浮现出一个杯子的形象。而“杯子”这个词,是用来指代的是这个相状的,叫做名。合起来就叫做“名相”。 可是当我们把杯子打碎了的时候,我们还会称这个碎了的东西叫杯子吗? 肯定不会,一般会叫“碎瓦片”,如果我们把碎瓦片磨碎了呢,名字又变了,叫做“沙子”。 这就奇怪了,同样一个东西,怎么会变出这么多的名字出来? 那究竟什么才是相? 实际上“相“表达的不是一个具体的东西,如上面所提的一个瓷器杯子,并不是指这个瓷器,而是这个瓷器所起的一个作用:一手可握,敞口(一般不超过底的大小,太大口就叫碗了),并且内部有一个空间可乘东西的这么一个作用。并不是指这个瓷器本身。这也是为什么我们从电视上看到一个人拿杯子的时候,我们知道这个是杯子。但是实际上我们看到的都是光影而已。 所以说相实际上代表的是这个作用,并不是具体的某个东西,而名是用来标识这个作用的,用来交流的。 为何需要这个作用? 这个作用其实是为了解决“人需要一个可单手持握,但是希望避免直接接触所盛物体”这个问题。 所以说,每个概念实际上所解决的,还是人遇到的某个特定的问题,我们把解决问题的解决方案,给定了一个名字,这个名字就是对应的某个特定的概念。对于概念这个词本身,为了统一指代这些名字,我们称起这类作用的名字称为“概念”。 同样,什么是“建筑”?“建筑”实际上解决的就是“人需要独占的空间,并还能够比较流畅的和外部世界沟通”的问题。 再拿前面的“桌子”来举例,什么叫“桌子”? 很多人回答,四条腿,或者说有腿,有一个平面,等等,柜子不也是这样吗?为什么我们看到柜子,不会认为是桌子呢?即使我们放在柜子上吃饭,我们看到仍然会问,为什么在柜子上吃饭? 不会叫桌子。 如果明白了上面的道理,就很简单了,桌子实际上是为了解决人坐在椅子上,手还能够支撑在一个平面上继续开展活动的问题,一般会和椅子配对出现 。 同理,为何我们可以在不同的语言间进行翻译, 是因为虽然语言不同,但是人类所面临的的问题是一样的,所使用的名不同而已 。对于不同的动物之间的翻译也是同理。 在讨论桌子这个概念的过程中,很多人会提出抽象这个概念,认为定义桌子实际上就是抽象的一个过程。这里,有必要要澄清一下抽象这个概念,这个里面有误解。 抽象这个词代表的含义,实际上是把不同的概念的相似的部分合并在一起,形成一个新的概念。 这个里面问题很多:首先“相似的部分”在不同的人看来,并不一定那么相似;其次,抽象之后形成的是一个新的概念,和原来那个概念并不一样,所解决的问题也不一样。 所以我们不能用抽象来定义一个事物,抽象实际上是一个分类的过程,完全是另一码事。 再举一个例子,杯子和容器,很多人认为容器是杯子的抽象,但是实际上杯子是杯子,容器是容器,它们所解决的问题是不一样的。当我们需要解决装东西的问题的时候,会说容器;当我们需要解决单手持握要装东西的时候,会说要一个杯子。 回过头来,根据架构的定义, 要做好架构所首先必须具备的能力,就是能够正确的认识概念,能够发现概念背后所代表的问题,进而才能够认识目标领域所需要解决的问题 ,这样才能够为做好架构打好基础。 事实上,这一能力,在任何一个领域都是适用的,比如我们如果想要学习一项新的技术,如Hibernate、Spring、PhotoShop、WWW、Internet等等, 如果知道这些概念所要解决的问题,学习这些新的技术或者概念就会如虎添翼,快速的入手 ;学习一个新的领域,也会非常的快速有效;使用这些概念来解释问题,甚至发明新的概念都是很容易的事。 为什么强调这个呢,因为做架构的时候,很多时候都是在一个新的领域解决问题,必须要快速进入并掌握这个领域,然后才能够正确的解决问题 。 总结一下,正如上文所述: 相是一个具体物体的状态和作用,是来解决具体问题的 。而为了人之间的交流,便根据相有了名,名其实就是一个标记,或理解为简单的概念。 所以概念的背后其实是代表解决人的问题 。 而抽象则是对概念或名相似之处的归类、分类的过程 ,不同角度来看会得出不同的相似之处,从而会有不同的抽象出来,所以抽象也会产生不同的新的概念。但抽象出来的概念不能够指具体的事物,而只能做到泛指一类具有相似之处的事物。 其实抽象本身也是一个概念,其背后也在解决归类,分类的问题,但抽象并不是架构的必然产物 。 而在解决问题的工程中,会首先有简单名相(意指解决问题的最原始工具或物体),遇到更高级问题,会有更高级的名相或概念,通过抽象,对名相进行归类、分类,抽象出新的概念,或者再有更高级的抽象,产生更高级的概念,最后由这些概念会组成架构。 作者:猿码道 链接:https://juejin.im/post/5b36e19be51d4558b304325e 来源:掘金 著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。 |