Scala01入門

1章 可伸展的語言

Scala應用范圍廣,從編寫腳本,到建立大型系統。

運行在標準Java平臺上,與Java庫無縫交互。

更能發揮力量的地方:建立大型系統或可重用控件的架構。

將面向對象和函數式編程加入到靜態類型語言。


Scala中,函數就是對象。函數類型是能夠被子類繼承的類。

Scala是純粹的面向對象語言:每個值都是對象,每個操作都是方法調用。如1+1,實際是調用Int里的+方法。

?

語言分類:

指令式語言 imperative

函數式語言 functional


函數式編程:

函數是對能產生值的表達式的定義。

兩種指導理念:

1、函數是頭等值。

函數也是,與整數、字符串處于同一個地位;

可以當作參數傳遞給其他函數;

可以當作結果從函數中返回或保存在變量里;

可以在函數里定義其他函數,就好像在函數里定義整數一樣;

可以定義匿名函數,并隨意插入到代碼的任何地方。

2、程序的操作應該把輸入值映射為輸出值而不是就地修改數據。

不可變數據結構是函數式語言的一塊基石;

Scala中的不可變列表元組、映射表、集;

無副作用

?

Scala的兼容性:

Scala程序被編譯成JVM字節碼,性能與Java相當。

自由調用Java類庫。

允許定義類型失配或者選用不存在的方法時使用隱式類型轉換(implicit conversion)。

?

Scala定義類:?

class MyClass(index:Int, name:String)
含有兩個私有字段,以及一個構造函數。


測試只能證明錯誤存在,而非不存在。

有用的文檔是那些程序的讀者自己不可能很容易的看懂程序功能的文檔。

?

類型推斷 type inference

?


第2章?Scala入門初探第2章?Scala入門初探

Scala解釋器:

resX 解釋器自動產生的計算結果

val 只能賦值一次

var 可以賦值多次

?

兩次回車鍵取消多行輸入

?

函數定義:

def max(x:Int, y:Int):Int={function block;
}


參數類型必須指定。

函數結果(result type)類型 ?如果遞歸定義則必須指定,否則可以不用顯示指定而用類型推斷。

?

如果函數只有一行表達式,可省略{}

當函數沒有返回值時返回Unit

結果類型為Unit的函數是為了其運行效果,即side effect

?

腳本:經常會被執行的,放在文件中的子序列。

> scala hello.scala arguments

腳本中訪問腳本參數:args(0)

args.foreach(arg=>println(arg))
args.foreach(println)


函數字面量語法結構:括號、命名參數列表、右箭頭、函數體

(x:Int, y:Int) => x+y

for(arg <- args)println(arg)


3Scala入門再探

3.1 類型參數化數組

val greetStrings=new Array[String](3)
greetStrings(0)="Hello"
greetStrings(1)=", "
greetStrings(2)="world!\n"val greetStrings = Array("Hello",", ","world!\n")
for(i<-0 to 2)print(greetString(i))

1、[String]新建一個String型的數組;

2、數組用(index)引用其中的值;

3、若方法只有一個參數,調用時可以省略點及括號;

(0).to(2) ?0 to 2 ??????println(10) ?Console println 10

4Scala沒有傳統意義上的操作符,取而代之的是+-*/這樣的字符作為方法名,1+2 是方法的調用:(1).+(2)

?

用括號訪問數組:數組也是對象,實質為對象的值參數,調用的是apply方法

用括號傳遞給變量一個或多個值參數時,scala會把它轉換成對apply方法的調用。

任何對于對象的值參數應用都被轉換為對apply方法的調用。前提是這個類型定義了apply方法。

arrayObject(i)被轉換為arrayObject.apply(i)

?

當對帶有括號并包括一到若干參數的變量賦值時,編譯器將使用對象的update方法對括號里的參數和等號右邊的對象執行調用。

greetStrings(0)=”Hello”

greetStrings.update(0,”Hello”)

?

val numNames = Array(“zero”,”one”,”two”)

val numNames = Array.apply(“zero”,”one”,”two”)

調用apply工廠方法,可以有不定個數的參數,定義在Array的伴生對象(companion object)中。

?

3.2 使用列表(list)

方法沒有副作用是函數式編程的重要概念,計算并返回值應該是方法的唯一目的。

數組是可變的同類對象序列。

列表是不可變的同類對象序列,為的是方便函數式編程。


val oneTwo=List(1,2)
val threeFour=List(3,4)
val all=oneTwo::threeFour
val all=1::2::3::4::Nil

:::列表疊加,新建列表并返回

::前插 ???Nil是空列表 ???帶冒號的方法調用者是后者,1::Nil ??Nil.::(1)

如何append

1、::前插,再reverse;

2、ListBuffer支持append,toList

?

3.3 使用元組(Tuple)

不可變,可包含不同類型的元素。

如果在方法里返回多個對象,java的做法是創建JavaBean以包含多個返回值,Scala里可以返回元組來達到目的。

val pair=(99,"Luftballons")
println(pair._1+" "+pair._2)
用點號、下劃線和基于1 的索引訪問其中的元素。

列表的apply方法始終返回同樣的類型,所以可以用(index)訪問,而元組中元素的類型都不同,所以用._index訪問。

1開始是依傳統設定的。

?

3.4 使用集(set)和映射(map)

scala.collection.immutable.Set

scala.collection.mutable.Set

scala.collection.imutable.HashMap

scala.collection.mutable.HashMap

默認為immutable

?

3.5 學習識別函數式風格

如果包含var變量,可能是指令式風格;

如果僅含val變量,可能是函數式風格。

?

指令式風格

def printArgs(args :Array[String]):Unit={var i = 0while(i<args.length){println(args(i))i+=1}
}

函數式風格

def printArgs(args:Array[String]):Unit={for(arg<-args)println(args) //args.foreach(println)

每個有用的程序都會有某種形式的副作用,否則就不可能向程序之外提供什么有價值的東西。

?

無副作用的代碼使測試變得容易:

def formatArgs(args:Array[String])=args.mkString("\n")
val res=formatArgs(Array("zero","one","two"))
assert(res=="zero\none\ntwo")

Scalaassert方法檢查傳入的Boolean表達式,如果為假,拋出AssertionError

?

Scala程序員的平衡感:

崇尚val、不可變對象、無副作用的方法;

只有在特定需要和加以權衡之后才選擇var、可變對象、有副作用的方法。

?

3.6 從文件里讀取文本行(腳本)

import scala.io.Source
def widthOfLength(s:String)=s.length.toString.length
if(args.length>0){val lines=Source.fromFile(args(0)).getLines.toListval longestLine=lines.reduceLeft((a,b)=>if(a.length>b.length)a else b)val maxWidth=widthOfLength(longestLine)for(line<-lines){val numSpaces=maxWidth-widthOfLength(line)val padding=" "*numSpacesprint(padding+ling.length+"|"+line)
}
elseConsole.err.println("Please enter filename")


Source.fromFile(args(0)).getLines方法返回一個迭代器Iterator[String]

getLines方法返回的是迭代器,一旦遍歷完成就失效了,所以要toList


4章 類和對象

4.1 類、字段、方法

成員(member:

valvar定義字段

def定義方法

?

字段的另一種說法:實例變量(instance variable

?

私有字段只能被同一個類里的方法訪問,所有能更新字段的代碼都被鎖定在類里。

聲明字段私有:private關鍵字

PublicScala的默認訪問級別。

class ChecksumAccumulator{private var sum=0def add(b:Byte):Unit=sum+=b //def add(b:Byte){sum+=b}def checksum():Int=~(sum&0xFF)+1
}


Scala方法參數都是val,即C++的常引用。

如果沒有顯式返回語句,Scala方法將返回方法中最后一次計算得到的值。

如果函數只有一行表達式,可省略{}

對結果類型為Unit的方法來說,執行的目的就是為了它的副作用——能夠改變方法之外的某處狀態或執行I/O活動

過程(procedure)——一種僅為了副作用而執行的方法。

定義函數時,沒有等號,返回的是Unit??def add(b:Byte){sum+=b}

?

4.2 分號推斷

語句末尾的分號通常可選,如果一行包含多條語句,必須加分號。

val s = “hello”; println(s)

除非以下情況之一成立,否則行尾被認為是一個分號。

1、疑問行由一個不能合法作為語句結尾的字結束,如句點或中綴操作符;

2、下一行開始于不能作為語句開始的詞;

3、行結束于()[]內部,因為這些符號不能容納多個語句。

?

4.3 Singleton對象

Scala不能定義靜態成員,取而代之的是定義單例對象(singleton object

object關鍵字替換class關鍵字。

import scala.collection.mutable.Map
object ChecksumAccumulator{private val cache=Map[String,Int]()def calculate(s:String):Int=if(cache.contains(s))cache(s) //返回鍵s對應的值else{val acc=new ChecksumAccumulaterfor(c<-s)acc.add(c.toByte)val cs=acc.checksum()cache+=(s->cs)cs}
}

單例對象,對應于java的靜態方法工具類。

當單例對象與某個類共享同一個名稱時,被稱為這個類的伴生對象(companion object)。

同名類的伴生對象,與伴生類(companion class)在一個源文件中。

類和其伴生對象可以互相訪問其私有成員。

?

單例對象名.方法名 ?CheckSumAccumulator.calculate(“Every value is an object”)

單例對象不是類型,它擴展了伴生類的父類并可以混入特質。

可以使用類型調用單例對象,或者類型的實例變量指代單例對象,并把它傳遞給需要類型參數的方法。

單例對象不帶參數,而類可以。因為單例對象不是new實例化的,沒機會傳遞給它實例化參數。

每個單例對象都被實現為虛構類(synthetic class)的實例,并指向靜態的變量。

虛構類的名稱是對象名后加一個美元符,單例對象ChecksumAccumulator的虛構類是ChecksumAccumulator$

單例對象在第一次訪問時被初始化。

?

沒有伴生類的單例對象被稱為獨立對象(standalone object,可用于相關功能方法的工具類,或者定義Scala應用的入口點。

?

4.4 Scala程序

能獨立運行的Scala程序,必須創建main方法的單例對象——僅一個參數Array[String],且結果類型為Unit

?

以定義結尾的都不是腳本。

腳本:以結果表達式結束。

?

$ scalac ChecksumAccumulator.scala Summer.scala ?或者

快速Scala編譯器,fast Scala compiler,將編譯程序加載入后臺

$ fsc ChecksumAccumulator.scala Summer.scala

$ fsc -shutdown

?

import ChechsumAcculator.calculate
object Summer{def main(args:Array[String]){for(arg<-grgs)println(arg+":"+calculate(arg))}
}

Scala源文件默認引用java.langscala、單例對象Predef

println語句即為Predef單例對象的printlnPredef.println轉而調用Console.println)。

assert實際調用Predef.assert

?

4.5 Application特質

import ChecksumAcculator.calculate
object FallWinterSpringSummer extends Application{for(season<-List("fall","winter","spring","summer"))println(season+":"+calculate(season))
}

特質Application聲明了帶有合適簽名的main方法,并被單例對象繼承。

大括號之間的代碼被收集進了單例對象的主構造器(primary constructor),并在類初始化時執行。

Scala提供scala.Application特質,可以減少輸入工作。

但無法訪問命令行參數,無法應用于多線程。

?

數組Array 可變同類對象序列

列表List 不可變同類對象序列

元組Tuple 不可變非同類對象序列

集合Set ?映射Map 有可變和不可變

?

5章 基本類型和操作

5.1 基本類型和操作

整數類型 integral type

Byte

Short

Int

Long

Char

數類型 numeric type

Float

Double

?

String ?屬于java.lang

Boolean

?

5.2 字面量

字面量literal——直接寫在代碼里的常量值。

?

原始字符串raw string 三個雙引號對之間的字符串,字符串中可以包含任意字符,不用轉義。

?“””|line1

????|line2”””.stripMargin 此方法使結果符合預期

?

符號字面量——除了顯示名字,什么都不能做。

符號字面量被寫成’<標識符>

被映射成預定義類scala.Symbol的實例,即被編譯器擴展為工廠方法調用:Symbol(“標識符”)

應用場景:動態類型語言中使用一個標識符。

>val s = ‘aSymbol

>s.name ?#aSymbol

如果同一個符號字面量出現兩次,那么兩個字面量指向的是同一個Symbol對象。

?

5.3 操作符和方法

操作符實際只是普通方法調用的另一種表現形式。

值類型對象調用方法的簡寫形式。

任何方法都可以被當做操作符來標注。

>val s=”hello, world”

>s.indexof(‘o’)

>s indexof ‘o’

中綴標注

前綴標注 ?-2.0 實際為 (2.0).unary_- ???+ - ! ~四種操作符可被用作前綴標注

后綴標注 ?s toLowerCase ?不用點號或括號調用不帶任何參數的方法

?

中綴是二元的,前綴和后綴是一元的。

?

Scala中,方法調用的空括號,有副作用就加上,沒副作用就省略。

?

5.7 對象的相等性

首先檢查左側是否為null,如果不是,調用左操作數的equals方法。

精確比較取決于左操作數的equals方法定義。

Java中的==對基本類型,比較的是值相等性;對于引用類型,比較的是引用相等性,即是否指向JVM堆里的同一個對象。

5.8 操作符的關聯性

任何以:字符結尾的方法,右操作數調用方法,傳入左操作數 a:::b ??b.:::(a)

其余相反。

?

5.9 富包裝器

Scala基本類型的方法很多。


Scala基本類型都隱式轉換(implicit conversion)為富包裝器類型,可對外提供多種額外的方法。

想要看到基本類型的所有可用方法,可以查看基本類型的富包裝器的API文檔。

?

第6章?函數式對象

本章重點:函數式對象——不具有任何可改變狀態的對象的類。

不可變對象的優點:

1、對象狀態不可變,思路清晰;

2、無線程安全問題;

3、讓哈希鍵值更安全。

缺點:需要賦值很大的對象表,可變對象可以原址更新。

6.1 Rational的規格說明書

有理數:rational number ?狀態不可變,兩個有理數運算后將產生新的有理數。

分子:numerator

分母:denominator

約分:normalized

?

6.2 創建Rational

class Rational(n:Int,d:Int)

如果類沒有主體,不需要花括號。

n,d稱為類參數class parameter)。

Scala編譯器會收集這兩個類參數并創造出一個主構造器primary constructor)。

類內部任何既不是字段又不是方法的代碼將被編譯進主構造器中,每次新建實例時執行。

class Rational(n:Int,d:Int){println("Create"+n+"/"+d)
}


6.3 重新實現toString方法

類默認繼承了java.lang.Object類的toString實現,打印 ?類名@地址。

重寫(override)toString方法:

class Rational(n:Int,d:Int){override def toStirng=n+"/"+d
}

?

6.4 檢查先決條件

分子不能為零

先決條件是對傳遞給方法或構造器的值的限制,是調用者必須滿足的需求。

為主構造器定義先決條件(precondition:

使用require方法:(定義在scala包的獨立對象Predef上)

class Rational(n:Int,d:Int){require(d!=0)override def toStirng=n+"/"+d
}

Require方法帶一個boolean參數,如果為真,正常返回;反之,require將拋出IllegalArgumentException阻止對象被構造。

?

6.5 添加字段

類參數是為了給字段賦值,所以要添加字段。

class Rational(n:Int,d:Int){required(d!=0)val numer:Int=nval denom:Int=doverride toString=numer+"/"+denomdef add(that:Rational):Rational=new Rational(numer*that.denom+that.num*denom,denom*that.denom)
}

添加了兩個字段,并用參數初始化他們。

?

6.6 自指向

關鍵字this指向當前執行方法被調用的對象實例。

def lessThan(that:Rational)=this.numer*that.denom<that.num*this.denom

6.7 輔助構造器Auxiliary constructor

輔助構造器都是以this(...)形式開頭。

每個輔助構造器的第一個動作都是調用同類的別的構造器。

被調用的構造器可以是主構造器,也可以是別的輔助構造器。

每個Scala構造器最終調用主構造器。主構造器是類的唯一入口點。

?

6.8 私有字段和方法


最大公約數:greatest common divisor

初始化器:initializer——對字段進行初始化的代碼n/g ?d/g

?

6.9 定義操作符

直接將add替換為+

?

?

6.10 Scala的標識符

1、字母數字式 alphanumeric identifier ?

字母、下劃線開頭,之后跟字母數字下劃線。

$為編譯系統所用的標識符,用戶程序不應包含。不建議用“_”結尾

駝峰式camel case:類和特質開頭大寫,其余開頭小寫。

Java中常量名大寫且用“_”分隔,Scala中的常量也用駝峰式。

2、操作符 operator identifier

Scala編譯器將操作符標識符轉換成合法的內嵌”$”java標識符。

:->將被內部表達為$colon$minus$greater

3、混合標識符 mixed identifier

由字母數字組成,后面跟著下劃線和一個操作標識符。

unary_+ 前綴

myvar_=被用作定義賦值操作符的方法名,是由編譯器產生的用來支持屬性(property)的。

4、字面量標識符 literal identifier

用反引號包括的任意字符串`...`

可以把運行時環境認可的任意字符串放在反引號之間當作標識符,結果總被當作是Scala標識符。即使反引號中的是保留字也有效。

javaThread類中訪問靜態的yield方法是典型應用:

因為yieldScala的保留字,所以不能寫成Thread.yield(),可以寫成Thread.`yield`()

?

6.11 方法重載 overload


?

6.12 隱式轉換

類似于C++的轉換構造函數。實際定義在伴生對象中。

implicit def intToRational(x:Int)=new Rational(x)

此時,可執行操作:

>val r=new Rational(2,3)

>2*r ?//2轉換為Rational

注意:要隱式轉換起作用,需要將隱式轉換函數定義在作用范圍之內。

隱式轉換函數是隱式調用。

編程時要在簡潔性和可讀性之間進行權衡。




?

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/news/387199.shtml
繁體地址,請注明出處:http://hk.pswp.cn/news/387199.shtml
英文地址,請注明出處:http://en.pswp.cn/news/387199.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

架構師之路17年精選80篇

【架構必備】 《互聯網架構如何實現“高并發”》4W 《TCP接入層的負載均衡、高可用、擴展性架構設計》2.2W 《配置中心架構設計演進》1.7W 《跨公網調用的大坑與架構優化》1.4W 《DNS在架構設計中的巧用》1.9W 《消息如何在網絡上安全傳輸》1.2W 《10W定時任務&#xff0c;如何…

iphone手機型號獲取

#import <sys/utsname.h> //手機型號 NSString *device [self iphoneType]; (NSString *)iphoneType { struct utsname systemInfo; uname(&systemInfo); NSString *platform [NSString stringWithCString:systemInfo.machine encoding:NSUTF8StringEncoding]; if…

Java網絡01基本網絡概念

協議 Protocol&#xff1a;明確規則 &#xff08;1&#xff09;地址格式&#xff1b; &#xff08;2&#xff09;數據如何分包&#xff1b; ... TCP/IP四層模型&#xff1a; 應用層 HTTP SMTP POP IMAP 傳輸層 TCP UDP 網際層 IP 主機網絡層 host to host layer 數模、…

apache的產品分類說明

分類 項目名 說明 開發語言 服務器&#xff08;共20&#xff09; Apache HTTP Server全球第一HTTP服務器C/CTomcatJava的Web服務器JavaJames郵件服務器JavaSpamAssassin反垃圾郵件C/CPerlApache的Perl編程語言支持C/CTclTCL腳本語言C/CDirectory Server超級目錄服務器JavaAxisW…

Java網絡02基本Web概念

URI Uniform Resource Identifier 同一資源標識符 以特定語法標識一個資源的字符串 絕對URI&#xff1a;URI模式模式特有部分 scheme:scheme-specific-part scheme分為&#xff1a; data file本地文件系統 ftp http telnet urn 統一資源名 scheme-specific-part為&am…

解決自建ca認證后瀏覽器警告

前一篇講解了基本的建立證書的過程&#xff0c;但是建立后總是會在瀏覽器那里警告&#xff1a; 此鏈接不是私密鏈接 --谷歌瀏覽器 此證書頒發機構不可信 此證書不是這個網站的 --ie瀏覽器 總之證書是生成成功了&#xff0c;但是其中的內容填寫錯誤了&a…

設計模式學習(三)——單例模式

在Java開發過程中&#xff0c;很多場景下都會碰到或要用到單例模式&#xff0c;在設計模式里也是經常作為指導學習的熱門模式之一&#xff0c;相信每位開發童鞋都用到過。我們總是沿著前輩的足跡去做設定好的思路&#xff0c;往往沒去探究為何這么做&#xff0c;所以這篇文章對…

Java網絡03流

網絡程序所做的很大一部分工作只是輸入和輸出&#xff1a;從一個系統向另一個系統移動數據。 輸出流 Java的基本輸出流類是java.io.OutputStream: public abstract class OutputStream 這個類提供了寫入數據所需的基本方法&#xff0c;包括&#xff1a; public abstract vo…

基于微信小程序開發的仿微信demo

(本文參考自github/liujians,地址:https://github.com/liujians/weApp) 作者聲明&#xff1a; 基于微信小程序開發的仿微信demo 整合了ionic的樣式庫和weui的樣式庫 使用請查看使用必讀! 更新日志請點擊這里 目前功能 查看消息 網絡請求獲取數據&#xff08;download示例server…

設計模式之六大原則

設計模式之設計原則 這軟件設計過程中&#xff0c;有六大設計原則&#xff1a; 單一職責原則里氏替換原則依賴倒置原則接口隔離原則迪米特法則開閉原則由于軟件開發過程中&#xff0c;根據業務不同等因素形成了各種復雜的而不可預料的需求&#xff0c;遵守原則&#xff0c;讓項…

安裝配置tengine

安裝tengine 1、依賴gcc openssl-devel pcre-devel zlib-devel 安裝&#xff1a;yum install gcc openssl-devel pcre-devel zlib-devel 2、解壓tengine壓縮包&#xff0c;并進入目錄&#xff1b; 3、./configure --prefix/usr/tengine 4、make && make install 5…

使用springboot集成jseesite

請訪問 開源中國下的https://git.oschina.net/wolfking/wolfking-jeesitehttps://www.oschina.net/p/wolfking-jeesite?fromerr6Iie3qZt 下載源碼&#xff0c;按照如下的運行使用 springboot 改造 jeesite&#xff0c;只保留最簡單的系統配置 。 介紹 1、運行主類&#xff0c;…

解決idea 中web項目無法正常顯示的問題

轉載于:https://www.cnblogs.com/nulijiushimeili/p/10575364.html

Hadoop小知識點

hdfs命令行 上傳 hadoop fs -put 文件名 hdfs://主機名:9000/... 下載 hadoop fs -get hdfs://主機名:9000/... 文件名 /hadoop/share/hadoop/mapreduce 文件夾下有測試程序 提交MapReduce任務命令 #hadoop jar hadoop-mapreduce-examples-2.4.1.jar pi 5 5 hadoop fs -m…

copy 擴展名 包含子文件夾 文件 到某個 文件夾

比如我在d:\fff下面有很多子文件夾&#xff0c;子文件夾里還有子文件夾&#xff0c;里面有些文件夾里有.ppm.bz2的后綴的文件&#xff0c;需要把他們找出來復制到d:\fff2里面&#xff0c;應該怎么用批處理寫&#xff1f;最佳答案1234echo offfor /r d:\fff %%a in (*.ppm.bz2) …

在線視頻常見加密方式及安全性透析

信息化時代&#xff0c;多媒體的應用日漸成為人們生活中不可或缺的部分&#xff0c;無論是獲取最新資訊還是教育學習&#xff0c;視頻都是直觀高效的媒介之一。 基于互聯網的快速傳播&#xff0c;眾多培訓機構也逐漸將線下原創版權課程遷移到在線平臺中&#xff0c;一方面可以更…

分享一個前后端分離的web項目(vue+spring boot)

Github地址&#xff1a;https://github.com/smallsnail-wh 前端項目名為wh-web后端項目名為wh-server項目展示地址為我的github pages&#xff08;https://smallsnail-wh.github.io&#xff09;用戶名&#xff1a;admin&#xff0c;密碼admin&#xff08;第一次啟動會比較慢&am…

部署php項目到linux

服務器&#xff1a;39.106.26.67rootBayou2009 數據庫&#xff1a;rootbayou2009 項目文件夾路徑&#xff1a;/home/www/項目文件夾名稱&#xff1a;education.bayou-tech.cn 綁定域名&#xff1a;education.bayou-tech.cn 綁定域名&#xff1a; 用ftp把配置文件下班到windows修…

ionic最新安裝教程

公司最近開發webapp&#xff0c;研究了一下ionicangularjs開發。 安裝過程中碰到許多問題&#xff0c;發現網上有好多資料都已經過時&#xff0c;在這里把最新的流程記錄一下。 首先是安裝node.js&#xff0c;通過nodejs官網下載&#xff0c;沒什么問題。npm已經默認安裝&#…

ZooKeeper安裝配置

配置 1、在conf目錄下創建一個配置文件zoo.cfg tickTime2000 dataDir.../zookeeper/data dataLogDir.../zookeeper/dataLog clientPort2181 initLimit5 syncLimit2 server.1server1:2888:3888 server.2server2:2888:3888 server.3server3:2888:3888 ?tickTime&#…