摘要:以實(shí)現(xiàn)自己熟悉的東西為導(dǎo)向比如我們做后端開發(fā),首先是常用的循環(huán)迭代條件判斷增刪改成。它是由實(shí)現(xiàn)的,不保證元素的順序,也就是說(shuō)所說(shuō)元素插入的順序與輸出的順序不一致。
下面是我直播的文字版,直播地址:https://segmentfault.com/l/15...誤解
代碼:https://github.com/zhoumengka...
整個(gè)項(xiàng)目我們我又細(xì)分了6個(gè)版本來(lái)演進(jìn),希望更加便于大家對(duì)比學(xué)習(xí)。
我在收集大家是否愿意學(xué)習(xí) java 的時(shí)候,得到了如下反饋:
java == 太復(fù)雜 java == 各種亂七八糟的配置 java == 面向 ide 編程
其實(shí)我們?cè)趯W(xué)習(xí)的時(shí)候 java 的時(shí)候完全不用接觸那些高大上的工具,也可以盡量減少各種配置文件,比如下面我們只有個(gè)pom.xml配置文件。
還有的同學(xué)說(shuō)還學(xué) java 干嘛,不都應(yīng)該去學(xué) go 嗎?其實(shí)語(yǔ)言真的不重要,我們需要掌握的是快速學(xué)習(xí)利用一門語(yǔ)言的學(xué)習(xí)方法,這也是本課的真正目的。
就像盲人摸象一樣,他要想弄清楚大象的真實(shí)面貌可能要摸很久,就好比我們拿著放大鏡在學(xué)習(xí) java 一樣,java 經(jīng)過(guò)這么多年的發(fā)展,可以說(shuō)非常龐大。如果我們要知道大象長(zhǎng)什么樣,就應(yīng)該放下手中的放大鏡,向后退遠(yuǎn)點(diǎn),反而能夠非常清晰的看到它的全貌。學(xué)習(xí)一門新的語(yǔ)言也一樣,有很多很多網(wǎng)上的教程,非常的大而全,一般得系統(tǒng)的學(xué)習(xí)30~60小時(shí)之后才能正式的接觸項(xiàng)目開發(fā)。基礎(chǔ)很重要,但是學(xué)習(xí)了太多的基礎(chǔ)會(huì)讓大家失去學(xué)習(xí)的樂趣和自信心。很多知識(shí)點(diǎn)其實(shí)可以項(xiàng)目之后再補(bǔ)。按需去學(xué),反而是自我驅(qū)動(dòng)著去學(xué)習(xí)的最佳方式。
比如 hashmap 的哈希分布、哈希碰撞、動(dòng)態(tài)擴(kuò)容,這些都是我們后期深入提高需要理解的內(nèi)容,初期,我們只需要知道能拿 hashmap 做什么就行。
以實(shí)現(xiàn)自己熟悉的東西為導(dǎo)向比如我們做 Web 后端 api 開發(fā),首先是常用的循環(huán)/迭代、條件判斷、增刪改成。那么能不能快速用 java 實(shí)現(xiàn)一遍這些我們用 php 做起來(lái)非常順手的事呢?
這樣有助于我們快速提升自信心。
PHP 里如何實(shí)現(xiàn),重新用 java 實(shí)現(xiàn)一遍就行了。
最后深入系統(tǒng)的學(xué)習(xí)當(dāng)自己實(shí)現(xiàn)了一些小 demo 再去參考別人的項(xiàng)目。如果一開始就直接看別人的項(xiàng)目,可能完全不知道別人在干嘛。比如別人用了ConcurrentHashMap,就再去思考為什么我用HashMap他卻用ConcurrentHashMap,帶著問題,帶著思考去看開源代碼。
完成了一些簡(jiǎn)單的項(xiàng)目了之后就可以再回過(guò)頭來(lái)系統(tǒng)的學(xué)習(xí)了。這時(shí)候就會(huì)有不一樣的收獲。
最后就是當(dāng)項(xiàng)目需要調(diào)優(yōu),性能提升的時(shí)候,再各個(gè)擊破,深入學(xué)習(xí),更有針對(duì)性,更有目標(biāo)性。
實(shí)戰(zhàn)開始我們用 netty 來(lái)提供高性能的 web 服務(wù)服務(wù)。使用簡(jiǎn)單方便(netty 并不簡(jiǎn)單),不依賴其他軟件。然后思考完成一個(gè)簡(jiǎn)單的 web api 服務(wù)器需要哪些必不可少的組成部分。(其實(shí)在思考這的時(shí)候,你必須要要對(duì)做簡(jiǎn)單的架構(gòu)必須熟記于心)。
我簡(jiǎn)單概括了下:
java 基礎(chǔ)數(shù)據(jù)類型(php 也有,不怕)
java 集合框架(php 有數(shù)組,很強(qiáng)大)
初識(shí) maven(php 有 composer)
反射 (框架路由等地方要用到,php 也有)
序列化(數(shù)據(jù)傳輸要用到,php 沒有復(fù)雜的數(shù)據(jù)結(jié)構(gòu)要簡(jiǎn)單 N 倍)
jdbc (數(shù)據(jù)庫(kù)操作要用到,php 有 pdo)
大概認(rèn)識(shí)泛型、注解等語(yǔ)法 (可選)
使用 netty 實(shí)戰(zhàn)開發(fā)一個(gè) web api 服務(wù)(php 有 swoole)
Java 基本的數(shù)據(jù)結(jié)構(gòu)、各種基本數(shù)據(jù)類型包裝類 Java - Collections Framework 高頻類舉例HashSet 是一個(gè)沒有重復(fù)元素的集合。它是由HashMap實(shí)現(xiàn)的,不保證元素的順序,也就是說(shuō)所說(shuō)元素插入的順序與輸出的順序不一致。這其實(shí)是我的老朋友了,redis 里經(jīng)常用,比如咱們可以它來(lái)實(shí)現(xiàn)一個(gè)黑名單,這樣查找的速度就非???,也不用去遠(yuǎn)程查詢 redis 了,直接在當(dāng)前內(nèi)存中查詢。
ArrayList 基于數(shù)組來(lái)實(shí)現(xiàn)集合的功能,其內(nèi)部維護(hù)了一個(gè)可變長(zhǎng)的對(duì)象數(shù)組,集合內(nèi)所有對(duì)象存儲(chǔ)于這個(gè)數(shù)組中,并實(shí)現(xiàn)該數(shù)組長(zhǎng)度的動(dòng)態(tài)伸縮。
這不就是我們的 PHP 里面常用的索引數(shù)組么?
HashMap 以哈希表數(shù)據(jù)結(jié)構(gòu)實(shí)現(xiàn),查找對(duì)象時(shí)通過(guò)哈希函數(shù)計(jì)算其位置,它是為快速查詢而設(shè)計(jì)的。特點(diǎn)就是快,非線程安全。
這不就是我們的 PHP 里面常用的關(guān)聯(lián)數(shù)組么?
http://www.cnblogs.com/ITtang...
http://www.jianshu.com/p/b54f...
http://www.cnblogs.com/xiaoxi...
Maven的基本原理很簡(jiǎn)單,采用遠(yuǎn)程倉(cāng)庫(kù)和本地倉(cāng)庫(kù)以及一個(gè)核心的配置文件pom.xml,pom.xml中定義的jar文件從遠(yuǎn)程倉(cāng)庫(kù)下載到本地倉(cāng)庫(kù),各個(gè)項(xiàng)目使用同一個(gè)本地倉(cāng)庫(kù)的jar,同一個(gè)版本的jar只需下載一次,而且避免每個(gè)應(yīng)用都去拷貝jar。
這和 php 的包管理工具 composer 很像,或者是 composer 是參考著 maven 而設(shè)計(jì)的。maven 的功能更強(qiáng)大,composer 需要每個(gè)項(xiàng)目都要導(dǎo)入一遍,maven 卻像 git 一樣,有一個(gè)本地倉(cāng)庫(kù),第三方包也不會(huì)直接引用到項(xiàng)目中,而是在編譯的時(shí)候才會(huì)引入(是不是很方便)。另一方面,maven 不僅僅是包管理工具,而且是一個(gè)項(xiàng)目管理工具,集成了編譯、打包、單元測(cè)試等功能。
下面是最簡(jiǎn)單的一個(gè)演示,依賴了 netty 、junit 兩個(gè)包。然后使用maven-compiler-plugin指定了編譯時(shí)候的版本規(guī)則。
v1.0 構(gòu)建 http web 服務(wù)器4.0.0 mengkang.net demo 1.0-SNAPSHOT io.netty netty-all 5.0.0.Alpha2 junit junit 4.7 test org.apache.maven.plugins maven-compiler-plugin 2.3.2 1.8 1.8 UTF-8
我復(fù)制了 netty 官方的 demo 地址如下:
https://github.com/zhoumengkang/netty-http-demo/tree/v1.0
當(dāng)我們運(yùn)行api.mengkang.net.netty.HttpServer.main方法,服務(wù)器就跑起來(lái)了,當(dāng)在瀏覽器里訪問 http://localhost:9009/ 就會(huì)返回Hello World。
方法 | 用途 |
---|---|
api.mengkang.net.netty.HttpServer#main | 服務(wù)器啟動(dòng)的入口 |
api.mengkang.net.netty.HttpServerInitializer#initChannel | 初始化 Channel |
api.mengkang.net.netty.HttpServerHandler#channelRead | 進(jìn)行網(wǎng)絡(luò) I/O |
這是第一步,netty 這里就充當(dāng)了一個(gè) web server 的角色。而我們就可以直接在 netty 提供的接口的基礎(chǔ)上做編程,而不需要想 nginx + php-fpm 還需要一次反向代理,性能高了許多。(swoole 的方式就很像 netty 了)。
v2.0 實(shí)現(xiàn)控制器的訪問具體需求:提供一個(gè) api 可以用戶指定用戶的信息
定義接口:
http://localhost:10000/users/{id} http://localhost:10000/?method=user.get&id={id}
可能現(xiàn)在大家早已習(xí)慣了前者 restful 的 api 接口。
因?yàn)檫@里需要一次路由的映射和 http method 的匹配,考慮到學(xué)習(xí)的成本呢,我沒有選擇這種方式。
我們今天的目標(biāo)是以最簡(jiǎn)單有效的方式實(shí)現(xiàn)我們的功能。
我們首先從最簡(jiǎn)單的方式來(lái)實(shí)現(xiàn)(其實(shí)沒有路由的 api 反而是最快的,畢竟需要做的判斷少嘛)。
后面大家有興趣可以參考我寫的一個(gè) restful api 的 demo netty-restful-server
具體代碼
https://github.com/zhoumengkang/netty-http-demo/tree/v2.0
這一版本中做一個(gè)過(guò)渡版本,暫時(shí)控制器還不解析過(guò)多的參數(shù)。只完成一個(gè)$_GET["method"]參數(shù)的解析。
主要的任務(wù)是通過(guò)獲取的$_GET["method"]去執(zhí)行UserController里面的get方法。
方法 | 用途 |
---|---|
api.mengkang.net.RequestHandler#response | 從 HttpServerHandler 處接管網(wǎng)絡(luò)請(qǐng)求 |
api.mengkang.net.RequestHandler#invoke | 執(zhí)行反射調(diào)用 |
api.mengkang.net.api.UserController#get | 模擬輸出一個(gè)用戶的信息 |
Class> classname; Method methodName; Object result = null; classname = Class.forName("api.mengkang.net.api." + clazz + "Controller"); Object inst = classname.newInstance(); methodName = classname.getMethod(function); result = methodName.invoke(inst);v3.0 解析請(qǐng)求參數(shù)
具體代碼
https://github.com/zhoumengkang/netty-http-demo/tree/v3.0
方法 | 用途 |
---|---|
api.mengkang.net.Request | 封裝一個(gè)通用 api 請(qǐng)求對(duì)象,包含客戶端請(qǐng)求的$_GET,$_POST,ip 等 |
api.mengkang.net.RequestHandler#requestFetch | 把請(qǐng)求解析成 api.mengkang.net.Request 對(duì)象 |
api.mengkang.net.RequestHandler#invoke | 把 api.mengkang.net.Request 傳遞給 Controller |
反射實(shí)例化對(duì)象使用了構(gòu)造函數(shù) ,這樣就把請(qǐng)求的對(duì)象Request實(shí)例傳到 Controller 中去了。Controller 中的方法就能取到$_GET,$_POST,以及類似 php://input 的數(shù)據(jù)了。
Class> classname; Object classObject; Constructor constructor; Method methodName; Object result = null; classname = Class.forName("api.mengkang.net.api." + clazz + "Controller"); constructor = classname.getConstructor(Request.class); classObject = constructor.newInstance(request); methodName = classname.getMethod(function); result = methodName.invoke(classObject);v3.1 完善返回體信息
具體代碼
https://github.com/zhoumengkang/netty-http-demo/tree/v3.1
類 | 用途 |
---|---|
api.mengkang.net.Response | 封裝一個(gè)通用 api 響應(yīng)對(duì)象 |
api.mengkang.net.ErrorCode | 錯(cuò)誤代碼統(tǒng)一規(guī)范起來(lái) |
api.mengkang.net.netty.HttpServerHandler | http 頭信息 改為 json |
這樣就更像一個(gè)正規(guī)的 api 服務(wù)了。
v4.0 構(gòu)建 User 對(duì)象增加 User 對(duì)象, 增加 UserModel 來(lái)處理 User 對(duì)象的返回, 完善了錯(cuò)誤返回機(jī)制.
類 | 用途 |
---|---|
api.mengkang.net.entity.User | 描述用戶對(duì)象,用于user.get接口的數(shù)據(jù)返回 |
api.mengkang.net.model.UserModel | 供UserController調(diào)用,簡(jiǎn)單分層 |
api.mengkang.net.ErrorCode | 完善了錯(cuò)誤類型 |
api.mengkang.net.api.UserController | 完善了錯(cuò)誤類型的判斷,返回給前端錯(cuò)誤更友好 |
類 | 用途 |
---|---|
api/mengkang/net/utils/mysql | 新增自己封裝的簡(jiǎn)單的數(shù)據(jù)連接池的操作工具 |
api.mengkang.net.dao.UserDao | 做數(shù)據(jù)庫(kù)連接的查詢,返回給UserModel |
中間引入三個(gè)包,來(lái)做數(shù)據(jù)庫(kù)的查詢和數(shù)據(jù)庫(kù)的連接池
mysql mysql-connector-java 5.1.18 commons-dbcp commons-dbcp 1.4 commons-pool commons-pool 1.6
最后整個(gè)項(xiàng)目結(jié)構(gòu)如下
├── main │?? ├── java │?? │?? └── api │?? │?? └── mengkang │?? │?? └── net │?? │?? ├── Config.java │?? │?? ├── ErrorCode.java │?? │?? ├── Request.java │?? │?? ├── RequestHandler.java │?? │?? ├── Response.java │?? │?? ├── api │?? │?? │?? ├── BaseController.java │?? │?? │?? └── UserController.java │?? │?? ├── dao │?? │?? │?? └── UserDao.java │?? │?? ├── entity │?? │?? │?? └── User.java │?? │?? ├── model │?? │?? │?? └── UserModel.java │?? │?? ├── netty │?? │?? │?? ├── HttpServer.java │?? │?? │?? ├── HttpServerHandler.java │?? │?? │?? └── HttpServerInitializer.java │?? │?? └── utils │?? │?? └── mysql │?? │?? ├── DMLTypes.java │?? │?? ├── DbFiled.java │?? │?? ├── JdbcPool.java │?? │?? ├── MySelect.java │?? │?? └── Mysql.java │?? └── resources │?? ├── api.properties │?? ├── read.db.properties │?? └── write.db.properties
文章版權(quán)歸作者所有,未經(jīng)允許請(qǐng)勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。
轉(zhuǎn)載請(qǐng)注明本文地址:http://m.hztianpu.com/yun/67484.html
摘要:以實(shí)現(xiàn)自己熟悉的東西為導(dǎo)向比如我們做后端開發(fā),首先是常用的循環(huán)迭代條件判斷增刪改成。它是由實(shí)現(xiàn)的,不保證元素的順序,也就是說(shuō)所說(shuō)元素插入的順序與輸出的順序不一致。 下面是我直播的文字版,直播地址:https://segmentfault.com/l/15...代碼:https://github.com/zhoumengka...整個(gè)項(xiàng)目我們我又細(xì)分了6個(gè)版本來(lái)演進(jìn),希望更加便于大家對(duì)比...
摘要:下面一起學(xué)習(xí)下鳥哥的框架。揭開神秘面紗采用客戶端服務(wù)器模式。在服務(wù)器端,進(jìn)程保持睡眠狀態(tài)直到調(diào)用信息的到達(dá)為止。這和我們外網(wǎng)的原理不都一個(gè)樣么那么我們一起看看高大上的是怎么在玩。整個(gè)傳輸以二進(jìn)制流的形式傳送。 各位老鐵在點(diǎn)贊、收藏的時(shí)候敢不敢報(bào)名小弟的直播分享,絕對(duì)有干貨,絕對(duì)有驚喜!一次早餐錢的投入,可能是薪資的翻倍,可能是視野的拓展! PHP 進(jìn)階之路 - 億級(jí) pv 網(wǎng)站架構(gòu)...
摘要:去年年底因?yàn)槭褂昧嗽拼鎯?chǔ)和其他方面的原因,計(jì)劃的將服務(wù)器縮減一個(gè)機(jī)柜出來(lái)。云服務(wù)的回源服務(wù)器的配置中間漏了一臺(tái),后期給補(bǔ)上了。監(jiān)控遷移完畢之后,除了常規(guī)的業(yè)務(wù)代碼,還需要注意圖片資源的回源是否正常服務(wù)器壓力是否正常檢查日志是否出現(xiàn)錯(cuò)誤。 去年年底因?yàn)槭褂昧嗽拼鎯?chǔ)和其他方面的原因,計(jì)劃的將服務(wù)器縮減一個(gè)機(jī)柜出來(lái)。這樣今年每月機(jī)房的費(fèi)用可以減少1萬(wàn)左右。前前后后抽空在弄這個(gè)任務(wù),現(xiàn)做個(gè)筆記...
摘要:唯一的知識(shí)點(diǎn)就是的基礎(chǔ)使用。可以簡(jiǎn)單的理解下面的代碼就構(gòu)建了一個(gè)服務(wù)器。握手完成之后的消息傳遞則在中處理。實(shí)際情況下,不可能那么多人同時(shí)說(shuō)話廣播,而是說(shuō)話的人少,接受廣播的人多。 硬廣一波 SF 官方首頁(yè)推薦《PHP進(jìn)階之路》(你又多久沒有投資自己了?先看后買) 我們下面則將一些實(shí)際場(chǎng)景都添加進(jìn)去,比如用戶身份的驗(yàn)證,游客只能瀏覽不能發(fā)言,多房間(頻道)的聊天。該博客非常適合 Java...
摘要:如果現(xiàn)有子進(jìn)程中的線程總數(shù)不能滿足負(fù)載,控制進(jìn)程將派生新的子進(jìn)程。為解決線程的并發(fā)問題,引入了線程安全資源管理器。的全拼,用來(lái)存放各個(gè)線程的鏈表。 PHP 進(jìn)階之路 - 零基礎(chǔ)構(gòu)建自己的服務(wù)治理框架(上) PHP 進(jìn)階之路 - 零基礎(chǔ)構(gòu)建自己的服務(wù)治理框架(下) PHP 進(jìn)階之路 - 億級(jí) pv 網(wǎng)站架構(gòu)的技術(shù)細(xì)節(jié)與套路 PHP 進(jìn)階之路 - 億級(jí) pv 網(wǎng)站架構(gòu)實(shí)戰(zhàn)之性能壓榨 注...
閱讀 2460·2021-11-23 09:51
閱讀 2061·2021-10-14 09:43
閱讀 2846·2021-09-27 13:35
閱讀 1225·2021-09-22 15:54
閱讀 2608·2021-09-13 10:36
閱讀 3961·2019-08-30 15:56
閱讀 3485·2019-08-30 14:09
閱讀 1801·2019-08-30 12:57