热门标签 | HotTags
当前位置:  开发笔记 > 编程语言 > 正文

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

下面是我直播的文字版,直播地址:https:segmentfault.coml15代码:https:github.comzhoume
下面是我直播的文字版,直播地址: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 服务器需要哪些必不可少的组成部分。(其实在思考这的时候,你必须要要对做简单的架构必须熟记于心)。

我简单概括了下:

  1. java 基础数据类型(php 也有,不怕)
  2. java 集合框架(php 有数组,很强大)
  3. 初识 maven(php 有 composer)
  4. 反射 (框架路由等地方要用到,php 也有)
  5. 序列化(数据传输要用到,php 没有复杂的数据结构要简单 N 倍)
  6. jdbc (数据库操作要用到,php 有 pdo)
  7. 大概认识泛型、注解等语法 (可选)
  8. 使用 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.0mengkang.netdemo1.0-SNAPSHOTio.nettynetty-all5.0.0.Alpha2junitjunit4.7testorg.apache.maven.pluginsmaven-compiler-plugin2.3.21.81.8UTF-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#responseHttpServerHandler 处接管网络请求
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#invokeapi.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.HttpServerHandlerhttp 头信息 改为 json

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

v4.0 构建 User 对象

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

用途
api.mengkang.net.entity.User描述用户对象,用于user.get接口的数据返回
api.mengkang.net.model.UserModelUserController调用,简单分层
api.mengkang.net.ErrorCode完善了错误类型
api.mengkang.net.api.UserController完善了错误类型的判断,返回给前端错误更友好

v5.0 使用数据库动态查询

用途
api/mengkang/net/utils/mysql新增自己封装的简单的数据连接池的操作工具
api.mengkang.net.dao.UserDao做数据库连接的查询,返回给UserModel

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

mysqlmysql-connector-java5.1.18

commons-dbcpcommons-dbcp1.4

commons-poolcommons-pool1.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



推荐阅读
  • 本文介绍了如何使用Java编程语言实现凯撒密码的加密与解密功能。凯撒密码是一种替换式密码,通过将字母表中的每个字母向前或向后移动固定数量的位置来实现加密。 ... [详细]
  • 雨林木风 GHOST XP SP3 经典珍藏版 YN2014.04
    雨林木风 GHOST XP SP3 经典珍藏版 YN2014.04 ... [详细]
  • 使用 ModelAttribute 实现页面数据自动填充
    本文介绍了如何利用 Spring MVC 中的 ModelAttribute 注解,在页面跳转后自动填充表单数据。主要探讨了两种实现方法及其背后的原理。 ... [详细]
  • 本文探讨了在 PHP 的 Zend 框架下,使用 PHPUnit 进行单元测试时遇到的 Zend_Controller_Response_Exception 错误,并提供了解决方案。 ... [详细]
  • 本文探讨了Android系统中联系人数据库的设计,特别是AbstractContactsProvider类的作用与实现。文章提供了对源代码的详细分析,并解释了该类如何支持跨数据库操作及事务处理。源代码可从官方Android网站下载。 ... [详细]
  • 深入理解Java字节码:方法调用详解
    本文详细介绍了Java字节码中的方法调用机制,通过具体示例解析了字节码如何处理方法调用及其参数传递。文章由Mahmoud Anouti撰写,原文链接:https://dzone.com/articles/introduction-to-java-bytecode ... [详细]
  • 本文探讨了如何在Angular项目中处理URL重写时遇到的参数缺失问题,并提供了一种有效的解决方案。 ... [详细]
  • 本文详细介绍了PHP中的几种超全局变量,包括$GLOBAL、$_SERVER、$_POST、$_GET等,并探讨了AJAX的工作原理及其优缺点。通过具体示例,帮助读者更好地理解和应用这些技术。 ... [详细]
  • 本文详细介绍了在PHP中如何获取和处理HTTP头部信息,包括通过cURL获取请求头信息、使用header函数发送响应头以及获取客户端HTTP头部的方法。同时,还探讨了PHP中$_SERVER变量的使用,以获取客户端和服务器的相关信息。 ... [详细]
  • 本文详细介绍了在MyBatis框架中如何通过#和$两种方式来传递SQL查询参数。使用#方式可以提高执行效率,而使用$则有助于在复杂SQL语句中更好地查看日志。此外,文章还探讨了不同场景下的参数传递方法,包括实体对象、基本数据类型以及混合参数的使用。 ... [详细]
  • java datarow_DataSet  DataTable DataRow 深入浅出
    本篇文章适合有一定的基础的人去查看,最好学习过一定net编程基础在来查看此文章。1.概念DataSet是ADO.NET的中心概念。可以把DataSet当成内存中的数据 ... [详细]
  • 使用 Babylon.js 实现地球模型与切片地图交互(第三部分)
    本文继续探讨在上一章节中构建的地球模型基础上,如何通过自定义的 `CameraEarthWheelControl` 类来实现更精细的地图缩放控制。我们将深入解析该类的实现细节,并展示其在实际项目中的应用。 ... [详细]
  • 本文探讨了在Eclipse中进行JavaScript验证时遇到的时间过长问题,并提供了解决方法。特别是对于使用ExtJS框架的用户,这一问题尤为突出。文章详细介绍了如何通过修改项目配置文件来有效解决这一问题。 ... [详细]
  • 宝塔面板下启用HTTPS的详细指南
    本文提供了在宝塔面板环境中配置HTTPS的具体步骤,确保您的网站通信更加安全可靠。 ... [详细]
  • 探讨多种方法来确定Java对象的实际类型,包括使用instanceof关键字、getClass()方法等。 ... [详细]
author-avatar
黄志琴文菱
这个家伙很懒,什么也没留下!
PHP1.CN | 中国最专业的PHP中文社区 | DevBox开发工具箱 | json解析格式化 |PHP资讯 | PHP教程 | 数据库技术 | 服务器技术 | 前端开发技术 | PHP框架 | 开发工具 | 在线工具
Copyright © 1998 - 2020 PHP1.CN. All Rights Reserved | 京公网安备 11010802041100号 | 京ICP备19059560号-4 | PHP1.CN 第一PHP社区 版权所有