资讯专栏INFORMATION COLUMN

PHP 进阶之路 - 后端多元化之快速切入 Java 开发

Cristic / 2682人阅读

摘要:以实现自己熟悉的东西为导向比如我们做后端开发,首先是常用的循环迭代条件判断增删改成。它是由实现的,不保证元素的顺序,也就是说所说元素插入的顺序与输出的顺序不一致。

下面是我直播的文字版,直播地址:https://segmentfault.com/l/15...
代码:https://github.com/zhoumengka...
整个项目我们我又细分了6个版本来演进,希望更加便于大家对比学习。
误解

我在收集大家是否愿意学习 java 的时候,得到了如下反馈:

java == 太复杂
java == 各种乱七八糟的配置
java == 面向 ide 编程

其实我们在学习的时候 java 的时候完全不用接触那些高大上的工具,也可以尽量减少各种配置文件,比如下面我们只有个pom.xml配置文件。
还有的同学说还学 java 干嘛,不都应该去学 go 吗?其实语言真的不重要,我们需要掌握的是快速学习利用一门语言的学习方法,这也是本课的真正目的。

入门不要拿着放大镜去学

就像盲人摸象一样,他要想弄清楚大象的真实面貌可能要摸很久,就好比我们拿着放大镜在学习 java 一样,java 经过这么多年的发展,可以说非常庞大。如果我们要知道大象长什么样,就应该放下手中的放大镜,向后退远点,反而能够非常清晰的看到它的全貌。学习一门新的语言也一样,有很多很多网上的教程,非常的大而全,一般得系统的学习30~60小时之后才能正式的接触项目开发。基础很重要,但是学习了太多的基础会让大家失去学习的乐趣和自信心。很多知识点其实可以项目之后再补。按需去学,反而是自我驱动着去学习的最佳方式。

比如 hashmap 的哈希分布、哈希碰撞、动态扩容,这些都是我们后期深入提高需要理解的内容,初期,我们只需要知道能拿 hashmap 做什么就行。

以实现自己熟悉的东西为导向

比如我们做 Web 后端 api 开发,首先是常用的循环/迭代、条件判断、增删改成。那么能不能快速用 java 实现一遍这些我们用 php 做起来非常顺手的事呢?
这样有助于我们快速提升自信心。

使用类比的学习方法

PHP 里如何实现,重新用 java 实现一遍就行了。

最后深入系统的学习

当自己实现了一些小 demo 再去参考别人的项目。如果一开始就直接看别人的项目,可能完全不知道别人在干嘛。比如别人用了ConcurrentHashMap,就再去思考为什么我用HashMap他却用ConcurrentHashMap,带着问题,带着思考去看开源代码。

完成了一些简单的项目了之后就可以再回过头来系统的学习了。这时候就会有不一样的收获。

最后就是当项目需要调优,性能提升的时候,再各个击破,深入学习,更有针对性,更有目标性。

实战开始

我们用 netty 来提供高性能的 web 服务服务。使用简单方便(netty 并不简单),不依赖其他软件。然后思考完成一个简单的 web api 服务器需要哪些必不可少的组成部分。(其实在思考这的时候,你必须要要对做简单的架构必须熟记于心)。

我简单概括了下:

java 基础数据类型(php 也有,不怕)

java 集合框架(php 有数组,很强大)

初识 maven(php 有 composer)

反射 (框架路由等地方要用到,php 也有)

序列化(数据传输要用到,php 没有复杂的数据结构要简单 N 倍)

jdbc (数据库操作要用到,php 有 pdo)

大概认识泛型、注解等语法 (可选)

使用 netty 实战开发一个 web api 服务(php 有 swoole)

Java 基本的数据结构、各种基本数据类型包装类

Java - Collections Framework 高频类举例

HashSet 是一个没有重复元素的集合。它是由HashMap实现的,不保证元素的顺序,也就是说所说元素插入的顺序与输出的顺序不一致。

这其实是我的老朋友了,redis 里经常用,比如咱们可以它来实现一个黑名单,这样查找的速度就非常快,也不用去远程查询 redis 了,直接在当前内存中查询。

ArrayList 基于数组来实现集合的功能,其内部维护了一个可变长的对象数组,集合内所有对象存储于这个数组中,并实现该数组长度的动态伸缩。

这不就是我们的 PHP 里面常用的索引数组么?

HashMap 以哈希表数据结构实现,查找对象时通过哈希函数计算其位置,它是为快速查询而设计的。特点就是快,非线程安全。

这不就是我们的 PHP 里面常用的关联数组么?

http://www.cnblogs.com/ITtang...
http://www.jianshu.com/p/b54f...
http://www.cnblogs.com/xiaoxi...

初识 maven

Maven的基本原理很简单,采用远程仓库和本地仓库以及一个核心的配置文件pom.xml,pom.xml中定义的jar文件从远程仓库下载到本地仓库,各个项目使用同一个本地仓库的jar,同一个版本的jar只需下载一次,而且避免每个应用都去拷贝jar。

这和 php 的包管理工具 composer 很像,或者是 composer 是参考着 maven 而设计的。maven 的功能更强大,composer 需要每个项目都要导入一遍,maven 却像 git 一样,有一个本地仓库,第三方包也不会直接引用到项目中,而是在编译的时候才会引入(是不是很方便)。另一方面,maven 不仅仅是包管理工具,而且是一个项目管理工具,集成了编译、打包、单元测试等功能。

下面是最简单的一个演示,依赖了 netty 、junit 两个包。然后使用maven-compiler-plugin指定了编译时候的版本规则。



    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
                
            
        
    

v1.0 构建 http web 服务器

我复制了 netty 官方的 demo 地址如下:

https://github.com/zhoumengkang/netty-http-demo/tree/v1.0

当我们运行api.mengkang.net.netty.HttpServer.main方法,服务器就跑起来了,当在浏览器里访问 http://localhost:9009/ 就会返回Hello World

方法 用途
api.mengkang.net.netty.HttpServer#main 服务器启动的入口
api.mengkang.net.netty.HttpServerInitializer#initChannel 初始化 Channel
api.mengkang.net.netty.HttpServerHandler#channelRead 进行网络 I/O

这是第一步,netty 这里就充当了一个 web server 的角色。而我们就可以直接在 netty 提供的接口的基础上做编程,而不需要想 nginx + php-fpm 还需要一次反向代理,性能高了许多。(swoole 的方式就很像 netty 了)。

v2.0 实现控制器的访问

具体需求:提供一个 api 可以用户指定用户的信息
定义接口:

http://localhost:10000/users/{id}
http://localhost:10000/?method=user.get&id={id}

可能现在大家早已习惯了前者 restful 的 api 接口。
因为这里需要一次路由的映射和 http method 的匹配,考虑到学习的成本呢,我没有选择这种方式。
我们今天的目标是以最简单有效的方式实现我们的功能。
我们首先从最简单的方式来实现(其实没有路由的 api 反而是最快的,毕竟需要做的判断少嘛)。
后面大家有兴趣可以参考我写的一个 restful api 的 demo netty-restful-server

具体代码

https://github.com/zhoumengkang/netty-http-demo/tree/v2.0

这一版本中做一个过渡版本,暂时控制器还不解析过多的参数。只完成一个$_GET["method"]参数的解析。
主要的任务是通过获取的$_GET["method"]去执行UserController里面的get方法。

方法 用途
api.mengkang.net.RequestHandler#response HttpServerHandler 处接管网络请求
api.mengkang.net.RequestHandler#invoke 执行反射调用
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 解析请求参数

具体代码

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

反射实例化对象使用了构造函数 ,这样就把请求的对象Request实例传到 Controller 中去了。Controller 中的方法就能取到$_GET,$_POST,以及类似 php://input 的数据了。

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 响应对象
api.mengkang.net.ErrorCode 错误代码统一规范起来
api.mengkang.net.netty.HttpServerHandler http 头信息 改为 json

这样就更像一个正规的 api 服务了。

v4.0 构建 User 对象

增加 User 对象, 增加 UserModel 来处理 User 对象的返回, 完善了错误返回机制.

用途
api.mengkang.net.entity.User 描述用户对象,用于user.get接口的数据返回
api.mengkang.net.model.UserModel UserController调用,简单分层
api.mengkang.net.ErrorCode 完善了错误类型
api.mengkang.net.api.UserController 完善了错误类型的判断,返回给前端错误更友好
v5.0 使用数据库动态查询
用途
api/mengkang/net/utils/mysql 新增自己封装的简单的数据连接池的操作工具
api.mengkang.net.dao.UserDao 做数据库连接的查询,返回给UserModel

中间引入三个包,来做数据库的查询和数据库的连接池


    mysql
    mysql-connector-java
    5.1.18


    commons-dbcp
    commons-dbcp
    1.4


    commons-pool
    commons-pool
    1.6

最后整个项目结构如下

├── 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

文章版权归作者所有,未经允许请勿转载,若此文章存在违规行为,您可以联系管理员删除。

转载请注明本文地址:https://www.ucloud.cn/yun/67484.html

相关文章

  • PHP 进阶 - 后端元化快速切入 Java 开发

    摘要:以实现自己熟悉的东西为导向比如我们做后端开发,首先是常用的循环迭代条件判断增删改成。它是由实现的,不保证元素的顺序,也就是说所说元素插入的顺序与输出的顺序不一致。 下面是我直播的文字版,直播地址:https://segmentfault.com/l/15...代码:https://github.com/zhoumengka...整个项目我们我又细分了6个版本来演进,希望更加便于大家对比...

    xi4oh4o 评论0 收藏0
  • PHP 教父鸟哥 Yar 的原理分析

    摘要:下面一起学习下鸟哥的框架。揭开神秘面纱采用客户端服务器模式。在服务器端,进程保持睡眠状态直到调用信息的到达为止。这和我们外网的原理不都一个样么那么我们一起看看高大上的是怎么在玩。整个传输以二进制流的形式传送。 各位老铁在点赞、收藏的时候敢不敢报名小弟的直播分享,绝对有干货,绝对有惊喜!一次早餐钱的投入,可能是薪资的翻倍,可能是视野的拓展! PHP 进阶之路 - 亿级 pv 网站架构...

    B0B0 评论0 收藏0
  • 我的服务器迁移踩坑经验分享

    摘要:去年年底因为使用了云存储和其他方面的原因,计划的将服务器缩减一个机柜出来。云服务的回源服务器的配置中间漏了一台,后期给补上了。监控迁移完毕之后,除了常规的业务代码,还需要注意图片资源的回源是否正常服务器压力是否正常检查日志是否出现错误。 去年年底因为使用了云存储和其他方面的原因,计划的将服务器缩减一个机柜出来。这样今年每月机房的费用可以减少1万左右。前前后后抽空在弄这个任务,现做个笔记...

    Developer 评论0 收藏0
  • PHP 程序员也能做的 Java 开发 30分钟使用 netty 轻松打造一个高性能 websock

    摘要:唯一的知识点就是的基础使用。可以简单的理解下面的代码就构建了一个服务器。握手完成之后的消息传递则在中处理。实际情况下,不可能那么多人同时说话广播,而是说话的人少,接受广播的人多。 硬广一波 SF 官方首页推荐《PHP进阶之路》(你又多久没有投资自己了?先看后买) 我们下面则将一些实际场景都添加进去,比如用户身份的验证,游客只能浏览不能发言,多房间(频道)的聊天。该博客非常适合 Java...

    kviccn 评论0 收藏0
  • PHP 进阶 - 揭开 PHP 线程安全的神秘面纱

    摘要:如果现有子进程中的线程总数不能满足负载,控制进程将派生新的子进程。为解决线程的并发问题,引入了线程安全资源管理器。的全拼,用来存放各个线程的链表。 PHP 进阶之路 - 零基础构建自己的服务治理框架(上) PHP 进阶之路 - 零基础构建自己的服务治理框架(下) PHP 进阶之路 - 亿级 pv 网站架构的技术细节与套路 PHP 进阶之路 - 亿级 pv 网站架构实战之性能压榨 注...

    pepperwang 评论0 收藏0

发表评论

0条评论

最新活动
阅读需要支付1元查看
<