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