20155232 2016-2017-3 《Java程序设计》第10周学习总结

20155232 2016-2017-3 《Java程序设计》第10周学习总结

教材学习内容总结

  • 计算机网络

路由器和交换机组成了核心的计算机网络,计算机只是这个网络上的节点以及控制等,通过光纤、网线等连接将设备连接起来,从而形成了一张巨大的计算机网络。

  • 网络概览

  • 计算机之间使用共同的语言来通信,称之为协议,协议分为几个层,如图展示了网络中的一些层。

image

  • 超文本传输协议(HTTP)

HTTP是允许WEB服务器和浏览器之间通过互联网发送和接收数据的协议。它是一种请求和响应协议。在HTTP中总是由客户端先建立一个连接并发送一个请求,从而发起一次事务。分为:HTTP响应和HTTP请求。

  • java.net.URL

1.URL是互联网资源的唯一地址。HTTP是URL中最常使用的协议。可以使用如下方法解析URL:
image
2.可以使用URL类的openStream方法读取一个web资源。

  • java.net.URLConnection

URLConnection表示到远程机器的一次连接。使用它读取资源并写到一台远程机器中。URLConnection类并没有公共的构造方法,因此无法使用new创建实例。

  • java.net.Socket

套接字是一个网络连接的端点。套接字使得应用程序能够从网络读取或者向网络写入信息。位于两台不同的计算机的软件,通过连接来发送和接受数据流,就可以彼此通信。
image

  • java.net.ServerSocket

Socket表示一个“客户端”套接字,当想要连接到一个远程服务器应用的时候,可以构造一个套接字。ServerSocket和socket不同。服务器套接字的角色是,等待客户端的连接请求。一档获得请求,会创建一个socket实例,以处理和客户端的通信。

  • Request类

Request类表示一个HTTP请求。该类的实例是通过传入Socket对象获取的java.io.InputStream对象来构造的。

  • Response类

代表了一个HTTP响应。Response类有两个公有的方法:setRequest和sendStaticResource方法。etRequest方法用于将一个Request对象传递给Response对象。

教材学习中的问题和解决过程

  • 问题一

如何使服务器端支持多个客户端同时工作?

  • 解决方法

在服务器端利用多线程。为每一个连接 创建一个线程去处理。一个服务器端一般都需要同时为多个客户端提供通讯,当服务器端接收到一个连接时,启动一个专门的线程处理和该客户端的通讯,这样就可以支持多个客户端。上网搜索了一下在这个链接中有很详细的解释
服务器端支持多个客户端工作

  • 问题二

在书中第22章的22.7中提到了await()方法,联想到了wait()方法,那么wait()方法和sleep()方法有什么区别?

  • 解决方案

Java中的多线程是一种抢占式的机制而不是分时机制。线程主要有以下几种状态:可运行,运行,阻塞,死亡。抢占式机制指的是有多个线程处于可运行状态,但是只有一个线程在运行。当有多个线程访问共享数据的时候,就需要对线程进行同步。线程中的几个主要方法的比较:

1.Thread类的方法:sleep(),yield()等

2.Object的方法:wait()和notify()等
每个对象都有一个机锁来控制同步访问。Synchronized关键字可以和对象的机锁交互,来实现线程的同步。

由于sleep()方法是Thread类的方法,因此它不能改变对象的机锁。所以当在一个Synchronized方法中调用sleep()时,线程虽然休眠了,但是对象的机锁没有被释放,其他线程仍然无法访问这个对象。

而wait()方法则会在线程休眠的同时释放掉机锁,其他线程可以访问该对象。

代码调试中的问题和解决过程

  • 问题一

在老师给的材料中java密码技术
如下程序SDec.java中:

import java.io.*;
import java.security.*;
import javax.crypto.*;
import javax.crypto.spec.*;
public class SDec{
   public static void main(String args[]) throws Exception{
        // 获取密文
        FileInputStream f=new FileInputStream("SEnc.dat");
        int num=f.available();
        byte[ ] ctext=new byte[num];          
        f.read(ctext);
        // 获取密钥
        FileInputStream  f2=new FileInputStream("keykb1.dat");
        int num2=f2.available();
        byte[ ] keykb=new byte[num2];          
        f2.read(keykb);
        SecretKeySpec k=new  SecretKeySpec(keykb,"DESede");
        // 解密
        Cipher cp=Cipher.getInstance("DESede");
        cp.init(Cipher.DECRYPT_MODE, k);
        byte []ptext=cp.doFinal(ctext);
         // 显示明文
        String p=new String(ptext,"UTF8");
        System.out.println(p);
   }
}

运行时出现错误

  • 解决方案

(未解决)

  • 问题二

在老师给的材料中java密码技术中程序:

import java.security.*;
public class DigestPass{
     public static void main(String args[ ]) throws Exception{
         String x=args[0];
         MessageDigest m=MessageDigest.getInstance("MD5");
         m.update(x.getBytes("UTF8"));
         byte s[ ]=m.digest( );
         String result="";
         for (int i=0; i<s.length; i++){
            result+=Integer.toHexString((0x000000ff & s[i]) | 
0xffffff00).substring(6);
         }
         System.out.println(result);
      }   
}

按照老师给出的代码运行错误:
image

  • 解决方案

将类名改为

DigestCalc.java

即可使用

java DigestCalc abc

运行,其中命令行参数abc是原始数据,屏幕输出计算后的消息摘要:900150983cd24fb0d6963f7d28e17f72。
image

代码托管

  • 代码提交过程截图:
    image
    image

结对及互评

评分标准(满分10分)

  1. 从0分加到10分为止

  2. 正确使用Markdown语法(加1分):

    • 不使用Markdown不加分
    • 有语法错误的不加分(链接打不开,表格不对,列表不正确...)
    • 排版混乱的不加分
  3. 模板中的要素齐全(加1分)

    • 缺少“教材学习中的问题和解决过程”的不加分
    • 缺少“代码调试中的问题和解决过程”的不加分
    • 代码托管不能打开的不加分
    • 缺少“结对及互评”的不能打开的不加分
    • 缺少“上周考试错题总结”的不能加分
    • 缺少“进度条”的不能加分
    • 缺少“参考资料”的不能加分
  4. 教材学习中的问题和解决过程, 一个问题加1分

  5. 代码调试中的问题和解决过程, 一个问题加1分

  6. 本周有效代码超过300分行的(加2分)

    • 一周提交次数少于20次的不加分

6 其他加分:

  • 周五前发博客的加1分
    • 感想,体会不假大空的加1分
    • 排版精美的加一分
    • 进度条中记录学习时间与改进情况的加1分
    • 有动手写新代码的加1分
    • 课后选择题有验证的加1分
    • 代码Commit Message规范的加1分
    • 错题学习深入的加1分
      7 扣分:
    • 有抄袭的扣至0分
    • 代码作弊的扣至0分

点评模板:

  • 博客中值得学习的或问题:

    • xxx
    • xxx
    • ...
  • 代码中值得学习的或问题:

    • xxx
    • xxx
    • ...
  • 基于评分标准,我给本博客打分:XX分。得分情况如下:xxx

  • 参考示例

点评过的同学博客和代码

  • 本周结对学习情况
    • 20155215

    • 结对学习内容

      • 一起看老师给的网页链接学习,共同解决代码编译报错问题。
      • 讨论分析上周考试留下来的部分没有解决的试题。
      • 讨论知识点,交换学习体会和总结学习难点。
  • 上周博客互评情况

20155317

20155207

20155312

20155206

20155205

上周考试错题总结

  • 简答(5)你是如何运行P509 ConnectionDemo.java和P513 MessageDAODemo.java的?
    下载安装MySQL(或XAMPP),IDE(Eclipse/IDEA/Netbeans)中导入数据库驱动 (1分)
    建数据库demo : create schema demo (1 分)
    修改P509 ConnectionDemo.java中passwd 改为自己的,openhome的一般不对(1分)

建表:
Use demo;
create TABLE t_message …. (1分)
修改P509 ConnectionDemo.java中MessageDAO dao = new MessageDAO()中的口令 改为自己的,openhome的一般不对(1分)

感悟心得

  • 对考试感悟

在这次考试中失分过多,是考试中最差的一次,主要原因是在前面的一个题上浪费的时间过多,导致最后一道大题会做却没得分,因为没有时间了,所以遇到不会的题不能一直纠结浪费时间,应该先做下一题,等做完后再反过来看不会的题,这样就不会导致这种情况的出现了。

  • 运行Java 密码学算法中代码

1.体验加解密---凯撒密码

加密过程:c≡m+k mod n (其中n为基本字符个数)

同样,解密过程可表示为:
m≡c+k mod n (其中n为基本字符个数)
image
该程序既可用于加密又可用于解密。只要执行:

java Caesar 明文(要加密的字符串) 密钥(移动的位数)

在密钥前面加上负号,将运行解密。

加密:image
解密:
image
加密Helloworld
image
解密Helloworld
image

2.Java对称加密-DES算法

本实例给出Java中创建对称密钥的步骤,并通过对象序列化方式保存在文件中。
image
运行java Skey_DES,在当前目录下将生成文件key1.dat,其中包含的密钥可以用于使用Triple-DES算法的加密和解密。
image
先创建文件输出流对象,在其参数中指定文件名,如keykb1.dat。然后执行文件输出流的write( )方法将第2步中得到的字节数组中的内容写入文件。

import java.io.*;
import java.security.*;
public class Skey_kb{
    public static void main(String args[]) throws Exception{
        FileInputStream f=new FileInputStream("key1.dat");
        ObjectInputStream b=new ObjectInputStream(f);
        Key k=(Key)b.readObject( );
        byte[ ] kb=k.getEncoded( );
        FileOutputStream  f2=new FileOutputStream("keykb1.dat");
       f2.write(kb);
        // 打印密钥编码中的内容
        for(int i=0;i<kb.length;i++){
                 System.out.print(kb[i]+",");
        }
   }
}

输入java Skey_kb 运行程序,在程序的当前目录中将产生文件名为keykb1.dat的文件,屏幕输出如下:
image
此即程序中创建的密钥的编码内容,如果用文本编辑器打开keykb1.dat,看到的不是上面的数字而是类似下面的字符:

棄2 ?&驊 馤禖??僪*

3.Java非对称加密-RSA算法

输入java Skey_RSA运行程序,当前目录下将生成两个文件:Skey_RSA_pub.dat和Skey_RSA_priv.dat,前者保存着公钥,后者保存着私钥。
image

import java.security.*;
import java.security.spec.*;
import javax.crypto.*;
import javax.crypto.spec.*;
import javax.crypto.interfaces.*;
import java.security.interfaces.*;
import java.math.*;
import java.io.*;
public class Enc_RSA{
   public static void main(String args[]) throws Exception{
        String s="Hello World!";
        // 获取公钥及参数e,n
        FileInputStream f=new FileInputStream("Skey_RSA_pub.dat");
        ObjectInputStream b=new ObjectInputStream(f);
        RSAPublicKey  pbk=(RSAPublicKey)b.readObject( );
        BigInteger e=pbk.getPublicExponent();
        BigInteger n=pbk.getModulus();
        System.out.println("e= "+e);
        System.out.println("n= "+n);
        // 明文 m
        byte ptext[]=s.getBytes("UTF8");
        BigInteger m=new BigInteger(ptext);
        // 计算密文c,打印
        BigInteger c=m.modPow(e,n);
        System.out.println("c= "+c);
       // 保存密文
        String cs=c.toString( );
        BufferedWriter out= 
             new BufferedWriter(new OutputStreamWriter(
                new FileOutputStream("Enc_RSA.dat")));
        out.write(cs,0,cs.length( ));
        out.close( );
       
   }
}

程序最后将密文c打印出来,并以字符串形式保存在文件中。

运行程序

输入java Enc_RSA运行程序,得到如下结果:
image
中显示了公钥中的参数以及加密的结果c,这些都是很大的整数,n和c多达上百位。程序运行后密文c以字符串形式保存在文件Enc_RSA.dat中。

RSA算法解密的结果m是一个很大的整数,为了计算出其对应的字符串的值,先使用BigInteger类的toByteArray( )方法得到代表该整型数的字节数组,然后将数组中每个元素转换为字符,组成字符串。

import java.security.*;
import java.security.spec.*;
import javax.crypto.*;
import javax.crypto.spec.*;
import javax.crypto.interfaces.*;
import java.security.interfaces.*;
import java.math.*;
import java.io.*;
public class Dec_RSA{
   public static void main(String args[]) throws Exception{
       //读取密文
        BufferedReader in= 
                new BufferedReader(new InputStreamReader(
new FileInputStream("Enc_RSA.dat")));
        String ctext=in.readLine();
        BigInteger c=new BigInteger(ctext);
       //读取私钥
        FileInputStream f=new FileInputStream("Skey_RSA_priv.dat");
        ObjectInputStream b=new ObjectInputStream(f);
        RSAPrivateKey prk=(RSAPrivateKey)b.readObject( );
        BigInteger d=prk.getPrivateExponent();
       //获取私钥参数及解密 
        BigInteger n=prk.getModulus();
        System.out.println("d= "+d);
        System.out.println("n= "+n);
        BigInteger m=c.modPow(d,n);
       //显示解密结果
        System.out.println("m= "+m);
        byte[] mt=m.toByteArray();
        System.out.println("PlainText is ");
        for(int i=0;i<mt.length;i++){
             System.out.print((char) mt[i]);
       }
    }
}

运行程序输入java Dec_RSA运行程序,得到如下结果:

image
其中显示了私钥中的参数以及解密的结果,其中整型的明文转换后显示出字符串“Hello World!”。

学习进度条

代码行数(新增/累积) 博客量(新增/累积) 学习时间(新增/累积) 重要成长
目标 5000行 30篇 400小时
第一周 15/15 1/1 23/26
第二周 208/240 2/2 35/38
第三周 376/584 3/3 32/38
第四周 823/1407 4/4 28/30
第五周 986/2393 5/5 21/26
第六周 1258/3651 6/6 26/25
第七周 575/4226 7/7 14/16
第八周 390/4616 8/8 15/18
第十周 363/6192 10/10 17/20
尝试一下记录「计划学习时间」和「实际学习时间」,到期末看看能不能改进自己的计划能力。这个工作学习中很重要,也很有用。
耗时估计的公式
:Y=X+X/N ,Y=X-X/N,训练次数多了,X、Y就接近了。

参考:软件工程软件的估计为什么这么难软件工程 估计方法

参考资料

posted @ 2017-04-30 21:41  短爪爪爪  阅读(174)  评论(3编辑  收藏  举报