《Java应该这么学》
《Java应该这么学》课程体系
第一节下载搭建第一个Web工程
第二节下载表单提交数据到Servlet
第三节下载容错处理,在线算命,如何实现提交页和展示页类似,理解http工作机制
第四节下载Java的基本知识和数据结构的基本应用,键-值对,使用数组方式实现简繁转换,哈希表与散列算法复习,HashMap使用
第五节下载
1、火星文翻译器https://www.360docs.net/doc/ae4831497.html,/
2、为什么要有Jar(别人不用重新编译、防止泄露源代码、复用)
3、开发自己的JianFan4J,打包成Jar供别人用(自己动手写开源项目,自己动手写类库,用工具的人变成造工具的人)。Static
方法和普通方法的区别,jar文件的导出,。
Java工程导出Jar包的方式:工程上右键,选择“Export”,选择“Java→JarFile”
4、课下作业:开发Huoxingwen4J的开源组件
5、Pinyin4j的使用和原理分析
6、课下作业:自己动手写Pinyin4j(文件处理、字符处理、HashMap,嵌入资源(可以先读取绝对路径的文件))
7、集合:HashSet 集合的特征:数据不重复
HashSet(挑选出重复的人员)
用Set实现从98中选中缺的2个数字这个算法;实现统计字符串中出现的所有字符的算法;
面试、笔试的时候能用最优化算法当然最好,如果想不到最优化算法,就是HashSet、HashMap、List等数据结构来实现,分数也不会很低。想不到好算法仍然拿高分的秘籍!
第六节下载:
1、利用HashMap简化阶乘运算(缓存、缓存命中率),BigInteger的使用
2、统计一篇文章中每个字的出现次数(HashMap的应用)
3、自己动手写模板引擎(文件处理、架构、Map、占位符、字符串处理、LoadFromFile、LoadFromStream)
如有问题,请发帖详细描述问题附代码https://www.360docs.net/doc/ae4831497.html,/forum/forum-37-1.html
《Java应该这么学》第一节
相当一部分时间不会讲太多Web方面的东西,只是把它当成一个展示界面而已。
为什么不用AWT、Swing,Eclipse下没有合适的可视化设计工具。咱们把主要精力放到后端更有差异性的逻辑上,比如JDBC数据库访问、XML解析、Java中反射/面向对象/设计模式等高级特性、Java流、文件处理、网络编程、多线程、数据结构(链表、散列、树、堆栈)算法、编译原理等上,而不是界面上。
将要安排的项目:自己动手写在线Eclipse、自己动手写SQL查询分析器、自己动手写论坛、自己动手写Struts。
为什么不直接上来就学Struts?为了尽可能的不变成代码工人。我在培训机构兼职,遇到很多学生上来Servlet没学过、JSP没学过,上来就学Struts,JDBC没学过、SQL没学过,上来就学Hibernate,只会用Struts、Hibernate这些工具模仿着实现一些固定的功能,一旦涉及到深层次的问题,就一脸茫然。咱们如鹏是避免大家成为代码工人,所以会把很多精力放到这些基础的东西上,可能人家学Struts一天就能做出来很酷的东西,也许你学这些基础的东西一个月也达不到他的效果,但是记住越是容易得到的越不值钱,等到他把Struts玩儿的很熟的时候你已经能自己动手写Struts了,谁能够进入更高档次的高位、拿更多的工资就不言而喻了。
第一个Web程序:用到的Jar下载https://www.360docs.net/doc/ae4831497.html,/download/software/java/jettylib1.zip
搭建第一个Web工程
1、创建一个Java工程,工程下创建一个文件夹lib
2、将jettylib1.zip解压到lib目录下,回到Eclipse刷新一下lib目录
3、在工程MyfirstWeb1上点击右键,选择Property,在打开的对话框中选择JavaBuildPath,切换到Libraries页,点击【Add Jars】,选择所有刚才解压的jar文件。
4、以后给大家提供一些jar包,大家模仿上面的步骤添加就可以。以前没学过加第三方jar。(第三方提供的扩展Java类库的类库,简化开发)
5、在src下新建【package】名字是“com.rupeng”
6、在“com.rupeng”上创建Class“StartServer”
7、添加入口类:
1.package com.rupeng;
2.import org.mortbay.http.SocketListener;
3.import org.mortbay.jetty.Server;
4.import org.mortbay.jetty.servlet.ServletHttpContext;
5.
6.public class StartServer
7.{
8.public static void main(String[] args)
9.{
10.Server server = new Server();
11.try
12.{
13.SocketListener listener = new SocketListener();
14.listener.setPort(80);
15.server.addListener(listener);
16.ServletHttpContext context = (ServletHttpContext)server.addContext("/");
17.server.start();
18.}
19.catch (Exception e)
20.{
21. e.printStackTrace();
22.}
23.}
24.}
所有的Servlet都从HttpServlet继承。
添加从HttpServlet继承的Servlet实现doGet方法
将Servlet添加到Context中
context.addServlet("/test/*", "com.rupeng.TestServlet");
表示用户请求test这个地址的时候由TestServlet来处理,而TestServlet则是doGet方法来处理。
doGet方法中req表示请求、resp表示回应
启动,养成以Debug方式启动的好习惯。
Debug As方式启动的好处:可以设置断点;可以实现代码热替换(每次改完代码以后立即生效,不用重启程序!)Servlet是什么?提供Web显示服务的类。
StartServer是一个包工头,遇到任务的时候会把任务分发给合适的Servlet,所以Servlet就是干活的。
遇到test请求的时候由TestServlet来处理。处理请求的还是方法,doGet方法来处理
Request:接受任务;Response:把任务完成返回
System.out.println(); 是向控制台输出
resp.getOutputStream().println("你好"); 是向浏览器输出
可能遇到的错误:
Address already in use: JVM_Bind 端口被占用
再添加一个长工“HelloServlet”,为什么不重启不行?热替换的前提条件之一是:代码被执行以后才会热替换,只有干活的时候热替换才起作用。
StartServer中main的代码只会执行一次,所以必须重启。
打开:http://127.0.0.1:8080/test
JSP和Servlet的关系是什么。JSP会被编译成Servlet。JSP是C语言、Servlet是汇编语言。Struts是不用写代码的自动生成C语言代码的代码生成器。又学到了一通百通的东西了。
上档次了!弄明白底层,工资非常高!!!
人家不都是开发JavaWeb程序用Tomcat吗?咱们怎么没用?Tomcat只是JavaWeb服务器的一种,JavaWeb服务器就是一个放置Servlet的服务器,Servlet只是一个普通类,用户来了由JavaWeb服务器来调用Servlet,所以JavaWeb 服务器是包工头,StartServer就是一个小型的Tomcat。用Tomcat的话会花在很多时间在环境配置上,也许配置一个礼拜了都运行不起来,很打击自信心,所以我的指导原则是5分钟之内就要能跑起来,所以我采用Jetty来代替Tomcat,具体原理大家现在不用关心,等时机成熟的时候我会像教大家怎样用10分钟从C-Free一通百通到VC一样用10分钟教大家从Jetty一通百通到Tomcat。
下一节课讲表单提交数据到Servlet,对HTML不熟悉的同学请看如鹏网的《自己动手写网站》的视频教程。必须达到手写HTML的水平《自己动手写网站》。
《Java应该这么学》第二节
1、带一个参数的SayHelloServlet
http://127.0.0.1/test?name=kider? 参数名=参数值
getParameter:Parameter(参数)
编辑代码的时候快速保存的快捷键:Ctrl+S
为什么是字符串类型?Http协议本质论。很多直接用Struts的人根本不知道背后发生了什么,发生了很多笑话。
2、带多个参数的AddServlet
Alt+/:自动代码提示
传递多个参数,在各个参数组之间用“&”分割
http://127.0.0.1/love?boy=tom&girl=lily
3、通过HTML页面向Servlet提交数据(不放入工程,直接点击运行)
HTML有头Head、有身体Body
表单:form。Please fill the form。注册、登录都是一种申请,都需要Fill the form。
文本框
提交按钮
action=http://127.0.0.1/love
表示表单要提交给谁处理。否则大街上随便有人给你表单,你填了都不知道给谁
乱码问题,后面的课程
4、Get与Post,如果做到GetPost统一?service。
如果信息太多的话,GET方式URL太长了,浏览器能够处理的URL长度是有限的。
传递文件内容等的时候GET是不可以的。
method="Post"
GET、POST区别之一:能不能在URL里边看到参数的值。
很多公司面试求职的常考题。
Post和get的区别。长度限制、提交的内容。信息隐藏。
学习Web开发就要有手写HTML的能力。Form的action什么意思,input、type。
代码重复了!DRY。Don’t Repeat YourSelf。
以后写Servlet统一都使用service方法,不用doGet、doPost了。
5、如何将HTML融入工程?
addWebApplication("/", "WebContent")
6、实现登录页面(不连接数据库)
7、Add一切都是字符串,转换成数字需要程序员自己处理
课下作业:
1、容错处理:字段为空、非法数字
2、在线算命
《Java应该这么学》第三节
1、容错处理:字段为空、非法数字
NumberFormatException
N1变量的作用域问题。一个变量的作用域是:大括号。变量的初始化。
为什么Eclipse报错是“may not been initialized”。为啥是“可能未初始化”。
Null和空字符串””是不一样的
2、在线算命
3、如何实现提交页面和展示页面类似?
两个页面
Http的特性:无状态!!!服务器不记得上次浏览器提交的内容和返回给浏览器的内容。非常健忘。
判断是直接显示form内容还是提交的处理
自己提交给自己,但是由于Http无状态,笨到自己都不认识自己:
通过这个理解Http的工作机制。代码是运行在服务端的,客户端只负责显示。
把Submit用起来
自己实现PostBack机制,很少有人明白,到了https://www.360docs.net/doc/ae4831497.html,中的IsPostBack。咱们已经很NB了!
下节课安排:
(和Web没有直接关系,是Java的基本知识和数据结构的基本应用)
提前复习《数据结构》中关于散列表和散列算法的内容
用两个数组实现简繁转换。
散列表的应用与散列算法
简繁体翻译功能。
《Java应该这么学》第四节
1、把字典定义为“键-值对”(Key-Value Pair)的集合。
在英汉字典中,英文单词是名字,此单词的中文解释条目是值;在电话簿中,人名是名字,此人名对应的电话号码是值。从字典中查找“键-值对”的最简单方法就是使用数组存储
2、
1.class KeyValue
2.{
3.public key;
4.public value;
5.}
6.
7.KeyValue[] kvArray;
8.String eng[] = new String{"book","computer","money"};
9.String chn[] = new String{"书","电脑","钱"};
10.String s = "北京欢迎你";
11.
12.for(int i=0;i 13.{ 14.System.out.println(s.charAt(i)); 15.} 16. 17.for(int i=0;i 18.{ 19.char ch = text.charAt(i); 20.int pos = charSC.indexOf(ch); 21.char tcCH; 22.if (pos == -1) 23.{ 24.tcCH = ch; 25.} 26.else 27.{ 28.tcCH = charTC.charAt(pos); 29.} 30.System.out.print(tcCH); 31.} O(n*n) 344毫秒 3、使用数组方式实现简繁转换。字典文件:jianfan.txt a) 性能测试:翻译一篇100字的文章。算法计时的方法 4、哈希表与散列算法复习 哈希方法在“键-值对”的存储位置与它的键之间建立一个确定的对应函数关系hash(),就是key向value的换算关系;使得每一个键与结构中的一个唯一的存储位置相对应: 存储位置=hash(键) Value的位置=hash(key) 有一组“键值对”:<5,”tom”>、<8,”Jane”>、<12,”Bit”>、<17,”Lily”>、<20,”sunny”>,我们按照如下哈希函数对键进行计算:hash(x)=x%17+3,得出如下结果:hash(5)=8、hash(8)=11、hash(12)=15、hash(17)=3、hash(20)=6。 我们把<5,”tom”>、<8,”Jane”>、<12,”Bit”>、<17,”Lily”>、<20,”sunny”>分别放到地址为8、11、15、3、6的位置上。当要检索17对应的值的时候,只要首先计算17的哈希值为3,然后到地址为3的地方去取数据就可以找到17对应的数据是“Lily”了。 算法复杂度(查询)。O(1)。大大加快数据的查询速度。 还有看不明白的回去看《数据结构》的教材。 5、将数据采用哈希算法进行保存的数据结构就是哈希表,常见操作put、get、remove。 6、先不管范型 7、Java中的HashMap使用(Java内置的哈希表数据结构) HashMap的主要方法 int size():得到Map中“键-值对”的数量 boolean isEmpty():Map是否是空的,也就是是否不含有任何“键-值对” boolean containsKey(Object key):Map中是否含有以key为键的“键-值对” boolean containsValue(Object value):Map中是否含有以value为值的“键-值对” Object get(Object key):从Map中得到以key为键的值,如果Map中不含有以key为键的“键-值对”则返回null Object put(Object key, Object value):向Map中存储以key为键、value为值的“键-值对” Object remove(Object key):从Map中移除以key为键的“键-值对” void clear():清除所有“键-值对” Set keySet():得到所有的键 Collection values():得到所有的值 Set entrySet():得到所有的“键-值对”,Set中的类型是Map.Entry 8、工号查询;枚举工号; 9、使用HashMap改造简繁转换并进行性能测试 //为什么算法复杂度由O(n*n)变成O(n),但是实际执行时间没有明显的变化 //print,数据在CPU、内存中运算都非常快,一旦与外设(打印机、网络(网卡)、显示设备(显卡))交换数据,速度就会慢很多。《操作系统》、《计算机组成原理》里边讲的。 更多内容参考杨中科的《J2EE开发全程实录》第二章。 课下作业:简繁转换web版词库我会放到板书附件里 火星文翻译器(web版) 下节课安排: 开发自己的JianFan4J(自己动手写开源项目,自己动手写类库,用工具的人变成造工具的人) 打包成jar供别人使用 简繁词典下载:jianfan.rar (9.85 KB) 刚看视频,发现一处错误: String eng[] = new String{"book","computer","money"}; String chn[] = new String{"书","电脑","钱"}; 应该去掉new String 呵呵,继续看,然后作业. 《Java应该这么学》第五节 1、火星文翻译器https://www.360docs.net/doc/ae4831497.html,/ 2、为什么要有Jar(别人不用重新编译、防止泄露源代码、复用) 3、开发自己的JianFan4J,打包成Jar供别人用(自己动手写开源项目,自己动手写类库,用工具的人变成造工具的人)。Static方法和普通方法的区别,jar文件的导出。 Java工程导出Jar包的方式:工程上右键,选择“Export”,选择“Java→JarFile” 4、课下作业:开发Huoxingwen4J的开源组件 5、Pinyin4j的使用和原理分析 6、课下作业:自己动手写Pinyin4j(文件处理、字符处理、HashMap,嵌入资源(可以先读取绝对路径的文件)) 7、集合:HashSet 集合的特征:数据不重复 HashSet(挑选出重复的人员) 用Set实现从98中选中缺的2个数字这个算法;实现统计字符串中出现的所有字符的算法; 面试、笔试的时候能用最优化算法当然最好,如果想不到最优化算法,就是HashSet、HashMap、List等数据结构来实现,分数也不会很低。想不到好算法仍然拿高分的秘籍!!! 下节课内容: 1、利用HashMap简化阶乘运算(缓存、缓存命中率),BigInteger的使用 2、统计一篇文章中每个字的出现次数(HashMap的应用) 3、自己动手写模板引擎(文件处理、架构、Map、占位符、字符串处理、LoadFromFile、LoadFromStream) pinyin4j下载:pinyin4j.rar (98.27 KB) 《Java应该这么学》第六节 课程源码下载:TestRuPengPY4j.rar (96.63 KB) TestHashMap.rar (3.94 KB) 1、上节课作业自己动手写PinYin4j Winrar打开jar文件 为什么不提供直接读取文本文件到String字符串中的方法:防止大文件读取占用内存,所以使用“流”的概念,用一行读一行。 a)java中读取jar包内的资源文件 getResourceAsStream b)读取文本文件流,搜索关键字:“InputStream 文本文件” 1.BufferedReader reader = new BufferedReader(new InputStreamReader(inStream)); 2.line = reader.readLine(); 3.while (line != null) 4.{ 5.line = reader.readLine(); // 读取下一行 6.} 7.reader.close(); 复制代码 a)得到char的十六进制Unicode编码的方法(什么是Unicode编码)。Integer.toHexString。搜索关键字“java Char Unicode” 1、HashMap应用: 100!已经远远超出了int的表示范围 1.BigInteger i1 = new BigInteger("100"); 2.BigInteger i2 = new BigInteger("888"); 3.BigInteger i3 = i1.add(i2); 4.BigInteger i4 = i1.multiply(i2); 5.System.out.println(i3); 6.System.out.println(i4); 7. 8.public static BigInteger jiecheng(int n) 9.{ 10.if(n==0) 11.{ 12.return new BigInteger("1"); 13.} 14.else 15.{ 16.String s = Integer.toString(n); 17.//计算n-1的阶乘的时候先到map里查询有没有n-1的阶乘了,如果有则直接到map中取 18.if(map.containsKey(n-1)) 19.{ 20.return (BigInteger) map.get(n-1); 21.} 22.else//计算n-1的阶乘,然后放到map中 23.{ 24.BigInteger n_1jiecheng = jiecheng(n-1); 25.map.put(n-1, n_1jiecheng); 26.return n_1jiecheng.multiply(new BigInteger(s)); 27.} 28.} 29.} 复制代码 课下试验,生成几百个、几千个数字,验证一下是不是比传统的递归方式快很多。 数越多效果越明显!!! “缓存”!!!回去看《操作系统》教材中关于“缓存”的部分。HashMap与缓存。HashMap在企业中应用的非常广,可以不用考虑什么算法优化也能比较高效的优化算法。 a)使用HashMap简化阶乘计算(BigInteger) b)计算一系列数字的阶乘 c)统计一篇文章中每个字出现的次数 以字符(char)为key,以每个char出现的次数为value的map 1.public static void main(String[] args) 2.{ 3.String text = "BigInteger n_1jiecheng = jiecheng(n-1)"; 4.HashMap map = new HashMap(); 5.for(int I = 0; I < text.length(); I ++) 6.{ 7.Character ch = text.charAt(i); 8.if(map.containsKey(ch)) 9.{ 10.Integer count = (Integer) map.get(ch); 11.count = count + 1; 12.map.put(ch,count); 13.} 14.else 15.{ 16.map.put(ch, 1); 17.} 18.} 19. 20.for(Object obj:map.keySet()) 21.{ 22.Character ch = (Character) obj; 23.System.out.println(ch + " = " + map.get(ch)); 24.} 25.} 复制代码 细看下,杨老师的代码有一处疏忽 //计算n-1的阶乘的时候先到map里查询有没有n-1的阶乘了,如果有则直接到map中取 if(map.containsKey(n-1)) { return (BigInteger) map.get(n-1); } 视频和板书里的这段代码判断了map里是否有n-1的阶乘,但返回值应该为下面这段:(否则会少乘一个n) return ((BigInteger)map.get(n-1)).multiply(new BigInteger(s)); 测试了一下的确如此,我想可能改过来会方便一些