Bug调试专项练习二笔记

专项排错

网络编程专项排错

本程序存在两处代码错误。所有找出后能够实现文件上传功能, 上传成功后打开ServerDir文件夹,找到打开copy.jpg能够正常显示。java

错误1.文件找不到。 错误2.图片上传成功,访问Socket时出错。编程

需排错代码

接收端:数组

package com.itheima.demo1;

import java.io.*;
import java.net.ServerSocket;
import java.net.Socket;

public class ServerDemo {
   public static void main(String[] args) throws IOException {
       ServerSocket ss = new ServerSocket(10001);

       Socket accept = ss.accept();

       //网络中的流,从客户端读取数据的
       BufferedInputStream bis = new BufferedInputStream(accept.getInputStream());
       //本地的IO流,把数据写到本地中,实现永久化存储
       BufferedOutputStream bos = new BufferedOutputStream(new FileOutputStream("ServerDir\\copy.jpg"));

       int b;
       while((b = bis.read()) !=-1){
           bos.write(b);
      }

       BufferedWriter bw = new BufferedWriter(new OutputStreamWriter(accept.getOutputStream()));
       bw.write("上传成功");
       bw.newLine();
       bw.flush();

       bos.close();
       accept.close();
       ss.close();


  }
}

发送端:服务器

package com.itheima.demo1;

import java.io.*;
import java.net.Socket;

public class ClientDemo {
   public static void main(String[] args) throws IOException {
       Socket socket = new Socket("127.0.0.1",10001);

       //是本地的流,用来读取本地文件的.
       BufferedInputStream bis = new BufferedInputStream(new FileInputStream("ClientDir\\1.jpg"));

       //写到服务器 --- 网络中的流
       OutputStream os = socket.getOutputStream();
       BufferedOutputStream bos = new BufferedOutputStream(os);

       byte[] bytes=new byte[1024];
       int len;
       while((len = bis.read())!=-1){
           bos.write(bytes,0,len);//经过网络写到服务器中
      }
       bos.flush();
       //给服务器一个结束标记,告诉服务器文件已经传输完毕
       socket.shutdownOutput();


       BufferedReader br = new BufferedReader(new InputStreamReader(socket.getInputStream()));
       String line;
       while((line = br.readLine()) !=null){
           System.out.println(line);
      }
       bis.close();
       socket.close();


  }
}

首次运行异常

出现了系统找不到指定路径网络

 

 

异常缘由

代码中写的是相对于项目下的路径,而咱们的存放位置在模块下多线程

 

 

 

 

解决方案

更改路径,加上项目名socket

 

 

再次运行出现数据写入异常

 

 

异常缘由

经过debug发现,每次写入时候数组为空,写入为空ide

数据没有读取到数组中,因此每次写入的为空测试

 

 

解决方案

将数组传入atom

 

 

再次运行出现了访问出错

 

 

解决方案

 

 

问题解决成功

 

 

反射构造排错

错误代码

类文件

package com.itheima.demo1;

import java.lang.reflect.Constructor;


public class ReflectDemo1 {
   public static void main(String[] args) throws Exception {

       Class clazz = Class.forName("com.itheima.demo1.Student");
       Constructor constructor = clazz.getDeclaredConstructor(String.class);
       Student wang = (Student) constructor.newInstance("老王");
       System.out.println(wang);

  }
}

javabean类

package com.itheima.demo1;

public class Student {
   private String name;
   private int age;


   public Student() {

  }

   private Student(String name) {
       

  }

   public Student(String name, int age) {

  }

   @Override
   public String toString() {
       return "Student{" +
               "name='" + name + '\'' +
               ", age=" + age +
               '}';
  }
}

排错说明

本题目有两处错误。目前运行会报错。 错误1.运行直接会报出的异常。 错误2.运行结果是Student{name='null', age=0}。要求打印结果是: Student{name='老王', age=0}

首次运行错误信息

 

 

 

 

 

 

缘由该构造是私有的,咱们使用此构造须要修改Accessible

修改方案

修改临时检测

 

 

再次运行为null异常

异常信息

 

 

缘由

私有带参构造没有进行赋值操做

 

 

解决方案

进行赋值

 

 

最终效果

 

 

反射方法排错

类文件

package com.itheima.demo2;

import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;


public class ReflectDemo2 {
   public static void main(String[] args) throws ClassNotFoundException, NoSuchMethodException, IllegalAccessException, InstantiationException, InvocationTargetException {

       Class clazz = Class.forName("com.itheima.demo2.Student");
       Method method = clazz.getMethod("function4", String.class);
       Student student = (Student) clazz.newInstance();
       Object result = method.invoke("hello");
       System.out.println(result);
  }
}

javabean


package com.itheima.demo2;

public class Student {

   private void show() {
       System.out.println("私有的show方法,无参无返回值");
  }

   public void function1() {
       System.out.println("function1方法,无参无返回值");
  }

   public void function2(String name) {
       System.out.println("function2方法,有参无返回值,参数为" + name);
  }

   public String function3() {

       return "function3";
  }

   public String function4(String name) {

       return name;
  }
}

排错需求

本题目有1处错误。目前运行会报错:IllegalArgumentException。要求打印结果是: hello

运行错误

 

 

错误缘由

invoke方法传参错误

 

 

解决方案

修改参数

 

 

最终效果

 

 

dtd限制xml排错

dtd代码

<!ELEMENT note (to,from,heading,body)>
<!ELEMENT to (#PCDATA)>
<!ELEMENT from (#PCDATA)>
<!ELEMENT heading (#PCDATA)>
<!ELEMENT body (#PCDATA)>

xml代码

<?xml version="1.0"?>
       <!DOCTYPE note SYSTEM "note.dtd">
<note>
<to>George</to>
<from>John</from>
<body>Don't forget the meeting!</body>
<heading>Reminder</heading>
</note>

报错位置

 

 

错误缘由分析

标签位置和限制文档位置不符,致使报出此错误

 

 

解决方案

修改位置

 

 

xsd限制xml排错

xml文件

<?xml version="1.0"?>
<note
       xmlns="http://www.itheima.com.cn"
       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
       xsi:schemaLocation="http://www.itheima.com.cn note.xsd">

   <to>George</to>
   <from>John</from>
   <heading>Reminder</heading>
   <body>aaa</body>
</note>

xsd文件

<?xml version="1.0"?>
<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema"
          targetNamespace="http://www.itheima.com.cn"
          xmlns="http://www.itheima.com.cn"
          elementFormDefault="qualified">

   <xs:element name="note">
       <xs:complexType>
           <xs:sequence>
               <xs:element name="from" type="xs:string"/>
               <xs:element name="to" type="xs:string"/>
               <xs:element name="heading" type="xs:string"/>
               <xs:element name="body" type="xs:int"/>
           </xs:sequence>
       </xs:complexType>
   </xs:element>

</xs:schema>

错误信息:

 

 

 

错误缘由

限制文档顺序和类型引起异常

 

 

修改方案

修改位置,修改数据类型

 

 

最终效果

 

 

多线程排错

错误代码

线程任务类

package com.itheima.demo1;

public class MyThread extends Thread {
   @Override
   public void run() {
       //获取当前执行线程的名称
       String name = Thread.currentThread().getName();
       System.out.println(name+"线程进来执行了");
       for(int i=0; i<5; i++) {
           System.out.println(i);
      }
  }
}

测试类:

package com.itheima.demo1;

public class MyThreadDemo {
   public static void main(String[] args) {
       MyThread mt = new MyThread();
       mt.setName("1号线程");
       mt.start();
  }
}

排错说明

运行MyThreadDemo中的主方法,观察其运行结果后修改代码,要求运行结果是:

1号线程线程进来执行了
0
1
2
3
4

运行错误

 

 

 

错误缘由

run是调用,start才是开启线程

修改方案

 

 

最终效果

 

 

多线程重复票问题

错误代码

线程任务类

package com.itheima.demo2;

public class MyRunnable implements Runnable {
   private int count = 10;

   @Override
   public void run() {
       while (true) {
           synchronized (MyRunnable.class) {
               if (count > 0) {
                   System.out.println(Thread.currentThread().getName() + "售出:" + count + "号票");
                   count--;
              }
          }
      }
  }
}

测试类

package com.itheima.demo2;

public class MyRunnableDemo {
   public static void main(String[] args) {

       MyRunnable my1 = new MyRunnable();
       MyRunnable my2 = new MyRunnable();

       Thread t1 = new Thread(my1,"A窗口");
       Thread t2 = new Thread(my2,"B窗口");


       t1.start();
       t2.start();
  }
}

排错需求

运行MyRunnableDemo中的主方法,观察其运行结果后修改代码,要求运行结果是:

A窗口售出:10号票
A窗口售出:9号票
A窗口售出:8号票
A窗口售出:7号票
A窗口售出:6号票
A窗口售出:5号票
A窗口售出:4号票
A窗口售出:3号票
A窗口售出:2号票
A窗口售出:1号票

注意:出现哪一个窗口不重要,重要的是只能有10张被售出。

错误信息

出现重复票

 

 

解决方案

数据未静态

 

 

修改方案

将数据进行静态

 

 

程序未结束分析

没有结束语句

修改方案

加一个判断票数为0,结束程序

 

 

 

最终效果

相关文章
相关标签/搜索