二Scala基础知识

Scala基础知识谁适合阅读本教程? 本教程适合想从零开始学习 Scala 编程语言的开发人员,强烈建议你有一定的 JAVA 基础,因为 Scala 从 JAVA 演化而来学习任务1、解释器 2、基础语法 3、函数 4、条件与循环 2.1、Scala解释器2.1.1、 交互模式顾名思义就是在命令行调用scala的基础环境,我们在第一篇演示的命令行输出Hello,World!即是。当然Scala在交互模式下能够做很多的事情。在这里我们只做简单的输出演示。 CTRL+C退出交互模式 2.1.2、脚本模式类似于我们在命令行通过 <font color=#7A67EE>java *.java执行</font>一样,我们通过记事本创建一个文件HelloWorld.scala,存储在指定目录,我存储在了/Users/sunliangliang/Desktop/temp这个目录下,代码如下 object HelloWorld { /* 这是我的第一个Scala项目, * 输出"Hello,Scala!" */ def main(args: Array[String]) { println("Hello, Scala!") }}在命令行执行 scala /Users/sunliangliang/Desktop/temp/HelloWorld.scala,看到如下输出结果 2.2、基础语法2.2.1、基础内容普及区分大小写:大小写敏感,即Scala和scala在程序中含义不同类名:首字母大写,驼峰式方法名:首字母小写,驼峰文件名:文件名要和对象/类名匹配包名:全小写常量名:全大写行结尾: 行结尾的";"可省略空格与缩进:运算符前后保留一个空格如: def main(args: Array[String]): Unit = { print("Hello world") }语法规范基本和java一样,其他可参考java相关规范。 2.2.2、变量与常量1、常量的声明:var 常量名 :数据类型 = 值 scala采用数据类型在后面的方式 var str : String = "Scala"2、变量的声明:val 变量名 : 数据类型 = 值 ,如下图 ...

June 14, 2019 · 3 min · jiezi

对话巨杉核心研发团队:分布式数据库自研之路

一直以来,数据库的核心研发团队都十分神秘,作为隐藏在幕后的隐士高人,他们对数据库发展以及数据库研发团队的看法是什么呢?本文我们就由巨杉数据库核心技术研发团队的“老司机”,向大家分享他分布式数据库的自研之路。Q:作为数据库行业的“老司机”,您能否先介绍一下自己?A:我叫Danny,是巨杉数据库核心研发团队的成员,是一名数据库资深工程师和架构师,有超过20年的数据库核心研发经验,曾经作为DB2 内核研发团队成员参与了DB2 ,DPF等产品的架构设计和研发工作。目前,我们北美研发实验室的团队已经有很多数据库的专家“老司机”加入,全部来自DB2 的核心技术团队。虽然我们团队很多都是来自IBM、华为的“传统企业级IT人”,不太喜欢抛头露面。但是现在是技术圈一个变革的新时代,我们的产品已经开源了,所以我们之后也会让我们团队的技术大牛们多多参与社区活动,分享一下我们做数据库核心研发的心得,同时也和大家一起进步。Q:作为“老IBM”,您认为像IBM这样历史悠久的IT企业,他们的核心研发团队是怎么样的呢?您对此感受最深的是什么?A:IBM是最早提出“关系型数据库”这一概念和理论体系的公司,从技术上看,传统三大关系型数据库在发展过程中,其实已经具有很深远的技术储备了。DB2是三大传统关系型数据库中唯一的分布式产品,因此我们团队在分布式技术方面的积累是一脉相承的。我在DB2的十几年里,感受最深的就是技术底蕴和沉淀。比如说,在Unix真正支持线程机制之前,针对多线程模型,甚至是针对不同的硬件设备,他们早已使用汇编语言实现了逻辑线程的切换和调用,这些机制在当时其实是相当领先的。说到研发团队,IBM的实验室也是卧虎藏龙。从最初使用汇编语言开始的技术专家们,一直在参与数据库、操作系统和编译器底层的研发工作,可以说正是他们创造了最早的关系型数据库的概念,也是他们真正把数据库打造成为一个通用的软件平台。Q:像数据库这样的基础软件,技术上的难度是什么?A:数据库软件,特别是一款真正企业级ready的产品,并没有大家想象的,只是开发一款软件那么简单。从技术上来说,数据库既需要有技术基因的传承,又需要创新。数据库技术到现在已经发展了40多年了。在技术的发展中,数据库软件/平台已经成为一个功能复杂,架构庞大,安全要求很高的庞大软件产品体系。因此,技术上既需要技术的积累,也需要新的创新。同时,在应用端这边,由于用户都是银行、政府等这些30年前就开始使用数据库的老客户,他们通常无法承担全盘迁移的风险,因此在业务技术架构上,难免保留了各个时代的历史遗留,比如说,北美一些银行的核心IT系统,直到目前仍然运行在40年前的技术平台之上。这也要求企业级ready的数据库基础软件需要有很强的兼容能力,不但可以保证旧业务的运行,还可以不断地推陈出新。这种创新是必须的,但在技术上却又是最难的。Q:以您近20年的数据库行业经验,您认为数据库核心团队应该是怎么样的?A:我认为数据库核心研发团队的基因很重要,就比如说IBM的DB2团队,就是以多位数据库领域的“老炮儿”为核心,搭配有技术实力的资深工程师,而不像现在很多的开源新产品,他们都是以年轻的创新团队为主。就像我上面提到的技术复杂度和产品历史跨度的问题,数据库产品如果要在大型企业内使用,技术团队必须要有传统数据库的开发经验,这也就是技术老炮儿存在的作用。简单说,数据库基础软件就是创新技术和技术经验积累的融合体。Q:海内外基础软件研发有什么不同?A:相对来说,海外拥有技术人才的基础,也有像IBM Oracle这样的体系的沿袭,培养出了一批批技术人才和团队。所以现在北美很多新一代基础软件产品团队其实还是围绕了老一辈的“老司机”构建的。国内基础软件的人才积累还不够,因此基础软件领域还没有完全形成基础软件领域的武林门派,这也是近年来基础软件和AI领域国内企业疯狂往外招人的原因。但是数据库由于历史原因,国内无论是互联网还是科研团队想要形成独特的门派,还需要时间。巨杉这边我们的团队拥有以王涛为代表的很多DB2 团队的核心技术专家,以及来自华为的技术核心团队成员,是技术基因和技术创新很好的结合。Q:数据库开发和其他软件有什么不同?A:因为刚才提到的这些特点,基础软件特别是数据库的研发,和其他应用软件有很大的不同。其中最大的一个不同点就是开发语言和开发模式。从计算机的发展来看,C是最面向机器语言(汇编代码)的,原则上每一行C代码都可以很精准地映射到一些汇编指令上,因此从对操作系统底层的操控来看最为精准。C++则是在C之上发展起来的面向对象语言。在底层编程中,C++的高级特性被使用的非常少,但是其设计模式对于模块化开发很有帮助。因此使用C++既可以兼顾对操作系统底层最精准的把控,也可以将一些面向对象的理念融入代码中,在复杂系统构建时起到重要作用。如今新的一些新型开发语言则不是面向对象,因此在设计模式上不适合大型复杂系统的开发。同时,这些语言语言简化了很多C/C++里最为重要的指针概念,使其对内存的精准操作变得不可能完成。指针这个概念用好了是神器,用差了是垃圾,大部分能力不高的程序员,或者没有非常完善测试框架的项目很难完美把握指针这类高级特性,使得大型项目开发里面内存泄露和崩溃漏洞遍地都是。但是对于我们巨杉来说,有着DB2数据库内核的研发经验,从人员能力,到代码质量管理,到测试框架的完善都能够完美驾驭这类高级特性,最大程度挖掘出操作系统和数据库底层的性能与处理能力。Q:分布式数据库方向是什么?A:根据Gartner和我们CTO王涛的共同观点,真正特别大使得传统关系型数据库存不下的表相对来讲数量都是可控的。因此有很多workaround都可以搞定这个问题,这也是为什么传统以来大家用分库分表虽然麻烦,但也不是解决不了应用问题。数据库其实真正面临的痛点是“微服务”下,数据服务的资源池化。应用程序从传统烟囱式构建,向微服务转型的过程中,在每一个微服务上都放一个独立的数据库已经是不可能的事情了。这种情况下,数据服务资源池需要直接面向上层成百上千个,来自不同开发商、不同团队的,开发能力不一、应用类型不同、SLA安全级别不同等等的各类需求。因此,资源池必须拥有弹性扩张、资源隔离、多租户、可配置一致性、多模式(支持各类SQL协议)、集群内可配置容灾策略等一系列功能,同时每个数据库实例的计算和存储能力需要做到能够无限扩张,毕竟有些微服务可能会涉及到极多的流水数据,不能限定每个数据库实例使用的资源仅局限于一台物理设备。所以说,单纯为了分布式的OLTP只是解决了不构成刚需的问题(分库分表早可以解决),但是在微服务应用开发的环境下,数据库更是要从资源池化的角度对上层提供服务,同时资源池中的每个数据库实例内部也要支持分布式交易等一系列特性,做到与传统数据库的全兼容。Q:SequoiaDB自从发布3.0版本以来,在社区和市场得到的反馈都很好,能否透露一下产品的一些新动向?A:近期,我们会发布一个新的版本,其中OLTP场景选性能会有大的提升,同时对于SQL处理能力也会有很大提升。在分布式的交易型业务下,整体性能提升将比现在版本有23倍的提升,对比同类产品性能将高出56倍以上。这些在本周的活动我们也会做一个简单的分享和介绍。3月30号,本周末我们巨杉Techday的第二期活动也会在北京举办,我们也会带来一些深度的技术分享,届时也会有现场的视频直播,希望大家也能多多关注和参与!未来我们也会有更多“神秘”的数据库“老司机”给大家带来技术、趋势、见闻的分享~

March 28, 2019 · 1 min · jiezi

写个 Go 时间交并集小工具

示例代码(含测试)在这里需求在甘特图的场景下,我们经常会遇到这种情况,五位员工A, B, C, D, E,可能他们的工作都是并行的,我们需要计算某段时间内他们总的工作时长。我们不能简单得把五个人的工作时间都加起来,因为当中会有重叠的部分。所以这时候我们就需要一个计算时间交并集的工具。思路将一组离散的时间段按照开始时间,从小到大排序。像这样[{2 7} {4 11} {10 19} {10 30} {16 18} {19 29} {23 35} {24 42} {25 30} {27 49}]我这里将时间用十分小的秒来代替,方便理解。循环排序后的数组,如果下一个时间段开始时间介于上个时间段的开始时间和结束时间之间,那么就进行合并,否则就分离。可以看到我们这里有两个关键动作,合并,分离,而这个就是我们要实现的核心代码。实现一段连续的工作时间都会有两个点,开始时间和结束时间。所以我们可以把这个时间结构设计成:type T struct { Start int64 End int64}而一个人的工作时间是由多个 T 组成的,所以我们在定义一个切片类型type TSlice []T为了能顺序合并时间,我们需要将TSlice进行排序。我们知道 Go 中有个 sort 包,我们只需要实现 sort 类型的接口,就能实现 TSlice 的排序了。我们实现下:func (t TSlice) Len() int { return len(t) }func (t TSlice) Swap(i, j int) { t[i], t[j] = t[j], t[i] }func (t TSlice) Less(i, j int) bool { return t[i].Start < t[j].Start }三个方法分别是,长度、交换位置、比小。这样一来,我们就能直接用 sort.Stable() 稳定排序,对我们的时间段切片排序了。好,接下来我们实现并集的方法,我们取名为 Union:func (t TSlice) Union() TSlice { // 新建一个空的时间切片 var s TSlice // 如果有至少两个是时间段,我们才排序,否则直接返回 if len(t) > 1 { // @todo 合并逻辑 } return s}Union 方法将会返回一个同样的 TSlice 时间切片,只不过是经过并集处理的。一旦 t 中的时间段个数大于1,我们就要执行处理逻辑了:if len(t) > 1 { sort.Stable(t) s = append(s, t[0]) // @todo 循环比较合并}我们先对时间切片进行排序,然后把第一个时间段作为第一个元素放进我们的结果 TSlice 中,好让我们开始进行循坏的比较。if len(t) > 1 { sort.Stable(t) s = append(s, t[0]) for k, v := range t { // 如果开始时间大于结束时间,那其实是错误数据,但是我们这里正常返回 // 你可以根据自己的需要定制错误处理逻辑 if v.Start > v.End { return s } // 第一组元素我们不做任何操作 if k == 0 { continue } // 当开始时间介于上一个时间段的开始时间和结束时间之间 if v.Start >= s[len(s)-1].Start && v.Start <= s[len(s)-1].End { // 合并 if v.End > s[len(s)-1].End { s[len(s)-1].End = v.End } // 如果大于上一个时间段的结束时间 } else if v.Start > s[len(s)-1].End { // 分离 inner := T{Start: v.Start, End: v.End} s = append(s, inner) } } }来张图其实就清楚了:可以看到最后输出的也是一个 TSlice 类型。上面就是 union,求并集的过程,那交集的?其实交集也很简单,如果两个时间段相交,我们只要判断:开始时间取最大的那个,结束时间取两个时间段中最小的那个。func (t TSlice) Intersect() TSlice { var s TSlice if len(t) > 1 { sort.Stable(t) s = append(s, t[0]) for k, v := range t { if v.Start > v.End { return s } if k == 0 { continue } // 两个时间段相交 if v.Start >= s[0].Start && v.Start <= s[0].End { // 开始时间取最大的那个 s[0].Start = v.Start // 结束时间取最小的那个 if v.End <= s[0].End { s[0].End = v.End } } else { return s[:0] } } } return s}一样,我们来个图:需要注意的是,这个求交集的结果是全相交–只有当所有时间段都有共同时间才会有结果。这样的需求在实际过程中用到的是不是不太多??所以我想是不是能够实现:一次相交,两次相交…的条件筛选。看看效果我们随机生成了一组时间切片func makeTimes(t int) TSlice { var set TSlice rand.Seed(time.Now().Unix()) for i := 0; i < t; i++ { randStart := rand.Int63n(50) randEnd := randStart + rand.Int63n(25) + 1 set = append(set, T{Start: randStart, End: randEnd}) } return set}testSet := makeTimes(10) // 生成10个时间段的时间切片res := testSet.Union() // 直接调用 Union() 或者 Intersect()输入数据为:[{10 21} {34 52} {49 54} {18 31} {26 44} {24 27} {43 51} {41 53} {20 41} {48 67}]输出结果:[{10 67}]结果还行~额外我发现在求并集的过程中,会要求求最终的时间之和,所以我们为 TSlice 加一个 Sum() 方法,就是简单的循环求和:func (t TSlice) Sum() (sum int64) { for i := 0; i < len(t); i++ { sum += t[i].End - t[i].Start } return sum} ...

February 1, 2019 · 2 min · jiezi

微服务入门【系列视频课程】

本文首发于本博客 猫叔的博客,转载请申明出处公众号:Java猫说现架构设计(码农)兼创业技术顾问,不羁平庸,热爱开源,杂谈程序人生与不定期干货。视频教程地址第一章 从传统单体架构走向微服务第二章 传统单体电商架构第三章 SpringCloud入门第四章 Eureka实操与微服务架构搭建第五章 服务拆分和应用间通信第六章 微服务的不解和深入探讨GitHub源码:mic-demo第一章 从传统单体架构走向微服务Hello,大家好,我是猫叔MySelf,本课程将带领大家入门微服务。各位年轻又帅气的靓仔们!新入职公司,接手公司项目,你所看到的是不是就是一座大山你们接触的项目是不是庞大的代码块、并关系错综复杂(一大堆的目录与包)是不是接手后交付周期也很长(入门也是几个通宵)有没有觉得该项目的扩展能力与弹性受限同时,对于大家这样热爱新技术的同学,有时一用上新技术与工具框架就各种BUG而且一个微不足道的小问题,可以导致整个应用挂掉(高层还总是唠叨我们)也是辛苦大家那段时间每夜每夜的加班工作了!在听微服务之前,因为学员层次不一,希望大家有了解到至少一个单体架构的web项目开发经验或大致流程,这样学起来更轻松哦!聪明的老外总是能先于我们发现新的高效的开发模式,近几年前一个老头就提出了我们将要学习的“微服务”:微服务架构风格是一种将单个应用程序作为一套小型服务开发的方法,每种应用程序都在自己的进程中运行,并与轻量级机制(通常是HTTP资源API)进行通信。 这些服务是围绕业务功能构建的,可以通过全自动部署机制独立部署。 这些服务的集中管理最少,可以用不同的编程语言编写,并使用不同的数据存储技术。大叔的图片这个看起来有点复杂,我就不念了,像教科书一样的文案,有兴趣的同学可以上网深入了解。我们整理一下,并优先入门一些重点。其目的是有效的拆分应用,实现敏捷开发和部署只做一件事,并把它做好对于我们这种要求简单的,工作的时候一般都只想做一件事就好了,不要让我顾及太多。单一(隔离)、独立指责我们可以尽情的在自己负责的项目上“玩耍”啦!对于其他服务层的对接仅需要按照各个应用通信接口文档去走即可!通信(同异步)我们总是要和人交流的,对于我们自己独自负责的服务也是需要去交朋友的,因此它需要与其他各个服务进行通信,这里的通信可能是同步的、异步的。对于每个引用都有他们自己的数据,微服务的采纳有助于我们可以针对部分火爆业务采用不同的数据库类型或者分库读取,而不再需要在同一项目整合多个数据库操作。数据独立我们可以发挥不同语言的优势,比如python、nodejs、php….这对技术专项不同的开发团队来说,配合起来将更加容易与得心应手。技术栈灵活(数据流、存储、业务)独立部署、团队组织架构有效调整第二章 单体架构电商Demo讲解一个普通的电商项目:用户服务:注册商品服务:查询商品订单服务:下单、查看订单数据库表:用户表:用户id、用户名、用户密码、创建时间商品表:商品id、商品名、商品详情、商品价格、库存表:商品id、库存数订单表:订单id、用户名、商品id、订单价格、商品总数、创建时间大致的模拟环境:用户下单与查询订单列表,同时还具备管理人员查询库存接口列表:地址: http://localhost:8080/sells/order/order POST参数id 》 用户id goodsId 》 商品id num 》 商品数量例子{ “code”: 200, “msg”: “成功”, “data”: “MS04780334”}地址:localhost:8762/order/order?id=1 GET参数id 》 用户id例子{ “code”: 200, “msg”: “成功”, “data”: [ { “orderId”: “MS04475904”, “goodsId”: “MS000001”, “name”: “猫叔”, “orderPrice”: 1598, “orderNum”: 2, “createTime”: “2018-12-13T05:59:24.000+0000” }, { “orderId”: “MS04663799”, “goodsId”: “MS000002”, “name”: “猫叔”, “orderPrice”: 2999, “orderNum”: 1, “createTime”: “2018-12-12T16:04:18.000+0000” }, { “orderId”: “MS04780334”, “goodsId”: “MS000001”, “name”: “猫叔”, “orderPrice”: 1598, “orderNum”: 2, “createTime”: “2018-12-13T08:10:29.000+0000” } ]}地址: localhost:8763/goods/goods?id=1&goodsId=MS000002 GET参数id 》 管理员idgoodsId 》 商品id例子{ “code”: 200, “msg”: “成功”, “data”: { “inventoryId”: “IN4567825”, “goodsId”: “MS000002”, “inventoryNum”: 13 }}微服务架构拆分当前只有三个服务,一个用户服务、一个订单服务、一个库存服务假设我们的生意狂飙上涨,投放了分销环节、线上广告啥的,这个时候的订单量非常高。那么我们就可以使用微服务的思想,讲订单服务抽离出来。那么我们将使用SpringCloud来完成这一操作与编码。在基于单体架构的情况下,我们将进行手把手的演进,希望同学们可以一起来撸一把。首先是Eureka注册中心,我们需要向某人说明这里是什么,并将单体服务拆分为两个,order-client服务 还有 其余的服务。那么我们就再新建两个对应的Eureka Client的服务并注册到注册中心同时两个服务之间的通讯也需要采用SpringCloud的操作。第三章 SpringCloud入门说到SpringCloud,我们还需要说一下它基于的更厉害的框架,它就是Netflix。Netflix的多个开源组件一起正好可以提供完整的分布式微服务基础架构环境,而SpringCloud就是对Netflix的多个开源组件进一步封装而成的。同时,它利用SpringBoot的开发便利性巧妙地简化了分布式系统基础设施的开发,比如我们今天将学到的服务发现注册(Eureka)、调用框架(声明式服务客户端Fegin)等等。Spring Cloud将目前各个比较成熟、经得起实际考验的服务框架组合起来,通过Spring Boot风格进行再封装屏蔽掉了复杂的配置和实现原理,因为我们仅仅配置一下、写几句代码就可以实现一个想要的简单的微服务。第四章 Eureka实操与微服务架构搭建Spring Cloud Eureka1、Eureka是一个基于REST的服务2、基于Netflix Eureka做了二次封装3、核心组件为:Eureka Server 注册中心(服务端)Eureka Client 服务注册(客户端)第五章 服务拆分与应用间通信Spring Cloud 服务间的一种RestFul调用方式1、Feign声明式REST客户端接口 + 注解(开启、指定服务名)本质依旧是一个HTTP客户端第六章 关于微服务的不解与深入探讨我想极具好奇心的同学们一定不满足这么一点的概况,的确,微服务还有更多的知识点需要大家去掌握与了解。负载均衡安全机制配置中心链路追踪容器搭配说了那么多,微服务的缺点是什么呀!?我总是希望唱反调的同学毒液中的片段,世界掌握在我们手中没错,任何思想都有其适用性与自身环境,微服务也不例外。在介绍了微服务原理后,大家会提出什么问提呢?我做学生的时候就提出了几个小问题。微服务架构的取舍?需要避免为了“微服务”而“微服务”。 对传统企业而言,开始时可以考虑引入部分合适的微服务架构原则对已有系统进行改造或新建微服务应用,逐步探索及积累微服务架构经验,而非全盘实施微服务架构。微服务的不足又是哪些?微服务的复杂度分布式事务(CAP理论,AP系统)服务的划分服务的部署各个服务组件的版本与部署乃至升级?一套完善的开发管理规范,包括开发设计规范、分支管理规范、持续集成规范,再利用Docker容器的天然的特性:“版本控制、可移植性、隔离性”就可以实现组件的版本管理。实质上基于在支持DevOps完整流程的容器云平台,即可实现整个开发过程及交付中的持续集成、快速部署、灰度发布及无缝升级。最后希望大家都能在未来深入了解并使用微服务。 ...

January 10, 2019 · 1 min · jiezi

安装java编程环境

首先明确自己使用的操作系统在各个系统中的操作其实大同小异,都是以下三个步骤。下载、安装、配置环境变量(以及验证是否配置成功)下面这个是针对Windows的Windows版下载JDK(java development kit)首先要选定一个java版本,我这里选择java1.8,越新的版本一般会有越多的特性。搜索引擎搜索:oracle java 1.8进入到这个页面:Java SE Development Kit 8 - Downloads如果你使用其他操作系统,就下载相应系统的如果嫌下载慢,可以使用迅雷下载。如果要用迅雷下载如何手动获取下载链接呢?如果你正在使用的是windows操作系统,chrome浏览器,那么使用快捷键ctrl+J可以进入浏览器下载页面。如下图所示,可以获得真实的下载链接:安装JDK安装过程中使用默认的配置,一直点下一步即可安装过程发生了什么?我们下载的安装文件一般是压缩文件,所以安装的第一步是解压,将文件指定一个安装位置,也就会将程序文件解压到这个位置。然后有些程序会修改注册表(Windows系统独有的,类unix系统没有注册表),有些会修改自启动设置,有些会修改环境变量。配置java环境变量什么是环境变量?在Windows环境中,首先要区分一个东西:真正可以运行的程序和链接,我们桌面上摆放的那一个个图标其实都只不过是链接(链接也是一种文件),它指向真正可执行的程序(程序也是一种文件),所以如果我们真正可执行的程序文件丢失了(或者说移动到了其他位置),你双击链接是无法运行程序的。如果要让双击链接就能运行程序,有且只有一种情况:链接指向的那个位置存在着我们要执行的程序文件。右键点击,然后在菜单中找到属性,点击进入。一系列的概念:文件(file)、文件夹(也叫做:目录,directory)、路径(path)、命令行(commandline)、变量(variable)文件的概念大家应该是有的,比如一个图片、一个视频、一个word文档、一个可执行的exe文件等等都是一个文件。文件夹,文件夹大家应该也是懂的,一个文件夹下面可以包含文件和文件夹,操作系统的文件系统就像一个树形结构,不断的往下产生分支。但你们可能没想到文件夹其实也是一种文件。文件夹的底层实现原理:包含N多个条目,每个条目是一个文件或文件夹的一串信息,比如文件的创建日期,文件的权限(哪些人可以读,哪些人可以写,哪些人可以执行),文件的类型(是文件还是文件夹),文件的名字等待。路径,路径大家应该就相对陌生了路径就是由若干的文件夹一层一层指向的一个具体位置。我们举个例子来说明一下路径的格式规范:“C:\Program Files\Calibre2\calibre.exe”,在Windows中路径以磁盘符开头,这里是C:;然后是反斜杠\,它会将每一层目录分隔开,夹在两个反斜杠中间的就是目录了(或者说是文件夹)命令行,这个大家应该就十分不熟悉了。按一下windows图标键,然后直接键盘输入 cmd(command的缩写),就可以搜索出命令行程序:点击打开操作系统要找到可执行的文件,就必须依靠明确的路径,如果我们不给出明确的路径操作系统就无法找到。在命令行中,执行一个命令(也就是执行一个程序),系统会在 当前目录下 和 环境变量 中搜索这个名字(程序的名字)。为什么需要环境变量?因为我们不会蠢到跑到相应的路径下去执行我们想要执行的程序。于是我们发明了环境变量来在任意的路径下面执行我们想要执行的程序。于是我们可以猜想到,环境变量应该是由一个个路径或者链接组成的。我们在命令行输入一个程序的名字(很多时候,程序会让你在程序名后输入一些参数),并执行,系统除了在当前目录下查找,还会在环境变量所指明的路径中查找。变量这个词,一般我们会在数学中的函数,或者计算机程序编程语言中接触到。一个变量的值是可以变化的,它是一个抽象符号,背后有一个具体的值。如何配置环境变量然后点击属性此时我们会发现有两种环境变量,一种是当前用户的,一种是系统的,它们的区别就是:当前用户的环境变量只能当前用户使用,如果你换了一个账号登陆,那个账号就没有这些环境变量了;而系统的环境变量对所有用户都有效。我一般会设置到系统的环境变量里。虽然这里有这么多环境变量,但我们的命令行程序只使用其中叫:path的这个环境变量。选择变量是path的这一行,左键双击进入如我们所想的,里面都是一条条路径。我们注意到%,这个符号包裹了一个变量,例如:%SystemRoot%,夹在两个百分号之间的这个SystemRoot也是个环境变量,下面的 JAVA_HOME、ADB_HOME 也是如此。现在安装的Java 1.8版本,已经自动配置了java的环境变量,但没有配置javac的。有些编程语言比如python会自动配置好环境变量。我一般会选择先配置一个JAVA_HOME变量,然后以:%JAVA_HOME%\bin的方式配置在path变量中。我们要先找到Java的安装位置,然后赋值给JAVA_HOME变量。然后在path中新建一条%JAVA_HOME%\bin接下来依次点击确定,关闭打开的窗口就能保存新建的这些配置了。验证是否配置成功依然是新开一个cmd命令行程序(必须要新开一个,旧的cmd在打开的时候已经载入了环境变量,不会刷新环境变量),输入java回车:如果看到下图中的情况,就表示成功了。下图中系统在描述java这个程序的用法,说明系统找到了它。然后再输入javac回车:如果看到下图中的情况,就表示成功了。下图中系统在描述javac这个程序的用法,说明系统找到了它。为什么是两个程序,java用于启动JVM并运行你的.class文件,javac用于将java源程序编译成.class文件。

December 18, 2018 · 1 min · jiezi