真实的国产乱ⅩXXX66竹夫人,五月香六月婷婷激情综合,亚洲日本VA一区二区三区,亚洲精品一区二区三区麻豆

成都創(chuàng)新互聯(lián)網(wǎng)站制作重慶分公司

go語言p2p項(xiàng)目練手,p2p golang

IPFS(四) 源碼解讀之-p2p

package p2p

10年積累的成都做網(wǎng)站、成都網(wǎng)站制作經(jīng)驗(yàn),可以快速應(yīng)對客戶對網(wǎng)站的新想法和需求。提供各種問題對應(yīng)的解決方案。讓選擇我們的客戶得到更好、更有力的網(wǎng)絡(luò)服務(wù)。我雖然不認(rèn)識你,你也不認(rèn)識我。但先網(wǎng)站設(shè)計(jì)后付款的網(wǎng)站建設(shè)流程,更有石嘴山免費(fèi)網(wǎng)站建設(shè)讓你可以放心的選擇與我們合作。

import (

"context"

"errors"

"time"

net "gx/ipfs/QmPjvxTpVH8qJyQDnxnsxF9kv9jezKD1kozz1hs3fCGsNh/go-libp2p-net"

manet "gx/ipfs/QmV6FjemM1K8oXjrvuq3wuVWWoU2TLDPmNnKrxHzY3v6Ai/go-multiaddr-net"

ma "gx/ipfs/QmYmsdtJ3HsodkePE3eU3TsCaP2YvPZJ4LoXnNkDE5Tpt7/go-multiaddr"

pro "gx/ipfs/QmZNkThpqfVXs9GNbexPrfBbXSLNYeKrE7jwFM2oqHbyqN/go-libp2p-protocol"

pstore "gx/ipfs/QmZR2XWVVBCtbgBWnQhWk2xcQfaR3W8faQPriAiaaj7rsr/go-libp2p-peerstore"

p2phost "gx/ipfs/Qmb8T6YBBsjYsVGfrihQLfCJveczZnneSBqBKkYEBWDjge/go-libp2p-host"

peer "gx/ipfs/QmdVrMn1LhB4ybb8hMVaMLXnA8XRSewMnK6YqXKXoTcRvN/go-libp2p-peer"

)

//P2P結(jié)構(gòu)保存當(dāng)前正在運(yùn)行的流/監(jiān)聽器的信息

// P2P structure holds information on currently running streams/listeners

type P2P struct {

//監(jiān)聽器

Listeners ListenerRegistry

//數(shù)據(jù)流

Streams StreamRegistry

//節(jié)點(diǎn)ID

identity peer.ID

//節(jié)點(diǎn)地址

peerHost p2phost.Host

//一個(gè)線程安全的對等節(jié)點(diǎn)存儲

peerstore pstore.Peerstore

}

//創(chuàng)建一個(gè)新的p2p結(jié)構(gòu)

// NewP2P creates new P2P struct

//這個(gè)新的p2p結(jié)構(gòu)不包含p2p結(jié)構(gòu)中的監(jiān)聽器和數(shù)據(jù)流

func NewP2P(identity peer.ID, peerHost p2phost.Host, peerstore pstore.Peerstore) *P2P {

return P2P{

identity: identity,

peerHost: peerHost,

peerstore: peerstore,

}

}

//新建一個(gè)數(shù)據(jù)流 工具方法 構(gòu)建一個(gè)有節(jié)點(diǎn)id,內(nèi)容和協(xié)議的流

func (p2p P2P) newStreamTo(ctx2 context.Context, p peer.ID, protocol string) (net.Stream, error) {

//30s 后會自動timeout

ctx, cancel := context.WithTimeout(ctx2, time.Second 30) //TODO: configurable?

defer cancel()

err := p2p.peerHost.Connect(ctx, pstore.PeerInfo{ID: p})

if err != nil {

return nil, err

}

return p2p.peerHost.NewStream(ctx2, p, pro.ID(protocol))

}

//對話為遠(yuǎn)程監(jiān)聽器創(chuàng)建新的P2P流

//創(chuàng)建一個(gè)新的p2p流實(shí)現(xiàn)對對話的監(jiān)聽

// Dial creates new P2P stream to a remote listener

//Multiaddr是一種跨協(xié)議、跨平臺的表示格式的互聯(lián)網(wǎng)地址。它強(qiáng)調(diào)明確性和自我描述。

//對內(nèi)接收

func (p2p P2P) Dial(ctx context.Context, addr ma.Multiaddr, peer peer.ID, proto string, bindAddr ma.Multiaddr) ( ListenerInfo, error) {

//獲取一些節(jié)點(diǎn)信息 network, host, nil

lnet, _, err := manet.DialArgs(bindAddr)

if err != nil {

return nil, err

}

//監(jiān)聽信息

listenerInfo := ListenerInfo{

//節(jié)點(diǎn)身份

Identity: p2p.identity,

////應(yīng)用程序協(xié)議標(biāo)識符。

Protocol: proto,

}

//調(diào)用newStreamTo 通過ctx(內(nèi)容) peer(節(jié)點(diǎn)id) proto(協(xié)議標(biāo)識符) 參數(shù)獲取一個(gè)新的數(shù)據(jù)流

remote, err := p2p.newStreamTo(ctx, peer, proto)

if err != nil {

return nil, err

}

//network協(xié)議標(biāo)識

switch lnet {

//network為"tcp", "tcp4", "tcp6"

case "tcp", "tcp4", "tcp6":

//從監(jiān)聽器獲取新的信息 nla.Listener, nil

listener, err := manet.Listen(bindAddr)

if err != nil {

if err2 := remote.Reset(); err2 != nil {

return nil, err2

}

return nil, err

}

//將獲取的新信息保存到listenerInfo

listenerInfo.Address = listener.Multiaddr()

listenerInfo.Closer = listener

listenerInfo.Running = true

//開啟接受

go p2p.doAccept(listenerInfo, remote, listener)

default:

return nil, errors.New("unsupported protocol: " + lnet)

}

return listenerInfo, nil

}

//

func (p2p *P2P) doAccept(listenerInfo *ListenerInfo, remote net.Stream, listener manet.Listener) {

//關(guān)閉偵聽器并刪除流處理程序

defer listener.Close()

//Returns a Multiaddr friendly Conn

//一個(gè)有好的 Multiaddr 連接

local, err := listener.Accept()

if err != nil {

return

}

stream := StreamInfo{

//連接協(xié)議

Protocol: listenerInfo.Protocol,

//定位節(jié)點(diǎn)

LocalPeer: listenerInfo.Identity,

//定位節(jié)點(diǎn)地址

LocalAddr: listenerInfo.Address,

//遠(yuǎn)程節(jié)點(diǎn)

RemotePeer: remote.Conn().RemotePeer(),

//遠(yuǎn)程節(jié)點(diǎn)地址

RemoteAddr: remote.Conn().RemoteMultiaddr(),

//定位

Local: local,

//遠(yuǎn)程

Remote: remote,

//注冊碼

Registry: p2p.Streams,

}

//注冊連接信息

p2p.Streams.Register(stream)

//開啟節(jié)點(diǎn)廣播

stream.startStreaming()

}

//偵聽器將流處理程序包裝到偵聽器中

// Listener wraps stream handler into a listener

type Listener interface {

Accept() (net.Stream, error)

Close() error

}

//P2PListener保存關(guān)于偵聽器的信息

// P2PListener holds information on a listener

type P2PListener struct {

peerHost p2phost.Host

conCh chan net.Stream

proto pro.ID

ctx context.Context

cancel func()

}

//等待偵聽器的連接

// Accept waits for a connection from the listener

func (il *P2PListener) Accept() (net.Stream, error) {

select {

case c := -il.conCh:

return c, nil

case -il.ctx.Done():

return nil, il.ctx.Err()

}

}

//關(guān)閉偵聽器并刪除流處理程序

// Close closes the listener and removes stream handler

func (il *P2PListener) Close() error {

il.cancel()

il.peerHost.RemoveStreamHandler(il.proto)

return nil

}

// Listen創(chuàng)建新的P2PListener

// Listen creates new P2PListener

func (p2p P2P) registerStreamHandler(ctx2 context.Context, protocol string) ( P2PListener, error) {

ctx, cancel := context.WithCancel(ctx2)

list := P2PListener{

peerHost: p2p.peerHost,

proto: pro.ID(protocol),

conCh: make(chan net.Stream),

ctx: ctx,

cancel: cancel,

}

p2p.peerHost.SetStreamHandler(list.proto, func(s net.Stream) {

select {

case list.conCh - s:

case -ctx.Done():

s.Reset()

}

})

return list, nil

}

// NewListener創(chuàng)建新的p2p偵聽器

// NewListener creates new p2p listener

//對外廣播

func (p2p P2P) NewListener(ctx context.Context, proto string, addr ma.Multiaddr) ( ListenerInfo, error) {

//調(diào)用registerStreamHandler 構(gòu)造一個(gè)新的listener

listener, err := p2p.registerStreamHandler(ctx, proto)

if err != nil {

return nil, err

}

//構(gòu)造新的listenerInfo

listenerInfo := ListenerInfo{

Identity: p2p.identity,

Protocol: proto,

Address: addr,

Closer: listener,

Running: true,

Registry: p2p.Listeners,

}

go p2p.acceptStreams(listenerInfo, listener)

//注冊連接信息

p2p.Listeners.Register(listenerInfo)

return listenerInfo, nil

}

//接受流

func (p2p *P2P) acceptStreams(listenerInfo *ListenerInfo, listener Listener) {

for listenerInfo.Running {

//一個(gè)有好的 遠(yuǎn)程 連接

remote, err := listener.Accept()

if err != nil {

listener.Close()

break

}

}

//取消注冊表中的p2p偵聽器

p2p.Listeners.Deregister(listenerInfo.Protocol)

}

// CheckProtoExists檢查是否注冊了協(xié)議處理程序

// mux處理程序

// CheckProtoExists checks whether a protocol handler is registered to

// mux handler

func (p2p *P2P) CheckProtoExists(proto string) bool {

protos := p2p.peerHost.Mux().Protocols()

for _, p := range protos {

if p != proto {

continue

}

return true

}

return false

}

python如何入門?

1.找淺顯易懂,例程比較好的教程,從頭到尾看下去。不要看很多本,專注于一本。把里面的例程都手打一遍,搞懂為什么。

2.去找實(shí)際項(xiàng)目練手。最好是要有真實(shí)的項(xiàng)目做??梢哉?guī)讉€(gè)同學(xué)一起做個(gè)網(wǎng)站之類。注意,真實(shí)項(xiàng)目不一定非要是商業(yè)項(xiàng)目。

3.最好能找到一個(gè)已經(jīng)會python的人。問他一點(diǎn)學(xué)習(xí)規(guī)劃的建議,然后在遇到卡殼的地方找他指點(diǎn)。這樣會事半功倍。

4.另外,除了學(xué)習(xí)編程語言,也兼顧補(bǔ)一點(diǎn)計(jì)算機(jī)基礎(chǔ),和英語。

5.不但要學(xué)寫代碼,還要學(xué)會看代碼,更要會調(diào)試代碼。讀懂你自己程序的報(bào)錯信息。再去找些github上的程序,讀懂別人的代碼。

6.學(xué)會查文檔,用好搜索引擎和開發(fā)者社區(qū)。

想學(xué)Python的童鞋可以加企鵝裙前三位是227,中間是435,后三位是450分享軟件視頻資料

學(xué)Python和學(xué)其他的語言其實(shí)是相同的,我給新同事講課的時(shí)候就說學(xué)編程和練武功其實(shí)是很相似,入門大致這樣幾步:

找本靠譜的書,

找個(gè)靠譜的師傅,

找一個(gè)地方開始練習(xí)。

學(xué)語言也是的:選一本通俗易懂的書,找一個(gè)好的視頻資料,然后自己裝一個(gè)IDE工具開始邊學(xué)變寫。下面我具體來講講:

1.找一本靠譜的書,難度一定要是入門級別,千萬不能太復(fù)雜,不要一下子陷進(jìn)去,會打亂節(jié)奏,學(xué)東西要循序漸進(jìn),不能一口吃個(gè)胖子.打個(gè)比方,學(xué)過java的同學(xué)都聽過大名鼎鼎的thinking in java,這邊書很厚很全,若一上來就學(xué),肯定會吃力,時(shí)間長了就會失去興趣,因此對初學(xué)者來說,一定要找一個(gè)通熟易懂的,簡單的書。入門的書非常關(guān)鍵。

入門的書很多,但是我個(gè)人強(qiáng)烈推薦"A Byte of Python",這本書我讀了2遍,作者寫的思路非常清晰,對每一個(gè)知識點(diǎn)講解的很到位,不多不少,剛剛好,對初學(xué)者來說,力道剛剛好。而且是全英文,對提高自己的英語水平,很有幫助.

網(wǎng)上有人會推薦"笨辦法學(xué)Python",我個(gè)人覺得這本書沒有"A Byte of Python"好 .一般有一些編程基本,我建議直接看"A Byte of Python".這本書的銷量已經(jīng)破百萬了,而且在豆瓣上點(diǎn)評有8.8,可謂是入門級的神書.電子版大家可以在CSDN 搜一下就有,都是高清的.

2.多編寫程序,這似乎是廢話,但是確實(shí)是一句實(shí)話。學(xué)編程一定要親身去編寫,沒有什么捷徑.一開始哪怕你把書里面的例子一字不落敲一遍,也好過你只是去看書,而不動手。

而且學(xué)python 最好是堅(jiān)持編,每天抽小半個(gè)小時(shí),學(xué)一些知識點(diǎn),不斷的堅(jiān)持.大概快的話幾個(gè)星期基本就能入門了。

以上就是我對python 入門的感悟,希望對初學(xué)者能有一點(diǎn)幫助,能幫到一些人少走一點(diǎn)彎路.也就不枉我大半夜在這里碼字了~~

最后說一下,我堅(jiān)持原創(chuàng),若我寫的對大家有幫助,麻煩大家支持一下,也是對我的一點(diǎn)鼓勵和動力。

當(dāng)然,如果你是0基礎(chǔ),周圍也沒有大神帶領(lǐng),自己也學(xué)不進(jìn)去,我勸你還是放棄吧,或者就找個(gè)培訓(xùn)機(jī)構(gòu)花點(diǎn)錢學(xué)習(xí)

謝謝

golang p2p網(wǎng)

繼續(xù)進(jìn)入下一個(gè)初始化

n.netService, err = nebnet.NewNebService(n)

if err != nil {

logging.CLog().WithFields(logrus.Fields{

"err": err,

}).Fatal("Failed to setup net service.")

}

netservice有兩個(gè)成員

type NebServicestruct {

node? ? ? *Node

dispatcher *Dispatcher

}

跳出stup()函數(shù)

先進(jìn)入start()函數(shù)看一看

if err := n.netService.Start(); err != nil {

logging.CLog().WithFields(logrus.Fields{

"err": err,

}).Fatal("Failed to start net service.")

}

進(jìn)入netservice.start()

func (ns *NebService) Start() error {

logging.CLog().Info("Starting NebService...")

// start dispatcher.

ns.dispatcher.Start()

// start node.

if err := ns.node.Start(); err != nil {

ns.dispatcher.Stop()

logging.CLog().WithFields(logrus.Fields{

"err": err,

}).Error("Failed to start NebService.")

return err

}

logging.CLog().Info("Started NebService.")

return nil

}

可以看到第一個(gè)start()的函數(shù)是dispatcher.start()

進(jìn)入dispatch.start()

func (dp *Dispatcher) Start() {

logging.CLog().Info("Starting NebService Dispatcher...")

go dp.loop()

}

然后就出現(xiàn)一個(gè)新的線程、goruntime

go dp.loop()

進(jìn)入該線程,看它干了些什么

timerChan := time.NewTicker(time.Second).C

for {

select {

case -timerChan:

metricsDispatcherCached.Update(int64(len(dp.receivedMessageCh)))

case -dp.quitCh:

logging.CLog().Info("Stoped NebService Dispatcher.")

return

case msg := -dp.receivedMessageCh:

msgType := msg.MessageType()

v, _ := dp.subscribersMap.Load(msgType)

if v == nil {

continue

? }

m, _ := v.(*sync.Map)

m.Range(func(key, valueinterface{}) bool {

select {

case key.(*Subscriber).msgChan - msg:

default:

logging.VLog().WithFields(logrus.Fields{

"msgType": msgType,

}).Warn("timeout to dispatch message.")

}

return true

? })

}

}

一個(gè)有點(diǎn)長的循環(huán)

metricsDispatcherCached.Update(int64(len(dp.receivedMessageCh)))一秒鐘刷新一次緩沖區(qū)

case msg := -dp.receivedMessageCh:

msgType := msg.MessageType()如果能取出dp.receivedMessageCh

msgType := msg.MessageType()首先判斷取出的信息類型

v, _ := dp.subscribersMap.Load(msgType)

if v == nil {

continue

}

根據(jù)類型取出相應(yīng)的map

如果取不出,那么使用continue結(jié)束這個(gè)case

m, _ := v.(*sync.Map)

斷言

m.Range(func(key, valueinterface{}) bool {

select {

case key.(*Subscriber).msgChan - msg:

default:

logging.VLog().WithFields(logrus.Fields{

"msgType": msgType,

}).Warn("timeout to dispa+tch message.")

}

return true

})

將msg推入其他管道里面去。其他goruntime會循環(huán)等待該

區(qū)塊鏈技術(shù)想要快速入門,一般涉及哪些編程語言?

任何一門計(jì)算機(jī)語言,都能在特定某個(gè)領(lǐng)域的應(yīng)用中,實(shí)現(xiàn)區(qū)塊鏈技術(shù);

具體使用哪一門語言,完全看我們相應(yīng)領(lǐng)域行業(yè)企業(yè)項(xiàng)目的技術(shù)要求,以及更關(guān)鍵的:跟已有信息系統(tǒng)的有效對接聯(lián)通。

區(qū)塊鏈具有自下而上生成記錄,生成兩方或多方合同類記錄,加入第三方確認(rèn)機(jī)制,分布存儲,……等特點(diǎn);

從而讓它相比集中式的存儲運(yùn)算而言,變得更為可信。

常見的總統(tǒng)投票,就非常適合以區(qū)塊鏈技術(shù)重新架構(gòu);采用區(qū)塊鏈技術(shù)的投票系統(tǒng),能夠避免哪一家技術(shù)公司、某一個(gè)關(guān)鍵技術(shù)人員,操縱選票統(tǒng)計(jì)結(jié)果的可能。

像我們的法院證據(jù),也特別適合采用區(qū)塊鏈技術(shù)重新架構(gòu)開發(fā)。

其實(shí)像當(dāng)前我們各類互聯(lián)網(wǎng)時(shí)代的“版權(quán)系統(tǒng)”,它們中一些就是采用區(qū)塊鏈技術(shù)架構(gòu)而來,只不過,目前我們的新聞出版局、專利局(或者更廣義地被稱作“專家評委”),都尚未接入這些由互聯(lián)網(wǎng)公司創(chuàng)新而來的版權(quán)平臺。

我們耳熟能詳 的“法大大”(雖然名字不甚好聽、甚至乍一聽來有些讓人“摸不著頭腦”),它也其實(shí)正準(zhǔn)備采用最新的區(qū)塊鏈技術(shù)重新架構(gòu);采用區(qū)塊鏈技術(shù)的合同平臺,因?yàn)樽兊酶涌尚?,也才能更便于互?lián)網(wǎng)時(shí)代人們簽訂各類商務(wù)合同。

還有像我們的“征信系統(tǒng)”,也非常適合以區(qū)塊鏈技術(shù)加以改造。能夠讓它更有說服力,而不致于出現(xiàn)一家單位、乃至隨意某個(gè)關(guān)鍵技術(shù)人員,能隨意往其中添加“征信污點(diǎn)數(shù)據(jù)”的情況。

還有像我們的P2P貸款,如果能夠以區(qū)塊鏈技術(shù)重新架構(gòu)的話,也能夠變得更加可信,而不致于出現(xiàn)違約、卷款跑路這樣的失信情況。

python哪家的培訓(xùn)比較好?價(jià)錢是多少?

相信在IT領(lǐng)域發(fā)展的同學(xué)對Java很熟悉。Java編程語言排行中一直處于領(lǐng)先地位,這可以直接體現(xiàn)Java的重要。因此很多同學(xué)準(zhǔn)備參加Python培訓(xùn)機(jī)構(gòu)系統(tǒng)學(xué)習(xí)。那么,Python培訓(xùn)機(jī)構(gòu)哪家比較好?下面我們介紹一下。

隨著Java的普及,越來越多的人了解Java,企業(yè)也會對求職者提出更高的要求,他們想招聘一些能馬上開始工作的人,所以往往會招聘一些有項(xiàng)目開發(fā)經(jīng)驗(yàn)的人。這就是為什么那么多計(jì)算機(jī)專業(yè)的大學(xué)生找不到工作,所以越來越多的大學(xué)生會選擇在畢業(yè)前后參加一些專業(yè)的Python培訓(xùn)課程,以增加他們的實(shí)踐經(jīng)驗(yàn)。只有增強(qiáng)自己的力量,才能立于不敗之地。

Python培訓(xùn)機(jī)構(gòu)哪家比較好?判斷Python培訓(xùn)機(jī)構(gòu)好與壞主要看以下幾個(gè)方面

1.看教學(xué)課程內(nèi)容

學(xué)習(xí)Java技術(shù),最主要是與時(shí)俱進(jìn),掌握的技術(shù)點(diǎn)能夠滿足時(shí)下企業(yè)的用人需求。而想要了解一家培訓(xùn)機(jī)構(gòu)所提供的課程是否新穎,也可以去機(jī)構(gòu)的官網(wǎng)上看看,了解自己想學(xué)習(xí)的學(xué)科的課程大綱。看看學(xué)習(xí)路線圖是如何安排的,有沒有從零到一的系統(tǒng)搭建,是不是有強(qiáng)化實(shí)訓(xùn)、實(shí)操的比重,有盡量多的項(xiàng)目實(shí)戰(zhàn)。因?yàn)槠髽I(yè)對Java從業(yè)者的技術(shù)能力和動手實(shí)戰(zhàn)能力要求較高。

2.看師資力量

因?yàn)镴ava開發(fā)技術(shù)知識的專業(yè)性很強(qiáng),如果盲目去學(xué)很容易走進(jìn)誤區(qū)。相反,有講師帶領(lǐng),站在巨人的肩膀上,往往事半功倍。畢竟現(xiàn)在這個(gè)時(shí)代只要多跟別人交流才能獲得更多更有價(jià)值的信息,初學(xué)者千萬不能閉門造車。

3.看口碑

行業(yè)內(nèi)口碑比較好,學(xué)生對培訓(xùn)機(jī)構(gòu)比較認(rèn)可,這種機(jī)構(gòu)把精力放在了學(xué)生身上的機(jī)構(gòu),才是做教育的應(yīng)有態(tài)度。

4.看就業(yè)情況

以學(xué)生就業(yè)為目標(biāo)的培訓(xùn)機(jī)構(gòu)現(xiàn)在才是最主要的。要知道就業(yè)也是教學(xué)成果的體現(xiàn),沒有好的教學(xué)保證是做不到好的就業(yè)的。

5.上門免費(fèi)試聽

試聽是為了更好的去感受培訓(xùn)機(jī)構(gòu)的課程內(nèi)容、講課風(fēng)格、班級氛圍等,同時(shí)也能通過和班上在讀同學(xué)進(jìn)行交流,更進(jìn)一步去了解這家培訓(xùn)機(jī)構(gòu)各個(gè)方面是否符合自己的需要。

如何系統(tǒng)地自學(xué) Python

是否非常想學(xué)好 Python,一方面被瑣事糾纏,一直沒能動手,另一方面,擔(dān)心學(xué)習(xí)成本太高,心里默默敲著退堂鼓?

幸運(yùn)的是,Python 是一門初學(xué)者友好的編程語言,想要完全掌握它,你不必花上太多的時(shí)間和精力。

Python 的設(shè)計(jì)哲學(xué)之一就是簡單易學(xué),體現(xiàn)在兩個(gè)方面:

語法簡潔明了:相對 Ruby 和 Perl,它的語法特性不多不少,大多數(shù)都很簡單直接,不玩兒玄學(xué)。

切入點(diǎn)很多:Python 可以讓你可以做很多事情,科學(xué)計(jì)算和數(shù)據(jù)分析、爬蟲、Web 網(wǎng)站、游戲、命令行實(shí)用工具等等等等,總有一個(gè)是你感興趣并且愿意投入時(shí)間的。

廢話不多說,學(xué)會一門語言的捷徑只有一個(gè): Getting Started

? 起步階段

任何一種編程語言都包含兩個(gè)部分:硬知識和軟知識,起步階段的主要任務(wù)是掌握硬知識。

硬知識

“硬知識”指的是編程語言的語法、算法和數(shù)據(jù)結(jié)構(gòu)、編程范式等,例如:變量和類型、循環(huán)語句、分支、函數(shù)、類。這部分知識也是具有普適性的,看上去是掌握了一種語法,實(shí)際是建立了一種思維。例如:讓一個(gè) Java 程序員去學(xué)習(xí) Python,他可以很快的將 Java 中的學(xué)到的面向?qū)ο蟮闹R map 到 Python 中來,因此能夠快速掌握 Python 中面向?qū)ο蟮奶匦浴?/p>

如果你是剛開始學(xué)習(xí)編程的新手,一本可靠的語法書是非常重要的。它看上去可能非??菰锓ξ?,但對于建立穩(wěn)固的編程思維是必不可少。

下面列出了一些適合初學(xué)者入門的教學(xué)材料:

廖雪峰的 Python 教程 ? ?Python 中文教程的翹楚,專為剛剛步入程序世界的小白打造。 ?

笨方法學(xué) Python ? ?這本書在講解 Python 的語法成分時(shí),還附帶大量可實(shí)踐的例子,非常適合快速起步。 ?

The Hitchhiker’s Guide to Python! ? ?這本指南著重于 Python 的最佳實(shí)踐,不管你是 Python 專家還是新手,都能獲得極大的幫助。 ?

Python 的哲學(xué):

用一種方法,最好是只有一種方法來做一件事。

學(xué)習(xí)也是一樣,雖然推薦了多種學(xué)習(xí)資料,但實(shí)際學(xué)習(xí)的時(shí)候,最好只選擇其中的一個(gè),堅(jiān)持看完。

必要的時(shí)候,可能需要閱讀講解數(shù)據(jù)結(jié)構(gòu)和算法的書,這些知識對于理解和使用 Python 中的對象模型有著很大的幫助。

軟知識

“軟知識”則是特定語言環(huán)境下的語法技巧、類庫的使用、IDE的選擇等等。這一部分,即使完全不了解不會使用,也不會妨礙你去編程,只不過寫出的程序,看上去顯得“傻”了些。

對這些知識的學(xué)習(xí),取決于你嘗試解決的問題的領(lǐng)域和深度。對初學(xué)者而言,起步階段極易走火,或者在選擇 Python 版本時(shí)徘徊不決,一會兒看 2.7 一會兒又轉(zhuǎn)到 3.0,或者徜徉在類庫的大海中無法自拔,Scrapy,Numpy,Django 什么都要試試,或者參與編輯器圣戰(zhàn)、大括號縮進(jìn)探究、操作系統(tǒng)辯論賽等無意義活動,或者整天跪舔語法糖,老想著怎么一行代碼把所有的事情做完,或者去構(gòu)想圣潔的性能安全通用性健壯性全部滿分的解決方案。

很多“大?!倍紩嬲]初學(xué)者,用這個(gè)用那個(gè),少走彎路,這樣反而把初學(xué)者推向了真正的彎路。

還不如告訴初學(xué)者,學(xué)習(xí)本來就是個(gè)需要你去走彎路出 Bug,只能腳踏實(shí)地,沒有奇跡只有狗屎的過程。

選擇一個(gè)方向先走下去,哪怕臟丑差,走不動了再看看有沒有更好的解決途徑。

自己走了彎路,你才知道這么做的好處,才能理解為什么人們可以手寫狀態(tài)機(jī)去匹配卻偏要發(fā)明正則表達(dá)式,為什么面向過程可以解決卻偏要面向?qū)ο螅瑸槭裁次铱梢圆倏v每一根指針卻偏要自動管理內(nèi)存,為什么我可以嵌套回調(diào)卻偏要用 Promise...

更重要的是,你會明白,高層次的解決方法都是對低層次的封裝,并不是任何情況下都是最有效最合適的。

技術(shù)涌進(jìn)就像波浪一樣,那些陳舊的封存已久的技術(shù),消退了遲早還會涌回的。就像現(xiàn)在移動端應(yīng)用、手游和 HTML5 的火熱,某些方面不正在重演過去 PC 的那些歷史么?

因此,不要擔(dān)心自己走錯路誤了終身,堅(jiān)持并保持進(jìn)步才是正道。

起步階段的核心任務(wù)是掌握硬知識,軟知識做適當(dāng)了解,有了穩(wěn)固的根,粗壯的枝干,才能長出濃密的葉子,結(jié)出甜美的果實(shí)。

? 發(fā)展階段

完成了基礎(chǔ)知識的學(xué)習(xí),必定會感到一陣空虛,懷疑這些語法知識是不是真的有用。

沒錯,你的懷疑是非常正確的。要讓 Python 發(fā)揮出它的價(jià)值,當(dāng)然不能停留在語法層面。

發(fā)展階段的核心任務(wù),就是“跳出 Python,擁抱世界”。

在你面前會有多個(gè)分支:科學(xué)計(jì)算和數(shù)據(jù)分析、爬蟲、Web 網(wǎng)站、游戲、命令行實(shí)用工具等等等等,這些都不是僅僅知道 Python 語法就能解決的問題。

拿爬蟲舉例,如果你對計(jì)算機(jī)網(wǎng)絡(luò),HTTP 協(xié)議,HTML,文本編碼,JSON 一無所知,你能做好這部分的工作么?而你在起步階段的基礎(chǔ)知識也同樣重要,如果你連循環(huán)遞歸怎么寫都還要查文檔,連 BFS 都不知道怎么實(shí)現(xiàn),這就像工匠做石凳每次起錘都要思考錘子怎么使用一樣,非常低效。

在這個(gè)階段,不可避免要接觸大量類庫,閱讀大量書籍的。

類庫方面

「Awesome Python 項(xiàng)目」:vinta/awesome-python · GitHub

這里列出了你在嘗試解決各種實(shí)際問題時(shí),Python 社區(qū)已有的工具型類庫,如下圖所示:

請點(diǎn)擊輸入圖片描述

vinta/awesome-python

你可以按照實(shí)際需求,尋找你需要的類庫。

至于相關(guān)類庫如何使用,必須掌握的技能便是閱讀文檔。由于開源社區(qū)大多數(shù)文檔都是英文寫成的,所以,英語不好的同學(xué),需要惡補(bǔ)下。

書籍方面

這里我只列出一些我覺得比較有一些幫助的書籍,詳細(xì)的請看豆瓣的書評:

科學(xué)和數(shù)據(jù)分析:

?「集體智慧編程」:集體智慧編程 (豆瓣)

?「數(shù)學(xué)之美」:數(shù)學(xué)之美 (豆瓣)

?「統(tǒng)計(jì)學(xué)習(xí)方法」:統(tǒng)計(jì)學(xué)習(xí)方法 (豆瓣)

?「Pattern Recognition And Machine Learning」:Pattern Recognition And Machine Learning (豆瓣)

?「數(shù)據(jù)科學(xué)實(shí)戰(zhàn)」:數(shù)據(jù)科學(xué)實(shí)戰(zhàn) (豆瓣)

?「數(shù)據(jù)檢索導(dǎo)論」:信息檢索導(dǎo)論 (豆瓣)

爬蟲:

?「HTTP 權(quán)威指南」:HTTP權(quán)威指南 (豆瓣)

Web 網(wǎng)站:

?「HTML CSS 設(shè)計(jì)與構(gòu)建網(wǎng)站」:HTML CSS設(shè)計(jì)與構(gòu)建網(wǎng)站 (豆瓣)

...

列到這里已經(jīng)不需要繼續(xù)了。

聰明的你一定會發(fā)現(xiàn)上面的大部分書籍,并不是講 Python 的書,而更多的是專業(yè)知識。

事實(shí)上,這里所謂“跳出 Python,擁抱世界”,其實(shí)是發(fā)現(xiàn) Python 和專業(yè)知識相結(jié)合,能夠解決很多實(shí)際問題。這個(gè)階段能走到什么程度,更多的取決于自己的專業(yè)知識。

? 深入階段

這個(gè)階段的你,對 Python 幾乎了如指掌,那么你一定知道 Python 是用 C 語言實(shí)現(xiàn)的。

可是 Python 對象的“動態(tài)特征”是怎么用相對底層,連自動內(nèi)存管理都沒有的C語言實(shí)現(xiàn)的呢?這時(shí)候就不能停留在表面了,勇敢的拆開 Python 的黑盒子,深入到語言的內(nèi)部,去看它的歷史,讀它的源碼,才能真正理解它的設(shè)計(jì)思路。

這里推薦一本書:

「Python 源碼剖析」:Python源碼剖析 (豆瓣)

這本書把 Python 源碼中最核心的部分,給出了詳細(xì)的闡釋,不過閱讀此書需要對 C 語言內(nèi)存模型和指針有著很好的理解。

另外,Python 本身是一門雜糅多種范式的動態(tài)語言,也就是說,相對于 C 的過程式、 Haskell 等的函數(shù)式、Java 基于類的面向?qū)ο蠖?,它都不夠純粹。換而言之,編程語言的“道學(xué)”,在 Python 中只能有限的體悟。學(xué)習(xí)某種編程范式時(shí),從那些面向這種范式更加純粹的語言出發(fā),才能有更深刻的理解,也能了解到 Python 語言的根源。

這里推薦一門公開課

「編程范式」:斯坦福大學(xué)公開課:編程范式

講師高屋建瓴,從各種編程范式的代表語言出發(fā),給出了每種編程范式最核心的思想。

值得一提的是,這門課程對C語言有非常深入的講解,例如C語言的范型和內(nèi)存管理。這些知識,對閱讀 Python 源碼也有大有幫助。

Python 的許多最佳實(shí)踐都隱藏在那些眾所周知的框架和類庫中,例如 Django、Tornado 等等。在它們的源代碼中淘金,也是個(gè)不錯的選擇。

? ?最后的話

每個(gè)人學(xué)編程的道路都是不一樣的,其實(shí)大都殊途同歸,沒有迷路的人只有不能堅(jiān)持的人!

希望想學(xué) Python 想學(xué)編程的同學(xué),不要猶豫了,看完這篇文章,

Just Getting Started ??。?!


當(dāng)前標(biāo)題:go語言p2p項(xiàng)目練手,p2p golang
網(wǎng)站地址:http://www.weahome.cn/article/dsgdehc.html

其他資訊

在線咨詢

微信咨詢

電話咨詢

028-86922220(工作日)

18980820575(7×24)

提交需求

返回頂部