精华内容
下载资源
问答
  • 包含: Java编程思想 第四版 (Pdf, Docx版), 练习答案, net.jar, tools.jar, 书中例子源码
  • Java编程思想第四版第十四章习题

    千次阅读 2019-08-08 21:59:14
    1In ToyTest.java, comment out Toy's default constructor andexplain what happens. package job; import java.util.*; interface HasBatteries {} interface Waterproof {} interface Shoots {} class .....

    1 In ToyTest.java, comment out Toy's default constructor and explain what happens.

    package job;
    import java.util.*;
    
    interface HasBatteries {}
    
    interface Waterproof {}
    
    interface Shoots {}
    
    
    
    class Toy {
    
        //Toy() {}
    
        Toy(int i) {}
    
    }
    
    
    
    class FancyToy extends Toy implements HasBatteries, Waterproof, Shoots {
    
        FancyToy() {
            super(1);
        }
    
    }
    
    
    
    public class Main {
    
        static void printInfo(Class cc) {
    
            System.out.println("Class name: " + cc.getName() +
    
                    " is interface? [" + cc.isInterface() + "]");
    
            System.out.println("Simple name: " + cc.getSimpleName());
    
            System.out.println("Canonical name : " + cc.getCanonicalName());
    
        }
    
        public static void main(String[] args) {
    
            Class c = null;
    
            try {
    
                c = Class.forName("job.FancyToy");
    
            } catch (ClassNotFoundException e) {
    
                System.out.println("Can't find FancyToy");
    
                System.exit(1);
    
            }
    
            printInfo(c);
    
            for (Class face : c.getInterfaces())
    
                printInfo(face);
    
            Class up = c.getSuperclass();
    
            Object obj = null;
    
            try {
    
                // Requires default constructor:
    
                obj = up.newInstance();
    
            } catch (InstantiationException e) {
    
                System.out.println("Cannot instantiate");
    
                System.exit(1);
    
            } catch (IllegalAccessException e) {
    
                System.out.println("Cannot access");
    
                System.exit(1);
    
            }
    
            printInfo(obj.getClass());
    
        }
    
    }
    

    output:

     Class name: job.FancyToy is interface? [false]
    Simple name: FancyToy
    Canonical name : job.FancyToy
    Class name: job.HasBatteries is interface? [true]
    Simple name: HasBatteries
    Canonical name : job.HasBatteries
    Class name: job.Waterproof is interface? [true]
    Simple name: Waterproof
    Canonical name : job.Waterproof
    Class name: job.Shoots is interface? [true]
    Simple name: Shoots
    Canonical name : job.Shoots
    Cannot instantiate

     

    2 Incorporate a new kind of interface into ToyTest.java andverify that it is detected and displayed properly.

    package job;
    import java.util.*;
    
    interface HasBatteries {}
    
    interface Waterproof {}
    
    interface Shoots {}
    
    interface A{}
    
    
    
    class Toy {
    
        Toy() {}
    
        Toy(int i) {}
    
    }
    
    
    
    class FancyToy extends Toy implements HasBatteries, Waterproof, Shoots,A {
    
        FancyToy() {
            super(1);
        }
    
    }
    
    
    
    public class Main {
    
        static void printInfo(Class cc) {
    
            System.out.println("Class name: " + cc.getName() +
    
                    " is interface? [" + cc.isInterface() + "]");
    
            System.out.println("Simple name: " + cc.getSimpleName());
    
            System.out.println("Canonical name : " + cc.getCanonicalName());
    
        }
    
        public static void main(String[] args) {
    
            Class c = null;
    
            try {
    
                c = Class.forName("job.FancyToy");
    
            } catch (ClassNotFoundException e) {
    
                System.out.println("Can't find FancyToy");
    
                System.exit(1);
    
            }
    
            printInfo(c);
    
            for (Class face : c.getInterfaces())
    
                printInfo(face);
    
            Class up = c.getSuperclass();
    
            Object obj = null;
    
            try {
    
                // Requires default constructor:
    
                obj = up.newInstance();
    
            } catch (InstantiationException e) {
    
                System.out.println("Cannot instantiate");
    
                System.exit(1);
    
            } catch (IllegalAccessException e) {
    
                System.out.println("Cannot access");
    
                System.exit(1);
    
            }
    
            printInfo(obj.getClass());
    
        }
    
    }
    

    output:

    Class name: job.FancyToy is interface? [false]
    Simple name: FancyToy
    Canonical name : job.FancyToy
    Class name: job.HasBatteries is interface? [true]
    Simple name: HasBatteries
    Canonical name : job.HasBatteries
    Class name: job.Waterproof is interface? [true]
    Simple name: Waterproof
    Canonical name : job.Waterproof
    Class name: job.Shoots is interface? [true]
    Simple name: Shoots
    Canonical name : job.Shoots
    Class name: job.A is interface? [true]
    Simple name: A
    Canonical name : job.A
    Class name: job.Toy is interface? [false]
    Simple name: Toy
    Canonical name : job.Toy
     

    3 Add Rhomboid to Shapes.java. Create a Rhomboid, upcast it to a Shape, then downcast it back to a Rhomboid. Try downcasting to a Circle and see what happens.

    package job;
    import java.util.*;
    abstract class Shape{
        abstract void draw();
        abstract void erase();
    }
    class Rhomboid extends Shape{
    
        public void draw() { System.out.println("Rhomboid.draw()"); }
    
        public void erase() { System.out.println("Rhomboid.erase()"); }
    
    }
    
    class Circle extends Shape{
    
        public void draw() { System.out.println("Circle.draw()"); }
    
        public void erase() { System.out.println("Circle.erase()"); }
    
    }
    public class Main {
    
    
        public static void main(String[] args) {
            try {
                Shape a = new Rhomboid();
    
                a.draw();
    
                ((Rhomboid) a).draw();
    
                ((Circle) a).draw();
            } catch (Exception e) {
                e.printStackTrace(System.out);
            }
        }
    
    }
    

    output:

    Rhomboid.draw()
    Rhomboid.draw()
    java.lang.ClassCastException: class job.Rhomboid cannot be cast to class job.Circle (job.Rhomboid and job.Circle are in unnamed module of loader 'app')
        at job.Main.main(Main.java:33)

     

    4 Modify the previous exercise so that it uses instancof to check the type before performing the downcast.

    package job;
    import java.util.*;
    abstract class Shape{
        abstract void draw();
        abstract void erase();
    }
    class Rhomboid extends Shape{
    
        public void draw() { System.out.println("Rhomboid.draw()"); }
    
        public void erase() { System.out.println("Rhomboid.erase()"); }
    
    }
    
    class Circle extends Shape{
    
        public void draw() { System.out.println("Circle.draw()"); }
    
        public void erase() { System.out.println("Circle.erase()"); }
    
    }
    public class Main {
    
    
        public static void main(String[] args) {
            try {
                Shape a = new Rhomboid();
                if(a instanceof Shape) {
                    a.draw();
                }
                if(a instanceof Rhomboid) {
                    ((Rhomboid) a).draw();
                }
                else if(a instanceof Circle) {
                    ((Circle) a).draw();
                }
            } catch (Exception e) {
                e.printStackTrace(System.out);
            }
        }
    
    }
    

     

    5 Implement a rotate(Shape) method in Shapes.java, such that it checks to see if it is rotating a Circle (and, if so, doesn't perform the operation).

    package job;
    import java.util.*;
    class Shape {
    
        public void draw() {
        }
    
        public void erase() {
        }
    
        public void rotate() {
        }
    
    }
    
    class Square extends Shape {
    
        public void draw() {
            System.out.println("Square.draw()");
        }
    
        public void erase() {
            System.out.println("Square.erase()");
        }
    
        public void rotate() {
            System.out.println("Square.rotate()");
        }
    
    }
    
    class Triangle extends Shape {
    
        public void draw() {
            System.out.println("Triangle.draw()");
        }
    
        public void erase() {
            System.out.println("Triangle.erase()");
        }
    
        public void rotate() {
            System.out.println("Triangle.rotate()");
        }
    
    }
    
    class Circle extends Shape {
    
        public void draw() {
            System.out.println("Circle.draw()");
        }
    
        public void erase() {
            System.out.println("Circle.erase()");
        }
    
        public void rotate() {
            System.out.println("Circle.rotate()");
        }
    
    }
    
    
    
    class RandomShapeGenerator {
    
        private Random rand = new Random(47);
    
        public RandomShapeGenerator() {
        }
    
        public Shape next() {
    
            switch (rand.nextInt(3)) {
    
                default:
    
                case 0:
                    return new Circle();
    
                case 1:
                    return new Square();
    
                case 2:
                    return new Triangle();
    
            }
    
        }
    
    }
    
    
    
    public class Main {
    
        private static RandomShapeGenerator gen = new RandomShapeGenerator();
    
        public static void main(String[] args) {
    
            Shape[] s = new Shape[9];
    
            // Fill up the array with shapes:
    
            for (int i = 0; i < s.length; i++)
    
                s[i] = gen.next();
    
            // Make polymorphic method calls:
    
            for (Shape shp : s) {
    
                if (!(shp instanceof Circle)) shp.rotate();
    
            }
    
        }
    }
    

     output:

    Radom

    6 Modify Shapes.java so that it can "highlight" (set a flag in) all shapes of a particular type.  The toString() method for each derived Shape should indicate whether that Shape is "highlighted."

    package job;
    import java.util.*;
    class Shape {
        boolean flag=false;
    
        public void draw() {
        }
    
        public void erase() {
        }
    
        public void rotate() {
        }
    
        void flag() {
        }
    }
    
    class Square extends Shape {
    
        public void draw() {
            System.out.println("Square.draw()");
        }
    
        public void erase() {
            System.out.println("Square.erase()");
        }
    
        public void rotate() {
            System.out.println("Square.rotate()");
        }
    
        void flag() {
            flag = true;
        }
    
        public String toString() {
            return ("Square: " + flag);
        }
    }
    
    class Triangle extends Shape {
    
        public void draw() {
            System.out.println("Triangle.draw()");
        }
    
        public void erase() {
            System.out.println("Triangle.erase()");
        }
    
        public void rotate() {
            System.out.println("Triangle.rotate()");
        }
    
        void flag() {
            flag = true;
        }
    
        public String toString() {
            return ("Triangle: " + flag);
        }
    }
    
    class Circle extends Shape {
    
        public void draw() {
            System.out.println("Circle.draw()");
        }
    
        public void erase() {
            System.out.println("Circle.erase()");
        }
    
        public void rotate() {
            System.out.println("Circle.rotate()");
        }
    
        void flag() {
            flag = true;
        }
    
        public String toString() {
            return ("Circle: " + flag);
        }
    }
    
    
    
    class RandomShapeGenerator {
    
        private Random rand = new Random(47);
    
        public RandomShapeGenerator() {
        }
    
        public Shape next() {
    
            switch (rand.nextInt(3)) {
    
                default:
    
                case 0:
                    return new Circle();
    
                case 1:
                    return new Square();
    
                case 2:
                    return new Triangle();
    
            }
    
        }
    
    }
    
    
    
    public class Main {
    
        private static RandomShapeGenerator gen = new RandomShapeGenerator();
    
        public static void main(String[] args) {
    
            Shape[] s = new Shape[9];
    
            // Fill up the array with shapes:
    
            for (int i = 0; i < s.length; i++)
    
                s[i] = gen.next();
    
            // Make polymorphic method calls:
    
            for (Shape a : s) {
    
                if (!(a instanceof Circle)) {
                    a.rotate();
                    a.flag();
                    System.out.println(a);
                }
            }
    
        }
    }
    

    output:

    Radom 

    7 Modify SweetShop.java so that each type of object creation is controlled by a command-line argument. That is, if your command line is "java  SweetShop Candy," then only the Candy object is created. Notice how you  can control which Class object are loaded via the command-line argument.

    package job;
    import java.util.*;
    class Candy {
        static {
            System.out.println("Loading Candy");
        }
    }
    class Gum {
        static {
            System.out.println("Loading Gum");
        }
    }
    
    class Cookie {
        static {
            System.out.println("Loading Cookie");
        }
    }
    
    
    class Main{
        public static void main(String[] args){
            Other.main(new String[]{"job.Candy"});
        }
    }
    
    class Other {
    
    
        public static void main(String[] args) {
            if (args.length < 1) {
                System.out.println("args is null");
                System.exit(0);
            }
            Class c = null;
            try {
                c = Class.forName(args[0]);
                System.out.println(c.getName() + " " + c.isInterface());
            } catch (Exception e) {
                e.printStackTrace(System.out);
            }
        }
    }
    

    output:

    Loading Candy
    job.Candy false 

    8 Write a method that takes an object and recursively prints allthe classes in that object's hierarchy.

     

    package job;
    import java.util.*;
    class A{
    
    }
    class B extends A{
    
    }
    class C extends B{
    
    }
    public class Main{
        static void Aa(Class obj){
            System.out.println(obj.getName());
            try{
                Aa(obj.getSuperclass());
            }catch (Exception e){}
        }
        public static void main(String[] args){
            Class c=null;
            try{
                c=Class.forName("job.C");
                Aa(c);
            }catch (Exception e){
                e.printStackTrace(System.out);
            }
        }
    }
    
    

    output:

    job.C
    job.B
    job.A
    java.lang.Object 

    9 Modify the previous exercise so that it uses Class.getDeclaredFields()to also display information about the fields in a class.

     

    package job;
    import java.util.*;
    class A{
    
    }
    class B extends A{
    
    }
    class C extends B{
    
    }
    public class Main{
        static void Aa(Class obj){
            System.out.println(obj.getName());
            try{
                Aa(obj.getSuperclass());
            }catch (Exception e){}
        }
        public static void main(String[] args){
            Class c=null;
            try{
                c=Class.forName("job.C");
                System.out.println(c.getDeclaredFields());
                Aa(c);
            }catch (Exception e){
                e.printStackTrace(System.out);
            }
        }
    }
    
    

    output:

    [Ljava.lang.reflect.Field;@34ce8af7
    job.C
    job.B
    job.A
    java.lang.Object 

    10 Write a program to determine whether an array of char is a primitive type or a true Object.

    package job;
    import java.util.*;
    
    public class Main{
        static void Aa(Class obj){
            System.out.println(obj.getName());
            try{
                Aa(obj.getSuperclass());
            }catch (Exception e){}
        }
        public static void main(String[] args){
            char[] a=new char[5];
            try{
                Class c=a.getClass();
                Aa(c);
            }catch (Exception e){
                e.printStackTrace(System.out);
            }
        }
    }
    
    

    output:

    [C
    java.lang.Object

    故:对象

    11 你在难为我胖虎?

    12 Use TypeCounter with the CoffeeGenerator.java class in the Generics chapter.

    
    import java.util.*;
    
    import generics.coffee.*;
    
     
    
    class TypeCounter extends HashMap<Class<?>,Integer>{
    
      private Class<?> baseType;
    
      public TypeCounter(Class<?> baseType) {
    
        this.baseType = baseType;
    
      }
    
      public void count(Object obj) {
    
        Class<?> type = obj.getClass();
    
        if(!baseType.isAssignableFrom(type))
    
          throw new RuntimeException(obj + " incorrect type: "
    
            + type + ", should be type or subtype of "
    
            + baseType);
    
        countClass(type);
    
      }	
    
      private void countClass(Class<?> type) {
    
        Integer quantity = get(type);
    
        put(type, quantity == null ? 1 : quantity + 1);
    
        Class<?> superClass = type.getSuperclass();
    
        if(superClass != null &&
    
           baseType.isAssignableFrom(superClass))
    
          countClass(superClass);
    
      }
    
      public String toString() {
    
        StringBuilder result = new StringBuilder("{");
    
        for(Map.Entry<Class<?>,Integer> pair : entrySet()) {
    
          result.append(pair.getKey().getSimpleName());
    
          result.append("=");
    
          result.append(pair.getValue());
    
          result.append(", ");
    
        }
    
        result.delete(result.length()-2, result.length());
    
        result.append("}");
    
        return result.toString();
    
      }
    
    }
    
    public class Main{
    
        public static void main(String[] args){
    
           TypeCounter tc=new TypeCounter(Coffee.class);
    
            for(Coffee c : new CoffeeGenerator(5)){
    
                tc.count(c);
    
            }
    
            System.out.println(tc);
    
        }
    
    }
    

     

    13 Use TypeCounter with the RegisteredFactories.java class in this chapter.

    
    
    import typeinfo.factory.*;
    
    import java.util.*;
    
     
    
    class Part {
    
      public String toString() {
    
        return getClass().getSimpleName();
    
      }
    
      static List<Factory<? extends Part>> partFactories =
    
        new ArrayList<Factory<? extends Part>>();	
    
      static {
    
        // Collections.addAll() gives an "unchecked generic
    
        // array creation ... for varargs parameter" warning.
    
        partFactories.add(new FuelFilter.Factory());
    
        partFactories.add(new AirFilter.Factory());
    
        partFactories.add(new CabinAirFilter.Factory());
    
        partFactories.add(new OilFilter.Factory());
    
        partFactories.add(new FanBelt.Factory());
    
        partFactories.add(new PowerSteeringBelt.Factory());
    
        partFactories.add(new GeneratorBelt.Factory());
    
      }
    
      private static Random rand = new Random(47);
    
      public static Part createRandom() {
    
        int n = rand.nextInt(partFactories.size());
    
        return partFactories.get(n).create();
    
      }
    
    }	
    
     
    
    class Filter extends Part {}
    
     
    
    class FuelFilter extends Filter {
    
      // Create a Class Factory for each specific type:
    
      public static class Factory
    
      implements typeinfo.factory.Factory<FuelFilter> {
    
        public FuelFilter create() { return new FuelFilter(); }
    
      }
    
    }
    
     
    
    class AirFilter extends Filter {
    
      public static class Factory
    
      implements typeinfo.factory.Factory<AirFilter> {
    
        public AirFilter create() { return new AirFilter(); }
    
      }
    
    }	
    
     
    
    class CabinAirFilter extends Filter {
    
      public static class Factory
    
      implements typeinfo.factory.Factory<CabinAirFilter> {
    
        public CabinAirFilter create() {
    
          return new CabinAirFilter();
    
        }
    
      }
    
    }
    
     
    
    class OilFilter extends Filter {
    
      public static class Factory
    
      implements typeinfo.factory.Factory<OilFilter> {
    
        public OilFilter create() { return new OilFilter(); }
    
      }
    
    }	
    
     
    
    class Belt extends Part {}
    
     
    
    class FanBelt extends Belt {
    
      public static class Factory
    
      implements typeinfo.factory.Factory<FanBelt> {
    
        public FanBelt create() { return new FanBelt(); }
    
      }
    
    }
    
     
    
    class GeneratorBelt extends Belt {
    
      public static class Factory
    
      implements typeinfo.factory.Factory<GeneratorBelt> {
    
        public GeneratorBelt create() {
    
          return new GeneratorBelt();
    
        }
    
      }
    
    }	
    
     
    
    class PowerSteeringBelt extends Belt {
    
      public static class Factory
    
      implements typeinfo.factory.Factory<PowerSteeringBelt> {
    
        public PowerSteeringBelt create() {
    
          return new PowerSteeringBelt();
    
        }
    
      }
    
    }	
    
    class TypeCounter extends HashMap<Class<?>,Integer>{
    
      private Class<?> baseType;
    
      public TypeCounter(Class<?> baseType) {
    
        this.baseType = baseType;
    
      }
    
      public void count(Object obj) {
    
        Class<?> type = obj.getClass();
    
        if(!baseType.isAssignableFrom(type))
    
          throw new RuntimeException(obj + " incorrect type: "
    
            + type + ", should be type or subtype of "
    
            + baseType);
    
        countClass(type);
    
      }	
    
      private void countClass(Class<?> type) {
    
        Integer quantity = get(type);
    
        put(type, quantity == null ? 1 : quantity + 1);
    
        Class<?> superClass = type.getSuperclass();
    
        if(superClass != null &&
    
           baseType.isAssignableFrom(superClass))
    
          countClass(superClass);
    
      }
    
      public String toString() {
    
        StringBuilder result = new StringBuilder("{");
    
        for(Map.Entry<Class<?>,Integer> pair : entrySet()) {
    
          result.append(pair.getKey().getSimpleName());
    
          result.append("=");
    
          result.append(pair.getValue());
    
          result.append(", ");
    
        }
    
        result.delete(result.length()-2, result.length());
    
        result.append("}");
    
        return result.toString();
    
      }
    
    }
    
    public class Main{
    
        public static void main(String[] args){
    
           TypeCounter tc=new TypeCounter(Part.class);
    
            for(int i = 0; i < 10; i++)
    
                tc.count(Part.createRandom());
    
            System.out.println(tc);
    
        }
    
    }
    
     
    

     

    14 A constructor is a kind of factory method. Modify RegisteredFactories.java so that instead of using explicit factories, the class object is stored in the List, and newInstance() is used to create each object.

    package job;
    import java.util.*;
    interface Factory<T>{
        T create();
    }
    
    class Part {
    
        public String toString() {
    
            return getClass().getSimpleName();
    
        }
    
        static List<Class<? extends Part>> partClasses =
    
                new ArrayList<Class<? extends Part>>();
    
        static {
    
            // Collections.addAll() gives an "unchecked generic
    
            // array creation ... for varargs parameter" warning.
    
            partClasses.add(FuelFilter.class);
    
            partClasses.add(AirFilter.class);
    
            partClasses.add(CabinAirFilter.class);
    
            partClasses.add(OilFilter.class);
    
            partClasses.add(FanBelt.class);
    
            partClasses.add(PowerSteeringBelt.class);
    
            partClasses.add(GeneratorBelt.class);
    
        }
    
        private static Random rand = new Random(47);
    
        public static Part createRandom() {
    
            int n = rand.nextInt(partClasses.size());
    
            try{return partClasses.get(n).newInstance();
    
            }catch(InstantiationException e){
    
                throw new RuntimeException(e);
    
            }catch(IllegalAccessException e){
    
                throw new RuntimeException(e);
    
            }
    
        }
    
    }
    
    
    
    class Filter extends Part {}
    
    
    
    class FuelFilter extends Filter {
    
        // Create a Class Factory for each specific type:
    
        public static class Factory
    
                implements typeinfo.factory.Factory<FuelFilter> {
    
            public FuelFilter create() { return new FuelFilter(); }
    
        }
    
    }
    
    
    
    class AirFilter extends Filter {
    
        public static class Factory
    
                implements typeinfo.factory.Factory<AirFilter> {
    
            public AirFilter create() { return new AirFilter(); }
    
        }
    
    }
    
    
    
    class CabinAirFilter extends Filter {
    
        public static class Factory
    
                implements typeinfo.factory.Factory<CabinAirFilter> {
    
            public CabinAirFilter create() {
    
                return new CabinAirFilter();
    
            }
    
        }
    
    }
    
    
    
    class OilFilter extends Filter {
    
        public static class Factory
    
                implements typeinfo.factory.Factory<OilFilter> {
    
            public OilFilter create() { return new OilFilter(); }
    
        }
    
    }
    
    
    
    class Belt extends Part {}
    
    
    
    class FanBelt extends Belt {
    
        public static class Factory
    
                implements typeinfo.factory.Factory<FanBelt> {
    
            public FanBelt create() { return new FanBelt(); }
    
        }
    
    }
    
    
    
    class GeneratorBelt extends Belt {
    
        public static class Factory
    
                implements typeinfo.factory.Factory<GeneratorBelt> {
    
            public GeneratorBelt create() {
    
                return new GeneratorBelt();
    
            }
    
        }
    
    }
    
    
    
    class PowerSteeringBelt extends Belt {
    
        public static class Factory
    
                implements typeinfo.factory.Factory<PowerSteeringBelt> {
    
            public PowerSteeringBelt create() {
    
                return new PowerSteeringBelt();
    
            }
    
        }
    
    }
    
    
    
    public class Main {
    
        public static void main(String[] args) {
    
            for(int i = 0; i < 10; i++)
    
                System.out.println(Part.createRandom());
    
        }
    
    }
    
    
    
    
    
    

    15 Implement a new PetCreator using Registered Factories, and modify the Pets Facade so that it uses this one instead of the other two. Ensure that the rest of the examples that use Pets.java still work correctly.

    package job;
    import typeinfo.pets.*;
    
    import typeinfo.factory.*;
    import java.util.*;
    
    public class PetFactory{
    
        static List<Factory<? extends Pet>> petFactories=new ArrayList<Factory<? extends Pet>>();
    
        static{
    
            //System.out.println(new Rodent.Factory());
    
            petFactories.add(new Pet.Factory());
    
            petFactories.add(new Cat.Factory());
    
            petFactories.add(new Cymric.Factory());
    
            petFactories.add(new Dog.Factory());
    
            petFactories.add(new EgyptianMau.Factory());
    
            //petFactories.add(new Gerbil.Factory());
    
            //petFactories.add(new Hamster.Factory());
    
            petFactories.add(new Manx.Factory());
    
            //petFactories.add(new Mouse.Factory());
    
            petFactories.add(new Mutt.Factory());
    
            petFactories.add(new Pug.Factory());
    
            //petFactories.add(new Rat.Factory());
    
            //petFactories.add(new Rodent.Factory());//!无法找到??
    
        }
    
        private static Random rand=new Random(55);
    
        public static Pet createRandom(){
    
            return petFactories.get(rand.nextInt(petFactories.size())).create();
    
        }
    
        public static void main(String[] args){
    
            for(int i=0;i<10;i++)
    
                System.out.println(PetFactory.createRandom());
    
        }
    
    }
    
    
    
    import typeinfo.pets.*;
    
            import java.util.*;
    
    
    
    public class Pets {
    
        public static final PetCreator creator =
    
                new LiteralPetCreator();
    
        public static Pet randomPet() {
    
            return PetFactory.createRandom()/*.randomPet()*/;
    
        }
    
        public static Pet[] createArray(int size) {
    
            return creator.createArray(size);
    
        }
    
        public static ArrayList<Pet> arrayList(int size) {
    
            return creator.arrayList(size);
    
        }
    
        public static void main(String[] args){
    
            for(int i=0;i<10;i++)
    
                System.out.println(Pets.randomPet());
    
        }
    
    }
    

    16 Modify the Coffee hierarchy in the Generics chapter to use Registered Factories.

    package job;
    import typeinfo.factory.*;
    
    import generics.coffee.*;
    
    import java.util.*;
    
    public class Ja14_16 implements Generator<Coffee>, Iterable<Coffee>{
    
        private static List<Factory<? extends Coffee>> coFactory=new ArrayList<Factory<? extends Coffee>>();
    
        static{
    
            coFactory.add(new Coffee.Factory());
    
            coFactory.add(new Americano.Factory());
    
            coFactory.add(new Breve.Factory());
    
            coFactory.add(new Cappuccino.Factory());
    
            coFactory.add(new Latte.Factory());
    
            coFactory.add(new Mocha.Factory());
    
        }
    
        private static Random rand = new Random(66);
    
        public Ja14_16() {}
    
        private int size = 0;
    
        public Ja14_16(int sz) { size = sz; }
    
        public Coffee next() {
    
            try {
    
                return (Coffee)
    
                        coFactory.get(rand.nextInt(coFactory.size())).create();
    
                // Report programmer errors at run time:
    
            } catch(Exception e) {
    
                throw new RuntimeException(e);
    
            }
    
        }
    
        class CoffeeIterator implements Iterator<Coffee> {
    
            int count = size;
    
            public boolean hasNext() { return count > 0; }
    
            public Coffee next() {
    
                count--;
    
                return Ja14_16.this.next();
    
            }
    
            public void remove() { // Not implemented
    
                throw new UnsupportedOperationException();
    
            }
    
        };
    
        public Iterator<Coffee> iterator() {
    
            return new CoffeeIterator();
    
        }
    
        public static void main(String[] args) {
    
            Ja14_16 gen = new Ja14_16();
    
            for(int i = 0; i < 5; i++)
    
                System.out.println(gen.next());
    
            for(Coffee c : new Ja14_16(5))
    
                System.out.println(c);
    
        }
    
    
    
    }
    
     
    

    17 Modify the regular expression in ShowMethods.java to additionally strip off the keywords native and final (hint: us the OR operator '|').

    
    import java.lang.reflect.*;
    
    import java.util.regex.*;
    
    import static net.mindview.util.Print.*;
    
     
    
    public class Ja14_17 {
    
      private static String usage =
    
        "usage:\n" +
    
        "ShowMethods qualified.class.name\n" +
    
        "To show all methods in class or:\n" +
    
        "ShowMethods qualified.class.name word\n" +
    
        "To search for methods involving 'word'";
    
      private static Pattern p = Pattern.compile("(\\w+\\.)|(final)|(native)");
    
      public static void main(String[] args) {
    
        if(args.length < 1) {
    
          print(usage);
    
          System.exit(0);
    
        }
    
        int lines = 0;
    
        try {
    
          Class<?> c = Class.forName(args[0]);
    
          Method[] methods = c.getMethods();
    
          Constructor[] ctors = c.getConstructors();
    
          if(args.length == 1) {
    
            for(Method method : methods)
    
              print(
    
                p.matcher(method.toString()).replaceAll(""));
    
            for(Constructor ctor : ctors)
    
              print(p.matcher(ctor.toString()).replaceAll(""));
    
            lines = methods.length + ctors.length;
    
          } else {
    
            for(Method method : methods)
    
              if(method.toString().indexOf(args[1]) != -1) {
    
                print(
    
                  p.matcher(method.toString()).replaceAll(""));
    
                lines++;
    
              }
    
            for(Constructor ctor : ctors)
    
              if(ctor.toString().indexOf(args[1]) != -1) {
    
                print(p.matcher(
    
                  ctor.toString()).replaceAll(""));
    
                lines++;
    
              }
    
          }
    
        } catch(ClassNotFoundException e) {
    
          print("No such class: " + e);
    
        }
    
      }
    
    } 
    

    18 Make ShowMethods a non-public class and verify that the synthesized default constructor no longer shows up in the output.

    
    import java.lang.reflect.*;
    
    import java.util.regex.*;
    
    import static net.mindview.util.Print.*;
    
     
    
    class Ja14_18 {
    
      private static String usage =
    
        "usage:\n" +
    
        "ShowMethods qualified.class.name\n" +
    
        "To show all methods in class or:\n" +
    
        "ShowMethods qualified.class.name word\n" +
    
        "To search for methods involving 'word'";
    
      private static Pattern p = Pattern.compile("\\w+\\.");
    
      public static void main(String[] args) {
    
        if(args.length < 1) {
    
          print(usage);
    
          System.exit(0);
    
        }
    
        int lines = 0;
    
        try {
    
          Class<?> c = Class.forName(args[0]);
    
          Method[] methods = c.getMethods();
    
          Constructor[] ctors = c.getConstructors();
    
          if(args.length == 1) {
    
            for(Method method : methods)
    
              print(
    
                p.matcher(method.toString()).replaceAll(""));
    
            for(Constructor ctor : ctors)
    
              print(p.matcher(ctor.toString()).replaceAll(""));
    
            lines = methods.length + ctors.length;
    
          } else {
    
            for(Method method : methods)
    
              if(method.toString().indexOf(args[1]) != -1) {
    
                print(
    
                  p.matcher(method.toString()).replaceAll(""));
    
                lines++;
    
              }
    
            for(Constructor ctor : ctors)
    
              if(ctor.toString().indexOf(args[1]) != -1) {
    
                print(p.matcher(
    
                  ctor.toString()).replaceAll(""));
    
                lines++;
    
              }
    
          }
    
        } catch(ClassNotFoundException e) {
    
          print("No such class: " + e);
    
        }
    
      }
    
    } 
    

    19 In ToyTest.java, use reflection to create a Toy object using the non-default constructor.

    import typeinfo.toys.*;
    
    import static net.mindview.util.Print.*;
    
    import java.lang.reflect.*;
    
     
    
    interface HasBatteries {}
    
    interface Waterproof {}
    
    interface Shoots {}
    
     
    
    class Toy {
    
      // Comment out the following default constructor
    
      // to see NoSuchMethodError from (*1*)
    
      Toy() {}
    
      Toy(int i) {print("sda");}
    
      public String toString(){
    
        return "it's Toy";
    
      }
    
    }
    
     
    
    class FancyToy extends Toy
    
    implements HasBatteries, Waterproof, Shoots {
    
      FancyToy() { super(1); }
    
    }
    
     
    
    public class Ja14_19 {
    
      static void printInfo(Class cc) {
    
        print("Class name: " + cc.getName() +
    
          " is interface? [" + cc.isInterface() + "]");
    
        print("Simple name: " + cc.getSimpleName());
    
        print("Canonical name : " + cc.getCanonicalName());
    
      }
    
      public static void main(String[] args) {
    
        /*Class c = null;
    
        try {
    
          c = Class.forName("typeinfo.toys.FancyToy");
    
        } catch(ClassNotFoundException e) {
    
          print("Can't find FancyToy");
    
          System.exit(1);
    
        }
    
    
    
        printInfo(c);	
    
        for(Class face : c.getInterfaces())
    
          printInfo(face);
    
        Class up = c.getSuperclass();
    
        Object obj = null;
    
        try {
    
          // Requires default constructor:
    
          obj = up.newInstance();
    
        } catch(InstantiationException e) {
    
          print("Cannot instantiate");
    
          System.exit(1);
    
        } catch(IllegalAccessException e) {
    
          print("Cannot access");
    
          System.exit(1);
    
        }
    
        printInfo(obj.getClass());*/
    
        try{
    
            print(Toy.class.getDeclaredConstructor(int.class).newInstance(1));
    
        }catch(Exception e){
    
            throw new RuntimeException(e);    
    
        }
    
        }
    
    } 
    

    20 Look up the interface for java.lang.Class in the JDK decumentation from http://java.sun.com. Write a program that takes the name of a class as a command line argument, then uses the Class methods to dump all the information available for that class. Test your prgram with a standard* library class and a class you create.

    import static net.mindview.util.Print.*;
    
    import java.lang.reflect.*;
    
    import java.lang.annotation.*;
    
    public class Ja14_20{
    
        public static void main(String[] args){
    
            if(args.length<1)System.exit(0);
    
            Class<?> c=null;
    
            try{
    
                c=Class.forName(args[0]);
    
            }catch(Exception e){
    
                throw new RuntimeException(e);
    
            }
    
            for(Annotation a:c.getAnnotations())print(a);
    
            for(Constructor a:c.getConstructors())print(a);
    
            for(Field a:c.getFields())print(a);
    
            //for(Method a:c.getMethods())print(a);
    
            for(Class a:c.getClasses())print(a);
    
            for(Annotation a : c.getDeclaredAnnotations())
    
    			print(a);
    
            for(Method m : c.getDeclaredMethods())
    
    			print(m);
    
            for(Type t : c.getGenericInterfaces())
    
    			print(t);
    
    		print("c.isInterface(): " + c.isInterface());
    
            
    
    		print("c.getTypeParameters(): " + c.getTypeParameters());
    
            		print("c.isAnnotation(): " + c.isAnnotation());
    
    		print("c.isAnnotationPresent(Documented.class): " + c.isAnnotationPresent(Documented.class));
    
    		print("c.isAnonymousClass(): " + c.isAnonymousClass());
    
    		print("c.isArray(): " + c.isArray());
    
    		print("c.isAssignableFrom(Object.class): " + c.isAssignableFrom(Object.class));
    
    		print("c.isEnum(): " + c.isEnum());
    
    		print("c.isInstance(Object.class): " + c.isInstance(Object.class));
    
    		print("c.isInterface(): " + c.isInterface());
    
    		print("c.isLocalClass(): " + c.isLocalClass());
    
    		print("c.isMemberClass(): " + c.isMemberClass());
    
    		print("c.isPrimitive(): " + c.isPrimitive());
    
    		print("c.isSynthetic(): " + c.isSynthetic());		
    
            
    
        }
    
    }
    

    21 Modify SimpleProxyDemo.java so that it measures method-call times.

    import static net.mindview.util.Print.*;
    
     
    
    interface Interface {
    
      void doSomething();
    
      void somethingElse(String arg);
    
    }
    
     
    
    class RealObject implements Interface {
    
      public void doSomething() { print("doSomething"); }
    
      public void somethingElse(String arg) {
    
        print("somethingElse " + arg);
    
      }
    
    }	
    
     
    
    class SimpleProxy implements Interface {
    
        private static int count=0;
    
        private static int scount=0;
    
      private Interface proxied;
    
      public SimpleProxy(Interface proxied) {
    
        this.proxied = proxied;
    
      }
    
      public void doSomething() {
    
        print("SimpleProxy doSomething");
    
        proxied.doSomething();
    
        print(++count);
    
      }
    
      public void somethingElse(String arg) {
    
        print("SimpleProxy somethingElse " + arg);
    
        proxied.somethingElse(arg);
    
        print(++scount);
    
      }
    
    }	
    
     
    
    class Ja14_21 {
    
      public static void consumer(Interface iface) {
    
        iface.doSomething();
    
        iface.somethingElse("bonobo");
    
      }
    
      public static void main(String[] args) {
    
        consumer(new RealObject());
    
        consumer(new SimpleProxy(new RealObject()));
    
      }
    
    }
    

    22 Modify SimpleDynamicProxy.java so that it measures method-call times.

    import java.lang.reflect.*;
    
     
    
    class DynamicProxyHandler implements InvocationHandler {
    
      private Object proxied;
    
      public DynamicProxyHandler(Object proxied) {
    
        this.proxied = proxied;
    
      }
    
      public Object
    
      invoke(Object proxy, Method method, Object[] args)
    
      throws Throwable {
    
        System.out.println("**** proxy: " + proxy.getClass() +
    
          ", method: " + method + ", args: " + args);
    
        if(args != null)
    
          for(Object arg : args)
    
            System.out.println("  " + arg);
    
        return method.invoke(proxied, args);
    
      }
    
    }	
    
     
    
    class Ja14_22 {
    
      public static void consumer(Interface iface) {
    
        iface.doSomething();
    
        iface.somethingElse("bonobo");
    
      }
    
      public static void main(String[] args) {
    
        RealObject real = new RealObject();
    
        SimpleProxy sim=new SimpleProxy(real);
    
        consumer(sim);
    
        // Insert a proxy and call again:
    
        Interface proxy = (Interface)Proxy.newProxyInstance(
    
          Interface.class.getClassLoader(),
    
          new Class[]{ Interface.class },
    
          new DynamicProxyHandler(sim));
    
        consumer(proxy);
    
      }
    
    }
    

    23 Inside invoke() in SimpleDynamicProxy.java, try to print the proxy argument and explain what happens.

    import java.lang.reflect.*;
    
     
    
    class DynamicProxyHandler implements InvocationHandler {
    
      private Object proxied;
    
      public DynamicProxyHandler(Object proxied) {
    
        this.proxied = proxied;
    
      }
    
      public Object  invoke(Object proxy, Method method, Object[] args) throws Throwable {
    
        System.out.println("**** proxy: " + proxy.getClass() +
    
          ", method: " + method + ", args: " + args);
    
        if(args != null)
    
          for(Object arg : args)
    
            System.out.println("  " + arg);
    
        System.out.println(proxy);
    
        return method.invoke(proxied, args);
    
      }
    
    }	
    
     
    
    class Ja14_23 {
    
      public static void consumer(Interface iface) {
    
        iface.doSomething();
    
        iface.somethingElse("bonobo");
    
      }
    
      public static void main(String[] args) {
    
        RealObject real = new RealObject();
    
        SimpleProxy sim=new SimpleProxy(real);
    
        consumer(sim);
    
        // Insert a proxy and call again:
    
        Interface proxy = (Interface)Proxy.newProxyInstance(
    
          Interface.class.getClassLoader(),
    
          new Class[]{ Interface.class },
    
          new DynamicProxyHandler(sim));
    
        consumer(proxy);
    
      }
    
    }
    
    //invoke调用print打印proxy,print操作又会调用invoke,产生了无限循环。
    

    24 Add Null Objects to RegisteredFactories.java.

    import typeinfo.factory.*;
    
    import java.util.*;
    
     
    
    class Part {
    
      public String toString() {
    
        return getClass().getSimpleName();
    
      }
    
      static List<Factory<? extends Part>> partFactories =
    
        new ArrayList<Factory<? extends Part>>();	
    
      static {
    
        // Collections.addAll() gives an "unchecked generic
    
        // array creation ... for varargs parameter" warning.
    
        partFactories.add(new FuelFilter.Factory());
    
        partFactories.add(new AirFilter.Factory());
    
        partFactories.add(new CabinAirFilter.Factory());
    
        partFactories.add(new OilFilter.Factory());
    
        partFactories.add(new FanBelt.Factory());
    
        partFactories.add(new PowerSteeringBelt.Factory());
    
        partFactories.add(new GeneratorBelt.Factory());
    
        partFactories.add(new NullPart.Factory());
    
      }
    
      private static Random rand = new Random(66);
    
      public static Part createRandom() {
    
        int n = rand.nextInt(partFactories.size());
    
        return partFactories.get(n).create();
    
      }
    
    }	
    
    interface Null{}
    
    class NullPart extends Part implements Null{
    
        public final static Part NULL=new NullPart();
    
        public static class Factory implements typeinfo.factory.Factory<NullPart>{
    
            public NullPart create(){return (NullPart)NULL;}
    
        }
    
        public String toString(){return "it's NullPart";}
    
    }
    
    class Filter extends Part {}
    
     
    
    class FuelFilter extends Filter {
    
      // Create a Class Factory for each specific type:
    
      public static class Factory  implements typeinfo.factory.Factory<FuelFilter> {
    
        public FuelFilter create() { return new FuelFilter(); }
    
      }
    
    }
    
     
    
    class AirFilter extends Filter {
    
      public static class Factory
    
      implements typeinfo.factory.Factory<AirFilter> {
    
        public AirFilter create() { return new AirFilter(); }
    
      }
    
    }	
    
     
    
    class CabinAirFilter extends Filter {
    
      public static class Factory
    
      implements typeinfo.factory.Factory<CabinAirFilter> {
    
        public CabinAirFilter create() {
    
          return new CabinAirFilter();
    
        }
    
      }
    
    }
    
     
    
    class OilFilter extends Filter {
    
      public static class Factory
    
      implements typeinfo.factory.Factory<OilFilter> {
    
        public OilFilter create() { return new OilFilter(); }
    
      }
    
    }	
    
     
    
    class Belt extends Part {}
    
     
    
    class FanBelt extends Belt {
    
      public static class Factory
    
      implements typeinfo.factory.Factory<FanBelt> {
    
        public FanBelt create() { return new FanBelt(); }
    
      }
    
    }
    
     
    
    class GeneratorBelt extends Belt {
    
      public static class Factory
    
      implements typeinfo.factory.Factory<GeneratorBelt> {
    
        public GeneratorBelt create() {
    
          return new GeneratorBelt();
    
        }
    
      }
    
    }	
    
     
    
    class PowerSteeringBelt extends Belt {
    
      public static class Factory
    
      implements typeinfo.factory.Factory<PowerSteeringBelt> {
    
        public PowerSteeringBelt create() {
    
          return new PowerSteeringBelt();
    
        }
    
      }
    
    }	
    
     
    
    public class Ja14_24 {
    
      public static void main(String[] args) {
    
        for(int i = 0; i < 10; i++)
    
          System.out.println(Part.createRandom());
    
      }
    
    } 
    

    25 Create a class containing private, protected and package-access methods. * Write code to access these methods from outside of the class's package.

    import static net.mindview.util.Print.*;
    
    import java.lang.reflect.*;
    
    import typeinfo.packageaccess.*;
    
    public class Ja14_25{
    
        public static void main(String[] agrs){
    
            DD d=new DD();
    
            try{
    
                Method u=d.getClass().getDeclaredMethod("u");
    
                u.setAccessible(true);
    
            u.invoke(d);
    
            }catch(Exception e){throw new RuntimeException(e);}
    
            
    
     
    
        }
    
    }
    

    26 Implement clearSpitValve() as described in the summary.

    import polymorphism.music.Note;
    
    import java.util.*;
    
    import static net.mindview.util.Print.*;
    
     
    
    class Instrument {
    
    	void play(Note n) { print("Instrument.play() " + n); }
    
    	public String toString() { return "Instrument"; }
    
    	void adjust() { print("Adjusting Instrument"); }
    
    }
    
     
    
    class Wind extends Instrument {
    
    	void play(Note n) { print("Wind.play() " + n); }
    
    	public String toString() { return "Wind"; }
    
    	void adjust() { print("Adjusting Wind"); }
    
    	void clearSpitValve() { print("Wind clearing spit valve"); }
    
    }
    
     
    
    class Percussion extends Instrument {
    
    	void play(Note n) { print("Percussion.play() " + n); }
    
    	public String toString() { return "Percussion"; }
    
    	void adjust() { print("Adjusting Percussion"); } 
    
    }
    
     
    
    class Stringed extends Instrument {
    
    	void play(Note n) { print("Stringed.play() " + n); }
    
    	public String toString() { return "Stringed"; }
    
    	void adjust() { print("Adjusting Stringed"); } 
    
    }
    
     
    
    class Keyboard extends Instrument {
    
    	void play(Note n) { print("Keyboard.play() " + n); }
    
    	public String toString() { return "Keyboard"; }
    
    	void adjust() { print("Adjusting Keyboard"); } 
    
    }
    
     
    
    class Brass extends Wind {
    
    	void play(Note n) { print("Brass.play() " + n); }
    
    	public String toString() { return "Brass"; }
    
    	void adjust() { print("Adjusting Brass"); }
    
    	void clearSpitValve() { print("Brass clearing spit valve"); }
    
    }
    
     
    
    class Woodwind extends Wind {
    
    	void play(Note n) { print("Woodwind.play() " + n); }
    
    	public String toString() { return "Woodwind"; }
    
    	void clearSpitValve() { print("Woodwind clearing spit valve"); }
    
    }
    
     
    
    class Piano extends Keyboard {
    
    	void play(Note n) { print("Piano.play() " + n); }
    
    	public String toString() { return "Piano"; }
    
    }
    
     
    
     class RandomInstrumentGenerator {
    
    	private Random rand = new Random();
    
    	public Instrument next() {
    
    		switch(rand.nextInt(7)) {
    
    			default:
    
    			case 0: return new Wind();
    
    			case 1: return new Percussion();
    
    			case 2: return new Stringed();
    
    			case 3: return new Keyboard();
    
    			case 4: return new Brass();
    
    			case 5: return new Woodwind();
    
    			case 6: return new Piano();
    
    		}
    
    	}
    
     }
    
    public class Ja14_26 {
    
    	// Doesn't care about type, so new types
    
    	// added to the system still work right:
    
    	public static void tune(Instrument i) {
    
    		//...
    
    		i.play(Note.MIDDLE_C);
    
    	}
    
    	public static void tuneAll(Instrument[] e) {
    
    		for(Instrument i : e)
    
    			tune(i);
    
    	}
    
    	private static RandomInstrumentGenerator gen = new RandomInstrumentGenerator();	
    
    	public static void main(String[] args) {
    
    		// Upcasting during addition to the array:
    
    		Instrument[] orchestra = new Instrument[20];
    
    		// fill up orchestra array wth instruments:
    
    		for(int i = 0; i < orchestra.length; i++)
    
    			orchestra[i] = gen.next();
    
    		for(Instrument i : orchestra) {
    
    			if(i instanceof Wind) // get RTTI
    
    				((Wind)i).clearSpitValve();
    
    			i.adjust();
    
    		}
    
    		tuneAll(orchestra);
    
    	}
    
    }
    

     

    展开全文
  • Java网络编程面试题

    千次阅读 2019-09-24 07:31:04
    Java网络编程面试题 1、tcp和udp的区别1 2、tcp连接建立的时候3次握手,断开连接的4次握手的具体过程1 3、什么是同步?什么是异步?2 4、.什么是阻塞?什么是非阻塞?5 5、什么是阻塞IO?什么...

     

    1、tcp和udp的区别 1

    2、tcp连接建立的时候3次握手,断开连接的4次握手的具体过程 1

    3、什么是同步?什么是异步? 2

    4、.什么是阻塞?什么是非阻塞? 5

    5、什么是阻塞IO?什么是非阻塞IO? 6

    6、什么是同步IO?什么是异步IO? 7

    7、 IO模型有几种?分别是什么? 8

    8、 Reactor和Proactor IO设计模式是什么? 13

    9、Java NIO 中的Buffer是什么?如何使用? 16

    10、Nio buffer 的内部结构是什么? 17

    11、Java NIO 中的 Channel是什么?有什么特点? 18

    12、Java NIO中的Selector是什么? 21

    13、简单讲一下文件IO中的Path和Files 22

    14、select、poll和epoll的区别 23

    15、网络编程中设计并发服务器,使用多进程 与 多线程 ,请问有什么区别? 29

    15、网络编程的一般步骤 29

    16、TCP的全称是? 31

    17、UDP的全称是? 31

    18、请说出TCP和UDP的区别? 31

    19、TCP为什么不是两次连接?而是三次握手? 33

    20、说明socket是什么? 34

    21、为什么需要端口?端口是真实存在的还是虚拟的概念? 35

    22、Java中,端口使用两个字节表示,可以表示多少个端口? UDP和TCP端口是各自独立的吗? 35

    23、URL类有什么作用? 35

    24、基于TCP的Socket网络编程的主要步骤是什么? 36

    25、【上机】写出建立TCP服务器ServerSocket的代码。并说明accept方法有什么特点? 37

    26、【上机】写出建立TCP客户端Socket的代码。并说明建立Socket后,通过什么方法Socket获得流对象? 37

    27、基于UDP的Socket网络编程的主要步骤是什么? 37

    28、【上机】使用UDP的方式,完成对象的传递。 38

    29、HTTPClient相关问题 39

    30、NIO 和传统 BIO区别是什么? 40

    31、Java NIO 的几个核心组成部分是什么?作用分别是什么? 41

    32、简单说一下http协议? 47

    33、http协议下客户端请求报文是什么? 48

    34、描述一下http协议服务器响应报文有哪些? 49

    35、HTTP协议中常用的请求方法有哪些 50

    36、常见的HTTP状态码有哪些 51

    37、HTTP 协议中content-type指的是什么? 55

    38、网络传输协议本质和作用是什么? 65

    39、可以实现一个简单的网络协议吗? 65

     

     

    1tcp和udp的区别 

    TCP:是面向连接的流传输控制协议,具有高可靠性,确保传输数据的正确性,有验证重发机制,因此不会出现丢失或乱序。

    UDP:是无连接的数据报服务,不对数据报进行检查与修改,无须等待对方的应答,会出现分组丢失、重复、乱序,但具有较好的实时性,UDP段结构比TCP的段结构简单,因此网络开销也小。

    2、tcp连接建立的时候3次握手,断开连接的4次握手的具体过程

    1. 建立连接采用的3次握手协议,具体是指:

    l 第一次握手是客户端connect连接到server

    l 第二次server accept client的请求之后,向client端发送一个消息,相当于说我都准备好了,你连接上我了

    l 第三次 就是client向server发送的,就是对第二次握手消息的确认。之后client和server就开始通讯了。

    2.断开连接的4次握手,具体如下:

    l 断开连接的一端发送close请求是第一次握手

    l 另外一端接收到断开连接的请求之后需要对close进行确认,发送一个消息,这是第二次握手

    l 发送了确认消息之后还要向对端发送close消息,要关闭对对端的连接,这是第3次握手

    l 而在最初发送断开连接的一端接收到消息之后,进入到一个很重要的状态time_wait状态,这个状态也是面试官经常问道的问题,最后一次握手是最初发送断开连接的一端接收到消息之后。对消息的确认。

    3、什么是同步?什么是异步?

    同步:

    如果有多个任务或者事件要发生,这些任务或者事件必须逐个地进行,一个事件或者任务的执行会导致整个流程的暂时等待,这些事件没有办法并发地执行;

    异步:

    如果有多个任务或者事件发生,这些事件可以并发地执行一个事件或者任务的执行不会导致整个流程的暂时等待。

    这就是同步和异步。

    举个简单的例子,假如有一个任务包括两个子任务A和B,对于同步来说,当A在执行的过程中,B只有等待,直至A执行完毕,B才能执行;而对于异步就是A和B可以并发地执行,B不必等待A执行完毕之后再执行,这样就不会由于A的执行导致整个任务的暂时等待。

     

    如果还不理解,可以先看下面这2段代码:

    void fun1() {

    }

     

    void fun2() {

    }

     

    void function(){

        fun1();

        fun2()

        .....

        .....

    }

    这段代码就是典型的同步,在方法function中,fun1在执行的过程中会导致后续的fun2无法执行,fun2必须等待fun1执行完毕才可以执行。

     

    接着看下面这段代码:

    void fun1() {

    }

     

    void fun2() {

    }

     

    void function(){

        new Thread(){

        public void run() {

            fun1();

        }

    }.start();

     

    new Thread(){

        public void run() {

            fun2();

        }

    }.start();

    .....

    .....

    }

    这段代码是一种典型的异步,fun1的执行不会影响到fun2的执行,并且fun1和fun2的执行不会导致其后续的执行过程处于暂时的等待。

     

    事实上,同步和异步是一个非常广的概念,它们的重点在于多个任务和事件发生时,一个事件的发生或执行是否会导致整个流程的暂时等待。我觉得可以将同步和异步与Java中的synchronized关键字联系起来进行类比。当多个线程同时访问一个变量时,每个线程访问该变量就是一个事件,对于同步来说,就是这些线程必须逐个地来访问该变量,一个线程在访问该变量的过程中,其他线程必须等待;而对于异步来说,就是多个线程不必逐个地访问该变量,可以同时进行访问。

     

    同步和异步可以表现在很多方面,但是记住其关键在于多个任务和事件发生时,一个事件的发生或执行是否会导致整个流程的暂时等待。一般来说,可以通过多线程的方式来实现异步,但是千万记住不要将多线程和异步画上等号,异步只是宏观上的一个模式,采用多线程来实现异步只是一种手段,并且通过多进程的方式也可以实现异步。同步和异步着重点在于多个任务的执行过程中,一个任务的执行是否会导致整个流程的暂时等待

    4、.什么是阻塞?什么是非阻塞?

    阻塞:

    当某个事件或者任务在执行过程中,它发出一个请求操作,但是由于该请求操作需要的条件不满足,那么就会一直在那等待,直至条件满足;

    非阻塞:

    当某个事件或者任务在执行过程中,它发出一个请求操作,如果该请求操作需要的条件不满足,会立即返回一个标志信息告知条件不满足,不会一直在那等待

    举个简单的例子:

    假如我要读取一个文件中的内容,如果此时文件中没有内容可读,对于同步来说就是会一直在那等待,直至文件中有内容可读;而对于非阻塞来说,就会直接返回一个标志信息告知文件中暂时无内容可读。

    阻塞和非阻塞着重点在于发出一个请求操作时,如果进行操作的条件不满足是否会返会一个标志信息告知条件不满足。理解阻塞和非阻塞可以同线程阻塞类比地理解,当一个线程进行一个请求操作时,如果条件不满足,则会被阻塞,即在那等待条件满足。

     

    5、什么是阻塞IO?什么是非阻塞IO?

    在了解阻塞IO和非阻塞IO之前,先看下一个具体的IO操作过程是怎么进行的。

    通常来说,IO操作包括:对硬盘的读写、对socket的读写以及外设的读写。

    当用户线程发起一个IO请求操作(本文以读请求操作为例),内核会去查看要读取的数据是否就绪,对于阻塞IO来说,如果数据没有就绪,则会一直在那等待,直到数据就绪;对于非阻塞IO来说,如果数据没有就绪,则会返回一个标志信息告知用户线程当前要读的数据没有就绪。当数据就绪之后,便将数据拷贝到用户线程,这样才完成了一个完整的IO读请求操作,也就是说一个完整的IO读请求操作包括两个阶段:

    1)查看数据是否就绪;

    2)进行数据拷贝(内核将数据拷贝到用户线程)。

    那么阻塞(blocking IO)和非阻塞(non-blocking IO)的区别就在于第一个阶段,如果数据没有就绪,在查看数据是否就绪的过程中是一直等待,还是直接返回一个标志信息

    Java中传统的IO都是阻塞IO,比如通过socket来读数据,调用read()方法之后,如果数据没有就绪,当前线程就会一直阻塞在read方法调用那里,直到有数据才返回;

    而如果是非阻塞IO的话,当数据没有就绪,read()方法应该返回一个标志信息,告知当前线程数据没有就绪,而不是一直在那里等待。

    6、什么是同步IO?什么是异步IO?

    我们先来看一下同步IO和异步IO的定义,在《Unix网络编程》一书中对同步IO和异步IO的定义是这样的:

    A synchronous I/O operation causes the requesting process to be blocked until that I/O operation completes.

    An asynchronous I/O operation does not cause the requesting process to be blocked.

    从字面的意思可以看出:同步IO即 如果一个线程请求进行IO操作,在IO操作完成之前,该线程会被阻塞;而异步IO为 如果一个线程请求进行IO操作,IO操作不会导致请求线程被阻塞。

    事实上,同步IO和异步IO模型是针对用户线程和内核的交互来说的:

    对于同步IO:当用户发出IO请求操作之后,如果数据没有就绪,需要通过用户线程或者内核不断地去轮询数据是否就绪,当数据就绪时,再将数据从内核拷贝到用户线程;

    而异步IO:只有IO请求操作的发出是由用户线程来进行的,IO操作的两个阶段都是由内核自动完成,然后发送通知告知用户线程IO操作已经完成。也就是说在异步IO中,不会对用户线程产生任何阻塞。

    这是同步IO和异步IO关键区别所在,同步IO和异步IO的关键区别反映在数据拷贝阶段是由用户线程完成还是内核完成。所以说异步IO必须要有操作系统的底层支持

    注意同步IO和异步IO与阻塞IO和非阻塞IO是不同的两组概念

    阻塞IO和非阻塞IO是反映在当用户请求IO操作时,如果数据没有就绪,是用户线程一直等待数据就绪,还是会收到一个标志信息这一点上面的。

    也就是说,阻塞IO和非阻塞IO是反映在IO操作的第一个阶段,在查看数据是否就绪时是如何处理的。

    7、 IO模型有几种?分别是什么?

    在《Unix网络编程》一书中提到了五种IO模型

    分别是:阻塞IO、非阻塞IO、多路复用IO、信号驱动IO以及异步IO。

    下面就分别来介绍一下这5种IO模型的异同。

    1.阻塞IO模型

    最传统的一种IO模型,即在读写数据过程中会发生阻塞现象。

    当用户线程发出IO请求之后,内核会去查看数据是否就绪,如果没有就绪就会等待数据就绪,而用户线程就会处于阻塞状态,用户线程交出CPU。当数据就绪之后,内核会将数据拷贝到用户线程,并返回结果给用户线程,用户线程才解除block状态。

    典型的阻塞IO模型的例子为:

    data = socket.read();

    如果数据没有就绪,就会一直阻塞在read方法。

    2.非阻塞IO模型

    当用户线程发起一个read操作后,并不需要等待,而是马上就得到了一个结果。如果结果是一个error时,它就知道数据还没有准备好,于是它可以再次发送read操作。一旦内核中的数据准备好了,并且又再次收到了用户线程的请求,那么它马上就将数据拷贝到了用户线程,然后返回。

    所以事实上,在非阻塞IO模型中,用户线程需要不断地询问内核数据是否就绪,也就说非阻塞IO不会交出CPU,而会一直占用CPU

     

    典型的非阻塞IO模型一般如下:

    伪代码

    while(true){

      new MyThread(socket)

    }

    class MyThread{

        data = socket.read();

        if(data!= error){

            处理数据

            break;

        }

     

    但是对于非阻塞IO就有一个非常严重的问题,在while循环中需要不断地去询问内核数据是否就绪,这样会导致CPU占用率非常高,因此一般情况下很少使用while循环这种方式来读取数据。

     

    3.多路复用IO模型

    多路复用IO模型是目前使用得比较多的模型。Java NIO实际上就是多路复用IO。

    在多路复用IO模型中,会有一个线程不断去轮询多个socket的状态,只有当socket真正有读写事件时,才真正调用实际的IO读写操作。因为在多路复用IO模型中,只需要使用一个线程就可以管理多个socket,系统不需要建立新的进程或者线程,也不必维护这些线程和进程,并且只有在真正有socket读写事件进行时,才会使用IO资源,所以它大大减少了资源占用。

      

    在Java NIO中,是通过selector.select()去查询每个通道是否有到达事件,如果没有事件,则一直阻塞在那里,因此这种方式会导致用户线程的阻塞。

    也许有朋友会说,我可以采用 多线程+ 阻塞IO 达到类似的效果,但是由于在多线程 + 阻塞IO 中,每个socket对应一个线程,这样会造成很大的资源占用,并且尤其是对于长连接来说,线程的资源一直不会释放,如果后面陆续有很多连接的话,就会造成性能上的瓶颈。

    而多路复用IO模式,通过一个线程就可以管理多个socket,只有当socket真正有读写事件发生才会占用资源来进行实际的读写操作。因此,多路复用IO比较适合连接数比较多的情况。

    另外多路复用IO为何比非阻塞IO模型的效率高是因为在非阻塞IO中,不断地询问socket状态时通过用户线程去进行的,而在多路复用IO中,轮询每个socket状态是内核在进行的,这个效率要比用户线程要高的多。

    不过要注意的是,多路复用IO模型是通过轮询的方式来检测是否有事件到达,并且对到达的事件逐一进行响应。因此对于多路复用IO模型来说,一旦事件响应体很大,那么就会导致后续的事件迟迟得不到处理,并且会影响新的事件轮询。

     

    4.信号驱动IO模型

    在信号驱动IO模型中,当用户线程发起一个IO请求操作,会给对应的socket注册一个信号函数,然后用户线程会继续执行,当内核数据就绪时会发送一个信号给用户线程,用户线程接收到信号之后,便在信号函数中调用IO读写操作来进行实际的IO请求操作。

    5.异步IO模型

    异步IO模型才是最理想的IO模型,在异步IO模型中,当用户线程发起read操作之后,立刻就可以开始去做其它的事。

    而另一方面,从内核的角度,当它受到一个asynchronous read之后,它会立刻返回,说明read请求已经成功发起了,因此不会对用户线程产生任何block。

    然后,内核会等待数据准备完成,然后将数据拷贝到用户线程,当这一切都完成之后,内核会给用户线程发送一个信号,告诉它read操作完成了。

    也就说用户线程完全不需要实际的整个IO操作是如何进行的,只需要先发起一个请求,当接收内核返回的成功信号时表示IO操作已经完成,可以直接去使用数据了。

    也就说在异步IO模型中,IO操作的两个阶段都不会阻塞用户线程,这两个阶段都是由内核自动完成,然后发送一个信号告知用户线程操作已完成。

    用户线程中不需要再次调用IO函数进行具体的读写。

    这点是和信号驱动模型有所不同的

    在信号驱动模型中,当用户线程接收到信号表示数据已经就绪,然后需要用户线程调用IO函数进行实际的读写操作;而在异步IO模型中,收到信号表示IO操作已经完成,不需要再在用户线程中调用iO函数进行实际的读写操作。

    注意,异步IO是需要操作系统的底层支持,在Java 7中,提供了Asynchronous IO。也就是java中的AIO

     

    前面四种IO模型实际上都属于同步IO,只有最后一种是真正的异步IO,因为无论是多路复用IO还是信号驱动模型,IO操作的第2个阶段都会引起用户线程阻塞,也就是内核进行数据拷贝的过程都会让用户线程阻塞。

    8、 Reactor和Proactor IO设计模式是什么?

    在传统的网络服务设计模式中,有两种比较经典的模式:一种是 多线程,一种是线程池。

    对于多线程模式,也就说来了client,服务器就会新建一个线程来处理该client的读写事件,如下图所示:

     

    这种模式虽然处理起来简单方便,但是由于服务器为每个client的连接都采用一个线程去处理,使得资源占用非常大。因此,当连接数量达到上限时,再有用户请求连接,直接会导致资源瓶颈,严重的可能会直接导致服务器崩溃。

     

    因此,为了解决这种一个线程对应一个客户端模式带来的问题提出了采用线程池的方式,也就说创建一个固定大小的线程池,来一个客户端,就从线程池取一个空闲线程来处理,当客户端处理完读写操作之后,就交出对线程的占用。因此这样就避免为每一个客户端都要创建线程带来的资源浪费,使得线程可以重用。

    但是线程池也有它的弊端,如果连接大多是长连接,因此可能会导致在一段时间内,线程池中的线程都被占用,那么当再有用户请求连接时,由于没有可用的空闲线程来处理,就会导致客户端连接失败,从而影响用户体验。因此,线程池比较适合大量的短连接应用。

    因此便出现了下面的两种高性能IO设计模式:Reactor和Proactor。

     

    Reactor模式中,会先对每个client注册感兴趣的事件,然后有一个线程专门去轮询每个client是否有事件发生,当有事件发生时,便顺序处理每个事件,当所有事件处理完之后,便再转去继续轮询,如下图所示:

     

    多路复用IO就是采用Reactor模式。注意,上面的图中展示的 是顺序处理每个事件,当然为了提高事件处理速度,可以通过多线程或者线程池的方式来处理事件。

     

    Proactor模式中,当检测到有事件发生时,会新起一个异步操作,然后交由内核线程去处理,当内核线程完成IO操作之后,发送一个通知告知操作已完成,可以得知,异步IO模型采用的就是Proactor模式。

    9、Java NIO 中的Buffer是什么?如何使用?

    Buffer(缓冲区):

    Java NIO Buffers用于和NIO Channel交互。 我们从Channel中读取数据到buffers里,从Buffer把数据写入到Channels;

    Buffer本质上就是一块内存区;

    一个Buffer有三个属性是必须掌握的,分别是:capacity容量、position位置、limit限制。

    Buffer的常见方法

    Buffer clear()

    Buffer flip()

    Buffer rewind()

    Buffer position(int newPosition)

    Buffer的使用方式/方法介绍:

    分配缓冲区(Allocating a Buffer):

    ByteBuffer buf = ByteBuffer.allocate(28);//以ByteBuffer为例子

    写入数据到缓冲区(Writing Data to a Buffer)

    写数据到Buffer有两种方法:

    1.从Channel中写数据到Buffer

    int bytesRead = inChannel.read(buf); //read into buffer.

    2.通过put写数据:

    buf.put(127);

    10、Nio buffer 的内部结构是什么?

     

    一个 buffer 主要由 position,limit,capacity 三个变量来控制读写的过程。此三个变量的含义见如下表格:

    参数

    写模式   

    读模式

    position

    当前写入的单位数据数量。

    当前读取的单位数据位置。

    limit

    代表最多能写多少单位数据和容量是一样的。

    代表最多能读多少单位数据,和之前写入的单位数据量一致。

    capacity

    buffer 容量

    buffer 容量

    Buffer 常见方法:

    flip(): 写模式转换成读模式

    rewind() :将 position 重置为 0 ,一般用于重复读。

    clear() :清空 buffer ,准备再次被写入 (position 变成 0 , limit 变成 capacity) 。

    compact(): 将未读取的数据拷贝到 buffer 的头部位。

    mark() 、 reset():mark 可以标记一个位置, reset 可以重置到该位置。

    Buffer 常见类型: ByteBuffer 、 MappedByteBuffer 、 CharBuffer 、 DoubleBuffer 、 FloatBuffer 、 IntBuffer 、LongBuffer 、 ShortBuffer 。

    channel 常见类型 :FileChannel 、 DatagramChannel(UDP) 、 SocketChannel(TCP) 、 ServerSocketChannel(TCP)

    11、Java NIO 中的 Channel是什么?有什么特点?

    Channel

    Java NIO中的SocketChannel是一个连接到TCP网络套接字的通道。

    可以通过以下2种方式创建SocketChannel:

    1. 打开一个SocketChannel并连接到互联网上的某台服务器。
    2. 一个新连接到达ServerSocketChannel时,会创建一个SocketChannel。

    打开 SocketChannel  下面是SocketChannel的打开方式:  

    SocketChannel socketChannel = SocketChannel.open();

    socketChannel.connect(new InetSocketAddress("http://jenkov.com", 80));

    关闭 SocketChannel  

    当用完SocketChannel之后调用SocketChannel.close()关闭SocketChannel:   socketChannel.close();

    从 SocketChannel 读取数据  

    要从SocketChannel中读取数据,调用一个read()的方法之一。

    ByteBuffer buf = ByteBuffer.allocate(48);

    int bytesRead = socketChannel.read(buf);

    非阻塞模式

    可以设置 SocketChannel 为非阻塞模式(non-blocking mode).设置之后,就可以在异步模式下调用connect(), read() 和write()了。

    如果SocketChannel在非阻塞模式下,此时调用connect(),该方法可能在连接建立之前就返回了。为了确定连接是否建立,可以调用finishConnect()的方法。

    像这样:

    socketChannel.configureBlocking(false);

    socketChannel.connect(new InetSocketAddress("http://jenkov.com", 80));

     

    while(! socketChannel.finishConnect() ){

        //wait, or do something else...

    }

    Java NIO Channel通道和流非常相似,主要有以下几点区别:

    l 通道可以读也可以写,流一般来说是单向的(只能读或者写,所以之前我们用流进行IO操作的时候需要分别创建一个输入流和一个输出流)。

    l 通道可以异步读写。

    l 通道总是基于缓冲区Buffer来读写。

    Java NIO中最重要的几个Channel的实现:

    l FileChannel: 用于文件的数据读写

    l DatagramChannel: 用于UDP的数据读写

    l SocketChannel: 用于TCP的数据读写,一般是客户端实现

    l ServerSocketChannel: 允许我们监听TCP链接请求,每个请求会创建会一个SocketChannel,一般是服务器实现

    类层次结构

     

    12、Java NIO中的Selector是什么?

    Selector(选择器):

    Selector 一般称 为选择器 ,当然你也可以翻译为 多路复用器 。

    它是Java NIO核心组件中的一个,用于检查一个或多个NIO Channel(通道)的状态是否处于可读、可写。

    如此可以实现单线程管理多个channels,也就是可以管理多个网络链接。

    使用Selector的好处在于: 使用更少的线程来就可以来处理通道了, 相比使用多个线程,避免了线程上下文切换带来的开销。

    Selector(选择器)的使用方法介绍

    Selector的创建

    Selector selector = Selector.open();

    注册Channel到Selector(Channel必须是非阻塞的)

    channel.configureBlocking(false);

    SelectionKey key = channel.register(selector, Selectionkey.OP_READ);

    SelectionKey介绍

    一个SelectionKey键表示了一个特定的通道对象和一个特定的选择器对象之间的注册关系。

    从Selector中选择channel(Selecting Channels via a Selector)

    选择器维护注册过的通道的集合,并且这种注册关系都被封装在SelectionKey当中.

    停止选择的方法

    wakeup()方法 和close()方法。

    13、简单讲一下文件IO中的Path和Files

    文件I/O基石:Path:

    创建一个Path

    File和Path之间的转换,File和URI之间的转换

    获取Path的相关信息

    移除Path中的冗余项

    Files类:

    Files.exists() 检测文件路径是否存在

    Files.createFile() 创建文件

    Files.createDirectories()和Files.createDirectory()创建文件夹

    Files.delete()方法 可以删除一个文件或目录

    Files.copy()方法可以吧一个文件从一个地址复制到另一个位置

    获取文件属性

    遍历一个文件夹

    Files.walkFileTree()遍历整个目录

     

    14、select、poll和epoll的区别

    在linux 没有实现epoll事件驱动机制之前,我们一般选择用select或者poll等IO多路复用的方法来实现并发服务程序。在大数据、高并发、集群等一些名词唱得火热之年代,select和poll的用武之地越来越有限,风头已经被epoll占尽。

    select的缺点:

    1. 单个进程能够监视的文件描述符的数量存在最大限制,通常是1024,当然可以更改数量,但由于select采用轮询的方式扫描文件描述符,文件描述符数量越多,性能越差;

    在linux内核头文件中,有这样的定义:

    #define __FD_SETSIZE    1024

    1. 内核 / 用户空间内存拷贝问题,select需要复制大量的句柄数据结构,产生巨大的开销;
    2. select返回的是含有整个句柄的数组,应用程序需要遍历整个数组才能发现哪些句柄发生了事件;
    3. select的触发方式是水平触发,应用程序如果没有完成对一个已经就绪的文件描述符进行IO操作,那么之后每次select调用还是会将这些文件描述符通知进程。

    相比select模型,poll使用链表保存文件描述符,因此没有了监视文件数量的限制,但其他三个缺点依然存在。

     

    拿select模型为例,假设我们的服务器需要支持100万的并发连接,则在__FD_SETSIZE 为1024的情况下,则我们至少需要开辟1k个进程才能实现100万的并发连接。

    除了进程间上下文切换的时间消耗外,从内核/用户空间大量的无脑内存拷贝、数组轮询等,是系统难以承受的。

    因此,基于select模型的服务器程序,要达到10万级别的并发访问,是一个很难完成的任务。

     

    epoll的实现机制与select/poll机制完全不同,上面所说的 select的缺点在epoll上不复存在。

    设想一下如下场景:

    有100万个客户端同时与一个服务器进程保持着TCP连接。而每一时刻,通常只有几百上千个TCP连接是活跃的(事实上大部分场景都是这种情况)。如何实现这样的高并发?

     

    在select/poll时代,服务器进程每次都把这100万个连接告诉操作系统(从用户态复制句柄数据结构到内核态),让操作系统内核去查询这些套接字上是否有事件发生,轮询完后,再将句柄数据复制到用户态,让服务器应用程序轮询处理已发生的网络事件,这一过程资源消耗较大,因此,select/poll一般只能处理几千的并发连接。

     

    epoll的设计和实现与select完全不同。

    epoll通过在Linux内核中申请一个简易的文件系统

    (文件系统一般用什么数据结构实现?B+树)

    把原先的select/poll调用分成了3个部分:

    1)调用epoll_create()建立一个epoll对象(在epoll文件系统中为这个句柄对象分配资源)

    2)调用epoll_ctl向epoll对象中添加这100万个连接的套接字

    3)调用epoll_wait收集发生的事件的连接

     

    如此一来,要实现上面说是的场景,只需要在进程启动时建立一个epoll对象,然后在需要的时候向这个epoll对象中添加或者删除连接。同时,epoll_wait的效率也非常高,因为调用epoll_wait时,并没有一股脑的向操作系统复制这100万个连接的句柄数据,内核也不需要去遍历全部的连接。

     

    下面来看看Linux内核具体的epoll机制实现思路。

     

    当某一进程调用epoll_create方法时,Linux内核会创建一个eventpoll结构体,这个结构体中有两个成员与epoll的使用方式密切相关。eventpoll结构体如下所示:

    struct eventpoll{    

    ....    

    /*红黑树的根节点,这颗树中存储着所有添加到epoll中的需要监控的事件*/    

    struct rb_root  rbr;

    /*双链表中则存放着将要通过epoll_wait返回给用户的满足条件的事件*/   

    struct list_head rdlist;  

      ....

    };

    每一个epoll对象都有一个独立的eventpoll结构体,用于存放通过epoll_ctl方法向epoll对象中添加进来的事件。这些事件都会挂载在红黑树中,如此,重复添加的事件就可以通过红黑树而高效的识别出来(红黑树的插入时间效率是lgn,其中n为树的高度)。

    所有添加到epoll中的事件都会与设备(网卡)驱动程序建立回调关系,也就是说,当相应的事件发生时会调用这个回调方法。这个回调方法在内核中叫ep_poll_callback,它会将发生的事件添加到rdlist双链表中。

    在epoll中,对于每一个事件,都会建立一个epitem结构体,如下所示:

    struct epitem{    

    struct rb_node  rbn;//红黑树节点    

    struct list_head    rdllink;//双向链表节点    

    struct epoll_filefd  ffd;  //事件句柄信息    

    struct eventpoll *ep;    //指向其所属的eventpoll对象    

    struct epoll_event event; //期待发生的事件类型

    }

    当调用epoll_wait检查是否有事件发生时,只需要检查eventpoll对象中的rdlist双链表中是否有epitem元素即可。如果rdlist不为空,则把发生的事件复制到用户态,同时将事件数量返回给用户。

     

    通过红黑树和双链表数据结构,并结合操作系统底层回调机制,造就了epoll的高效

    epoll的用法

    第一步:epoll_create()系统调用。此调用返回一个句柄,之后所有的使用都依靠这个句柄来标识。

    第二步:epoll_ctl()系统调用。通过此调用向epoll对象中添加、删除、修改感兴趣的事件,返回0标识成功,返回-1表示失败。

    第三部:epoll_wait()系统调用。通过此调用收集收集在epoll监控中已经发生的事件。

    15、网络编程中设计并发服务器,使用多进程 与 多线程 ,请问有什么区别? 

    1,进程:

    子进程是父进程的复制品。

    子进程获得父进程数据空间、堆和栈的复制品。
    2,线程:

    相对与进程而言,线程是一个更加接近与执行体的概念,它可以与同进程的其他线程共享数据,但拥有自己的栈空间,拥有独立的执行序列。

    两者都可以提高程序的并发度,提高程序运行效率和响应时间。
    线程和进程在使用上各有优缺点:

    线程执行开销小,但不利于资源管理和保护;而进程正相反。

    同时,线程适合于在SMP机器上运行,而进程则可以跨机器迁移。

    SMP的全称是"对称多处理"(Symmetrical Multi-Processing)技术,是指在一个计算机上汇集了一组处理器(多CPU),各CPU之间共享内存子系统以及总线结构。

     

     

    15、网络编程的一般步骤

    对于TCP连接:

    1.服务器端

    1)创建套接字create;

    2)绑定端口号bind;

    3)监听连接listen;

    4)接受连接请求accept,并返回新的套接字;

    5)用新返回的套接字recv/send;

    6)关闭套接字。

    2.客户端

    1)创建套接字create;

    2)发起建立连接请求connect;

    3)发送/接收数据send/recv;

    4)关闭套接字。

    TCP总结:

    Server端:create – bind – listen–  accept–  recv/send– close

    Client端:create——- conncet——send/recv——close.

     

    对于UDP连接:

    1.服务器端:

    1)创建套接字create;

    2)绑定端口号bind;

    3)接收/发送消息recvfrom/sendto;

    4)关闭套接字。

    2.客户端:

    1)创建套接字create;

    2)发送/接收消息sendto/recvfrom;

    3)关闭套接字.

    UDP总结:

    Server端:create—-bind —-recvfrom/sendto—-close

    Client端:create—-  sendto/recvfrom—-close.

    函数原型int recv( _In_ SOCKET s, _Out_ char *buf, _In_ int len, _In_ int flags);

     

    16、TCP的全称是?

            Transfer Control Protocol。

    17、UDP的全称是?

            User Datagram Protocol。

    18、请说出TCP和UDP的区别?

    TCP:

    一种面向连接(连接导向)的、可靠的、基于字节流的传输层(Transport layer)通信协议 。

    特点:

    面向连接;

    点到点的通信;

    高可靠性;

    占用系统资源多、效率低;

     

    UDP:

    一种无连接的、提供面向事务的简单不可靠信息传送服务的传输层通信协议。

    特点:

    非面向连接

    传输不可靠,可能丢失

    发送不管对方是否准备好,接收方收到也不确认

    可以广播发送

    非常简单的协议,开销小

     

     TCP—传输控制协议,提供的是面向连接、可靠的字节流服务。当客户和服务器彼此交换数据前,必须先在双方之间建立一个TCP连接,之后才能传输数据。TCP提供超时重发,丢弃重复数据,检验数据,流量控制等功能,保证数据能从一端传到另一端。

    UDP—用户数据报协议,是一个简单的面向数据报的运输层协议。UDP不提供可靠性,它只是把应用程序传给IP层的数据报发送出去,但是并不能保证它们能到达目的地。由于UDP在传输数据报前不用在客户和服务器之间建立一个连接,且没有超时重发等机制,故而传输速度很快

     

    19TCP为什么不是两次连接?而是三次握手?

    如果A与B两个进程通信,如果仅是两次连接。

    可能出现的一种情况

    就是:A发送完请求报文以后,由于网络情况不好,出现了网络拥塞,即B延时很长时间后收到报文,即此时A将此报文认定为失效的报文。

    B收到报文后,会向A发起连接。此时两次握手完毕

    B会认为已经建立了连接可以通信,B会一直等到A发送的连接请求

    而A对失效的报文回复自然不会处理。

    因此会陷入B忙等的僵局,造成资源的浪费。

    20、说明socket是什么?

     

    从上图可以看到:底层的东西已经被内核实现了,即我们通常意义上的内核协议栈(传输层,网络层,链路层)

    最上面的Application(应用层)是我们用户所要实现的,它是属于用户进程的一部分,工作在用户空间,那么用户空间的程序要想访问内核,使用内核的服务,就需要一个接口,去访问所需要的服务

    对于网络编程来说,这个接口就是套接口(Socket)。

           Socket:可以看作用户进程和内核网络协议栈编程(交互)接口

           Socket:不仅可以在同一台主机上进行通信,也可以在网络上不同的主机间进行通信,也可以异构(软硬件平台不同)进行通信(手机qq和PC机上的qq进行通信,手机的系统是ARM,而PC机是x86)

    21、为什么需要端口?端口是真实存在的还是虚拟的概念? 

    IP地址用来标志一台计算机,但是一台计算机上可能提供多种网络应用程序,使用端口来区分这些应用程序。

    端口是虚拟的概念,并不是说在主机上真的有若干个端口。通过端口,可以在一个主机上运行多个网络应用程序。

    端口范围0---65535,16位整数。

    22、Java中,端口使用两个字节表示,可以表示多少个端口? UDP和TCP端口是各自独立的吗?

    端口范围0---65535,16位整数。

    由于TCP/IP传输层的两个协议TCP和UDP是完全独立的两个软件模块,因此各自的端口号也相互独立,如TCP有一个255号端口,UDP也可以有一个255号端口,二者并不冲突。 

     

    23、URL类有什么作用?

    URL:Uniform Resource Locator,统一资源定位器;俗称“网址”,如:

    "http://www.baidu.com:80/index.html#aa?cansu=bjsxt“

    由4部分组成:

    l 协议: http;

    l 存放资源的主机域名:www.baidu.com;

    l 端口号:80;

    l 资源文件名: index.html#aa?cansu=bjsxt;

     

    URL是指向互联网“资源”的指针。资源可以是简单的文件或目录,也可以是对更为复杂的对象的引用,例如对数据库或搜索引擎的查询。

    24、基于TCP的Socket网络编程的主要步骤是什么?

     

    基于TCP协议的Socket编程的主要步骤

    服务器端(server):

    1. 构建一个ServerSocket实例,指定本地的端口。这个socket就是用来监听指定端口的连接请求的。

    2.重复如下几个步骤:

    a. 调用socket的accept()方法来获得下面客户端的连接请求。通过accept()方法返回的socket实例,建立了一个和客户端的新连接。

    b.通过这个返回的socket实例获取InputStream和OutputStream,可以通过这两个stream来分别读和写数据。

    c.结束的时候调用socket实例的close()方法关闭socket连接。

     

    客户端(client):

    1.构建Socket实例,通过指定的远程服务器地址和端口来建立连接。

    2.通过Socket实例包含的InputStream和OutputStream来进行数据的读写。

    3.操作结束后调用socket实例的close方法,关闭。

     

    25、【上机】写出建立TCP服务器ServerSocket的代码。并说明accept方法有什么特点?

    //服务器监听请求;

    ServerSocket ss=new ServerSocket(9999);

    //接受请求:创建了socket;

    Socket socket=ss.accept();

            详见课上示例。

    26、【上机】写出建立TCP客户端Socket的代码。并说明建立Socket后,通过什么方法Socket获得流对象?

    //客户端向服务器端发送请求;

    Socket socket=new Socket("127.0.0.1",9999);

    //建好连接后,开始传输数据;

    OutputStream os=socket.getOutputStream();

     

            详见课上示例。

    27、基于UDP的Socket网络编程的主要步骤是什么?

    基于UDP协议的Socket编程的主要步骤

    服务器端(server):

    1. 构造DatagramSocket实例,指定本地端口。

    2. 通过DatagramSocket实例的receive方法接收DatagramPacket.DatagramPacket中间就包含了通信的内容。

    3. 通过DatagramSocket的send和receive方法来收和发DatagramPacket.

    客户端(client):

    1. 构造DatagramSocket实例。

    2.通过DatagramSocket实例的send和receive方法发送DatagramPacket报文。

    3.结束后,调用DatagramSocket的close方法关闭。

     

    28、【上机】使用UDP的方式,完成对象的传递。

    (1)客户端向服务器端传送对象信息;

    DatagramSocket ds=new DatagramSocket(9999);

             //构建数据包;

            Scanner input=new Scanner(System.in);

            System.out.println("请输入用户名:");

            String username=input.nextLine();

            System.out.println("请输入密码:");

            String password=input.nextLine();

     //事先要创建好User类;

            User user=new User(username,password);

            //字节流;在内存开辟缓冲区;

            ByteArrayOutputStream baos=new ByteArrayOutputStream();

            ObjectOutputStream oos=new ObjectOutputStream(baos);

            oos.writeObject(user);

     

            byte buf[]=baos.toByteArray();

            DatagramPacket dp=new DatagramPacket(buf, buf.length, InetAddress.getByName("127.0.0.1"), 8888);//DatagramPacket只用byte[]数组;

                 //发送数据;

            ds.send(dp);

     

    (2)服务器端从客户端接收对象信息;

    //服务器定义DatagramSocket以接收数据;

    DatagramSocket ds=new DatagramSocket(8888);

     

    //定义一个数据包来接收数据;

    //数据包里是byte数组,所以还得定义一个byte数组;

    byte buf[]=new byte[1024];

    DatagramPacket dp=new DatagramPacket(buf, buf.length);

             //接收客户端发过来的数据;

    ds.receive(dp);

     

            //用字节流和对象流读取对象信息;

    ByteArrayInputStream bais=new ByteArrayInputStream(buf);

    ObjectInputStream ois=new ObjectInputStream(bais);

     

    User user=(User)ois.readObject();

            System.out.println(user);

     

    详见课上示例。

    29、HTTPClient相关问题

    1. 什么是httpClient?
    2. 什么是HttpClient不能做的?
    3. HttpClient有哪些特性?
    4. HttpClient怎样发送带参数的GET请求?
    5. HttpClient怎样发送带参数的POST请求?
    6. HttpClient怎样获取响应状态?
    7. HttpClient怎样获取响应内容?
    8. HttpClient怎样上传文件?

    30NIO 和传统 BIO区别是什么? 

     NIO vs BIO之间的理念上面的区别(NIO将阻塞交给了后台线程执行)

    IO是面向流的,NIO是面向缓冲区的

    Java BIO面向流意味着每次从流中读一个或多个字节,直至读取所有字节,它们没有被缓存在任何地方;

    NIO则能前后移动流中的数据,因为是面向缓冲区的 BIO流是阻塞的,NIO流是不阻塞的 Java IO的各种流是阻塞的。

    这意味着,当一个线程调用read() 或 write()时,该线程被阻塞,直到有一些数据被读取,或数据完全写入。

    该线程在此期间不能再干任何事情了 Java NIO的非阻塞模式,使一个线程从某通道发送请求读取数据,但是它仅能得到目前可用的数据,如果目前没有数据可用时,就什么都不会获取。

    NIO可让您只使用一个(或几个)单线程管理多个通道(网络连接或文件),但付出的代价是解析数据可能会比从一个阻塞流中读取数据更复杂。 

    非阻塞写也是如此。一个线程请求写入一些数据到某通道,但不需要等待它完全写入,这个线程同时可以去做别的事情。

    选择器

    Java NIO的选择器允许一个单独的线程来监视多个输入通道,你可以注册多个通道使用一个选择器,然后使用一个单独的线程来“选择”通道:这些通道里已经有可以处理的输入,或者选择已准备写入的通道。这种选择机制,使得一个单独的线程很容易来管理多个通道。

     

    31Java NIO 几个核心组成部分是什么?作用分别是什么?

    l Channels

    l Buffers

    l Selectors

    基本上,所有的 IO 在NIO 中都从一个Channel 开始。

    Channel 有点象流。

    数据可以从Channel读到Buffer中,也可以从Buffer 写到Channel中。

    Channel的实现: 

    (涵盖了UDP 和 TCP 网络IO,以及文件IO)  

    l FileChannel

    l DatagramChannel

    l SocketChannel

    l ServerSocketChannel

    读数据:  

    int bytesRead = inChannel.read(buf);

    写数据:  

    int bytesWritten = inChannel.write(buf);  

     

    Buffer  

    Buffer实现: (byte,  char、short, int, long, float, double )  

    l ByteBuffer

    l CharBuffer

    l DoubleBuffer

    l FloatBuffer

    l IntBuffer

    l LongBuffer

    l ShortBuffer

    Buffer使用  

    l 读数据 flip()方法:

    buf.flip();  

    将Buffer从写模式切换到读模式 调用flip()方法会将position设回0,并将limit设置成之前position的值。

    l (char) buf.get()

    读取数据

    l Buffer.rewind()

    将position设回0,所以你可以重读Buffer中的所有数据 limit保持不变,仍然表示能从Buffer中读取多少个元素(byte、char等)

    l Buffer.mark()方法,

    可以标记Buffer中的一个特定position。

    之后可以通过调用 Buffer.reset()方法,恢复到Buffer.mark()标记时的position

    一旦读完了所有的数据,就需要清空缓冲区,让它可以再次被写入。

    l clear()方法:

    清空整个缓冲区。 position将被设回0,limit被设置成 capacity的值

    l compact()方法:

     只会清除已经读过的数据;任何未读的数据都被移到缓冲区的起始处,新写入的数据将放到缓冲区未读数据的后面。

    将position设到最后一个未读元素正后面,limit被设置成 capacity的值 写数据 buf.put(127);    

    Buffer的三个属性  

    capacity:

    l 表示容量

    l Buffer的一个固定的大小值;

    l Buffer满了需要将其清空才能再写;

    l ByteBuffer.allocate(48);该buffer的capacity为48byte CharBuffer.allocate(1024);该buffer的capacity为1024个char 

    position:

    含义取决于Buffer处在读模式还是写模式(初始值为0,写或者读操作的当前位置)

    写数据时,初始的position值为0;

    其值最大可为capacity-1

    将Buffer从写模式切换到读模式,position会被重置为0

    limit:

    含义取决于Buffer处在读模式还是写模式(写limit=capacity;读limit等于最多可以读取到的数据)

    写模式下,limit等于Buffer的capacity 切换Buffer到读模式时, limit表示你最多能读到多少数据;  

    Selector  

    Selector允许单线程处理多个 Channel。

    如果你的应用打开了多个连接(通道),但每个连接的流量都很低,使用Selector就会很方便。

    例如,在一个聊天服务器中。    

    要使用Selector,得向Selector注册Channel,然后调用它的select()方法。这个方法会一直阻塞到某个注册的通道有事件就绪。

    一旦这个方法返回,线程就可以处理这些事件,事件的例子有如新连接进来,数据接收等。 

    使用  

    创建:

    Selector selector = Selector.open();   注册通道: channel.configureBlocking(false);   //与Selector一起使用时,Channel必须处于非阻塞模式 

    //这意味着不能将FileChannel与Selector一起使用,因为FileChannel不能切换到非阻塞模式(而套接字通道都可以)

    SelectionKey key = channel.register(selector, Selectionkey.OP_READ);  //第二个参数表明Selector监听Channel时对什么事件感兴趣

    //SelectionKey.OP_CONNECT  SelectionKey.OP_ACCEPT  SelectionKey.OP_READ SelectionKey.OP_WRITE //可以用或操作符将多个兴趣组合一起

    SelectionKey 包含了interest集合 、ready集合 、Channel 、Selector 、附加的对象(可选)

    int interestSet = key.interestOps();

    可以进行类似interestSet & SelectionKey.OP_CONNECT的判断

    select():

    阻塞到至少有一个通道在你注册的事件上就绪了

    selectNow():

    不会阻塞,不管什么通道就绪都立刻返回

    selectedKeys():

    访问“已选择键集(selected key set)”中的就绪通道

    close():

    使用完selector需要用其close()方法会关闭该Selector,且使注册到该Selector上的所有SelectionKey实例无效  

    Set selectedKeys = selector.selectedKeys();  

    Iterator keyIterator = selectedKeys.iterator();  

    while(keyIterator.hasNext()) {       

    SelectionKey key = keyIterator.next();       

    if(key.isAcceptable()) {           

    // a connection was accepted by a ServerSocketChannel.       

    } else if (key.isConnectable()) {          

     // a connection was established with a remote server.       

    } else if (key.isReadable()) {          

     // a channel is ready for reading       

    } else if (key.isWritable()) {           

    // a channel is ready for writing       

    }     

    keyIterator.remove();//注意这里必须手动remove;

    表明该selectkey我已经处理过了;

    }

     

    32、简单说一下http协议?

    HTTP协议是Hyper Text Transfer Protocol(超文本传输协议)的缩写,是用于从万维网(WWW:World Wide Web )服务器传输超文本到本地浏览器的传送协议。

    HTTP是一个基于TCP/IP通信协议来传递数据(HTML 文件, 图片文件, 查询结果等)。

    HTTP 工作原理

    HTTP协议工作于客户端-服务端架构上。浏览器作为HTTP客户端通过URL向HTTP服务端即WEB服务器发送所有请求。

    Web服务器有:Apache服务器,Nginx,IIS服务器(Internet Information Services)等。

    Web服务器根据接收到的请求后,向客户端发送响应信息。

    HTTP默认端口号为80,但是你也可以改为8080或者其他端口。

    HTTP三点注意事项:

    l HTTP是无连接:无连接的含义是限制每次连接只处理一个请求。服务器处理完客户的请求,并收到客户的应答后,即断开连接。采用这种方式可以节省传输时间。

    l HTTP是媒体独立的:这意味着,只要客户端和服务器知道如何处理的数据内容,任何类型的数据都可以通过HTTP发送。客户端以及服务器指定使用适合的MIME-type内容类型。

    l HTTP是无状态:HTTP协议是无状态协议。无状态是指协议对于事务处理没有记忆能力。缺少状态意味着如果后续处理需要前面的信息,则它必须重传,这样可能导致每次连接传送的数据量增大。另一方面,在服务器不需要先前信息时它的应答就较快。

     

     

    33、http协议下客户端请求报文是什么?

    客户端发送一个HTTP请求到服务器的请求消息包括以下格式:

    l 请求行(request line)

    l 请求头部(header)

    l 空行

    l 请求数据

    四个部分组成

    下图给出了请求报文的一般格式。

     

    客户端请求:

    GET /hello.txt HTTP/1.1

    User-Agent: curl/7.16.3 libcurl/7.16.3 OpenSSL/0.9.7l zlib/1.2.3

    Host: www.example.com

    Accept-Language: en, mi

    34、描述一下http协议服务器响应报文有哪些?

    HTTP响应也由四个部分组成,分别是:

    l 状态行

    l 消息报头

    l 空行

    l 响应正文

     

    HTTP/1.1 200 OK

    Date: Mon, 27 Jul 2009 12:28:53 GMT

    Server: Apache

    Last-Modified: Wed, 22 Jul 2009 19:15:56 GMT

    ETag: "34aa387-d-1568eb00"

    Accept-Ranges: bytes

    Content-Length: 51

    Vary: Accept-Encoding

    Content-Type: text/plain

    35HTTP协议中常用的请求方法有哪些

    根据HTTP标准,HTTP请求可以使用多种请求方法。

    HTTP1.0定义了三种请求方法: GET, POST 和 HEAD方法。

    HTTP1.1新增了五种请求方法:OPTIONS, PUT, DELETE, TRACE 和 CONNECT 方法。

    序号

    方法

    描述

    1

    GET

    请求指定的页面信息,并返回实体主体。

    2

    HEAD

    类似于get请求,只不过返回的响应中没有具体的内容,用于获取报头

    3

    POST

    向指定资源提交数据进行处理请求(例如提交表单或者上传文件)。数据被包含在请求体中。

    POST请求可能会导致新的资源的建立和/或已有资源的修改。

    4

    PUT

    从客户端向服务器传送的数据取代指定的文档的内容。

    5

    DELETE

    请求服务器删除指定的页面。

    6

    CONNECT

    HTTP/1.1协议中预留给能够将连接改为管道方式的代理服务器。

    7

    OPTIONS

    允许客户端查看服务器的性能。

    8

    TRACE

    回显服务器收到的请求,主要用于测试或诊断。

    36、常见的HTTP状态码有哪些

    当浏览者访问一个网页时,浏览者的浏览器会向网页所在服务器发出请求。当浏览器接收并显示网页前,此网页所在的服务器会返回一个包含HTTP状态码的信息头(server header)用以响应浏览器的请求。

    HTTP状态码的英文为HTTP Status Code。

    下面是常见的HTTP状态码:

    l 200 - 请求成功

    l 301 - 资源(网页等)被永久转移到其它URL

    l 404 - 请求的资源(网页等)不存在

    l 500 - 内部服务器错误

    HTTP状态码由三个十进制数字组成,第一个十进制数字定义了状态码的类型,后两个数字没有分类的作用。HTTP状态码共分为5种类型:

    HTTP状态码分类

    分类

    分类描述

    1**

    信息,服务器收到请求,需要请求者继续执行操作

    2**

    成功,操作被成功接收并处理

    3**

    重定向,需要进一步的操作以完成请求

    4**

    客户端错误,请求包含语法错误或无法完成请求

    5**

    服务器错误,服务器在处理请求的过程中发生了错误

    HTTP状态码列表:

    HTTP状态码列表

    状态码

    状态码英文名称

    中文描述

    100

    Continue

    继续。客户端应继续其请求

    101

    Switching Protocols

    切换协议。服务器根据客户端的请求切换协议。只能切换到更高级的协议,例如,切换到HTTP的新版本协议

     

    200

    OK

    请求成功。一般用于GET与POST请求

    201

    Created

    已创建。成功请求并创建了新的资源

    202

    Accepted

    已接受。已经接受请求,但未处理完成

    203

    Non-Authoritative Information

    非授权信息。请求成功。但返回的meta信息不在原始的服务器,而是一个副本

    204

    No Content

    无内容。服务器成功处理,但未返回内容。在未更新网页的情况下,可确保浏览器继续显示当前文档

    205

    Reset Content

    重置内容。服务器处理成功,用户终端(例如:浏览器)应重置文档视图。可通过此返回码清除浏览器的表单域

    206

    Partial Content

    部分内容。服务器成功处理了部分GET请求

     

    300

    Multiple Choices

    多种选择。请求的资源可包括多个位置,相应可返回一个资源特征与地址的列表用于用户终端(例如:浏览器)选择

    301

    Moved Permanently

    永久移动。请求的资源已被永久的移动到新URI,返回信息会包括新的URI,浏览器会自动定向到新URI。今后任何新的请求都应使用新的URI代替

    302

    Found

    临时移动。与301类似。但资源只是临时被移动。客户端应继续使用原有URI

    303

    See Other

    查看其它地址。与301类似。使用GET和POST请求查看

    304

    Not Modified

    未修改。所请求的资源未修改,服务器返回此状态码时,不会返回任何资源。客户端通常会缓存访问过的资源,通过提供一个头信息指出客户端希望只返回在指定日期之后修改的资源

    305

    Use Proxy

    使用代理。所请求的资源必须通过代理访问

    306

    Unused

    已经被废弃的HTTP状态码

    307

    Temporary Redirect

    临时重定向。与302类似。使用GET请求重定向

     

    400

    Bad Request

    客户端请求的语法错误,服务器无法理解

    401

    Unauthorized

    请求要求用户的身份认证

    402

    Payment Required

    保留,将来使用

    403

    Forbidden

    服务器理解请求客户端的请求,但是拒绝执行此请求

    404

    Not Found

    服务器无法根据客户端的请求找到资源(网页)。通过此代码,网站设计人员可设置"您所请求的资源无法找到"的个性页面

    405

    Method Not Allowed

    客户端请求中的方法被禁止

    406

    Not Acceptable

    服务器无法根据客户端请求的内容特性完成请求

    407

    Proxy Authentication Required

    请求要求代理的身份认证,与401类似,但请求者应当使用代理进行授权

    408

    Request Time-out

    服务器等待客户端发送的请求时间过长,超时

    409

    Conflict

    服务器完成客户端的PUT请求是可能返回此代码,服务器处理请求时发生了冲突

    410

    Gone

    客户端请求的资源已经不存在。410不同于404,如果资源以前有现在被永久删除了可使用410代码,网站设计人员可通过301代码指定资源的新位置

    411

    Length Required

    服务器无法处理客户端发送的不带Content-Length的请求信息

    412

    Precondition Failed

    客户端请求信息的先决条件错误

    413

    Request Entity Too Large

    由于请求的实体过大,服务器无法处理,因此拒绝请求。为防止客户端的连续请求,服务器可能会关闭连接。如果只是服务器暂时无法处理,则会包含一个Retry-After的响应信息

    414

    Request-URI Too Large

    请求的URI过长(URI通常为网址),服务器无法处理

    415

    Unsupported Media Type

    服务器无法处理请求附带的媒体格式

    416

    Requested range not satisfiable

    客户端请求的范围无效

    417

    Expectation Failed

    服务器无法满足Expect的请求头信息

     

    500

    Internal Server Error

    服务器内部错误,无法完成请求

    501

    Not Implemented

    服务器不支持请求的功能,无法完成请求

    502

    Bad Gateway

    充当网关或代理的服务器,从远端服务器接收到了一个无效的请求

    503

    Service Unavailable

    由于超载或系统维护,服务器暂时的无法处理客户端的请求。延时的长度可包含在服务器的Retry-After头信息中

    504

    Gateway Time-out

    充当网关或代理的服务器,未及时从远端服务器获取请求

    505

    HTTP Version not supported

    服务器不支持请求的HTTP协议的版本,无法完成处理

    37HTTP 协议中content-type指的是什么?

    Content-Type,内容类型,一般是指网页中存在的Content-Type,用于定义网络文件的类型和网页的编码,决定浏览器将以什么形式、什么编码读取这个文件,这就是经常看到一些Asp网页点击的结果却是下载到的一个文件或一张图片的原因。

     

    文件扩展名

    Content-Type(Mime-Type)

    文件扩展名

    Content-Type(Mime-Type)

    .*( 二进制流,不知道下载文件类型)

    application/octet-stream

    .tif

    image/tiff

    .001

    application/x-001

    .301

    application/x-301

    .323

    text/h323

    .906

    application/x-906

    .907

    drawing/907

    .a11

    application/x-a11

    .acp

    audio/x-mei-aac

    .ai

    application/postscript

    .aif

    audio/aiff

    .aifc

    audio/aiff

    .aiff

    audio/aiff

    .anv

    application/x-anv

    .asa

    text/asa

    .asf

    video/x-ms-asf

    .asp

    text/asp

    .asx

    video/x-ms-asf

    .au

    audio/basic

    .avi

    video/avi

    .awf

    application/vnd.adobe.workflow

    .biz

    text/xml

    .bmp

    application/x-bmp

    .bot

    application/x-bot

    .c4t

    application/x-c4t

    .c90

    application/x-c90

    .cal

    application/x-cals

    .cat

    application/vnd.ms-pki.seccat

    .cdf

    application/x-netcdf

    .cdr

    application/x-cdr

    .cel

    application/x-cel

    .cer

    application/x-x509-ca-cert

    .cg4

    application/x-g4

    .cgm

    application/x-cgm

    .cit

    application/x-cit

    .class

    java/*

    .cml

    text/xml

    .cmp

    application/x-cmp

    .cmx

    application/x-cmx

    .cot

    application/x-cot

    .crl

    application/pkix-crl

    .crt

    application/x-x509-ca-cert

    .csi

    application/x-csi

    .css

    text/css

    .cut

    application/x-cut

    .dbf

    application/x-dbf

    .dbm

    application/x-dbm

    .dbx

    application/x-dbx

    .dcd

    text/xml

    .dcx

    application/x-dcx

    .der

    application/x-x509-ca-cert

    .dgn

    application/x-dgn

    .dib

    application/x-dib

    .dll

    application/x-msdownload

    .doc

    application/msword

    .dot

    application/msword

    .drw

    application/x-drw

    .dtd

    text/xml

    .dwf

    Model/vnd.dwf

    .dwf

    application/x-dwf

    .dwg

    application/x-dwg

    .dxb

    application/x-dxb

    .dxf

    application/x-dxf

    .edn

    application/vnd.adobe.edn

    .emf

    application/x-emf

    .eml

    message/rfc822

    .ent

    text/xml

    .epi

    application/x-epi

    .eps

    application/x-ps

    .eps

    application/postscript

    .etd

    application/x-ebx

    .exe

    application/x-msdownload

    .fax

    image/fax

    .fdf

    application/vnd.fdf

    .fif

    application/fractals

    .fo

    text/xml

    .frm

    application/x-frm

    .g4

    application/x-g4

    .gbr

    application/x-gbr

    .

    application/x-

    .gif

    image/gif

    .gl2

    application/x-gl2

    .gp4

    application/x-gp4

    .hgl

    application/x-hgl

    .hmr

    application/x-hmr

    .hpg

    application/x-hpgl

    .hpl

    application/x-hpl

    .hqx

    application/mac-binhex40

    .hrf

    application/x-hrf

    .hta

    application/hta

    .htc

    text/x-component

    .htm

    text/html

    .html

    text/html

    .htt

    text/webviewhtml

    .htx

    text/html

    .icb

    application/x-icb

    .ico

    image/x-icon

    .ico

    application/x-ico

    .iff

    application/x-iff

    .ig4

    application/x-g4

    .igs

    application/x-igs

    .iii

    application/x-iphone

    .img

    application/x-img

    .ins

    application/x-internet-signup

    .isp

    application/x-internet-signup

    .IVF

    video/x-ivf

    .java

    java/*

    .jfif

    image/jpeg

    .jpe

    image/jpeg

    .jpe

    application/x-jpe

    .jpeg

    image/jpeg

    .jpg

    image/jpeg

    .jpg

    application/x-jpg

    .js

    application/x-javascript

    .jsp

    text/html

    .la1

    audio/x-liquid-file

    .lar

    application/x-laplayer-reg

    .latex

    application/x-latex

    .lavs

    audio/x-liquid-secure

    .lbm

    application/x-lbm

    .lmsff

    audio/x-la-lms

    .ls

    application/x-javascript

    .ltr

    application/x-ltr

    .m1v

    video/x-mpeg

    .m2v

    video/x-mpeg

    .m3u

    audio/mpegurl

    .m4e

    video/mpeg4

    .mac

    application/x-mac

    .man

    application/x-troff-man

    .math

    text/xml

    .mdb

    application/msaccess

    .mdb

    application/x-mdb

    .mfp

    application/x-shockwave-flash

    .mht

    message/rfc822

    .mhtml

    message/rfc822

    .mi

    application/x-mi

    .mid

    audio/mid

    .midi

    audio/mid

    .mil

    application/x-mil

    .mml

    text/xml

    .mnd

    audio/x-musicnet-download

    .mns

    audio/x-musicnet-stream

    .mocha

    application/x-javascript

    .movie

    video/x-sgi-movie

    .mp1

    audio/mp1

    .mp2

    audio/mp2

    .mp2v

    video/mpeg

    .mp3

    audio/mp3

    .mp4

    video/mpeg4

    .mpa

    video/x-mpg

    .mpd

    application/vnd.ms-project

    .mpe

    video/x-mpeg

    .mpeg

    video/mpg

    .mpg

    video/mpg

    .mpga

    audio/rn-mpeg

    .mpp

    application/vnd.ms-project

    .mps

    video/x-mpeg

    .mpt

    application/vnd.ms-project

    .mpv

    video/mpg

    .mpv2

    video/mpeg

    .mpw

    application/vnd.ms-project

    .mpx

    application/vnd.ms-project

    .mtx

    text/xml

    .mxp

    application/x-mmxp

    .net

    image/pnetvue

    .nrf

    application/x-nrf

    .nws

    message/rfc822

    .odc

    text/x-ms-odc

    .out

    application/x-out

    .p10

    application/pkcs10

    .p12

    application/x-pkcs12

    .p7b

    application/x-pkcs7-certificates

    .p7c

    application/pkcs7-mime

    .p7m

    application/pkcs7-mime

    .p7r

    application/x-pkcs7-certreqresp

    .p7s

    application/pkcs7-signature

    .pc5

    application/x-pc5

    .pci

    application/x-pci

    .pcl

    application/x-pcl

    .pcx

    application/x-pcx

    .pdf

    application/pdf

    .pdf

    application/pdf

    .pdx

    application/vnd.adobe.pdx

    .pfx

    application/x-pkcs12

    .pgl

    application/x-pgl

    .pic

    application/x-pic

    .pko

    application/vnd.ms-pki.pko

    .pl

    application/x-perl

    .plg

    text/html

    .pls

    audio/scpls

    .plt

    application/x-plt

    .png

    image/png

    .png

    application/x-png

    .pot

    application/vnd.ms-powerpoint

    .ppa

    application/vnd.ms-powerpoint

    .ppm

    application/x-ppm

    .pps

    application/vnd.ms-powerpoint

    .ppt

    application/vnd.ms-powerpoint

    .ppt

    application/x-ppt

    .pr

    application/x-pr

    .prf

    application/pics-rules

    .prn

    application/x-prn

    .prt

    application/x-prt

    .ps

    application/x-ps

    .ps

    application/postscript

    .ptn

    application/x-ptn

    .pwz

    application/vnd.ms-powerpoint

    .r3t

    text/vnd.rn-realtext3d

    .ra

    audio/vnd.rn-realaudio

    .ram

    audio/x-pn-realaudio

    .ras

    application/x-ras

    .rat

    application/rat-file

    .rdf

    text/xml

    .rec

    application/vnd.rn-recording

    .red

    application/x-red

    .rgb

    application/x-rgb

    .rjs

    application/vnd.rn-realsystem-rjs

    .rjt

    application/vnd.rn-realsystem-rjt

    .rlc

    application/x-rlc

    .rle

    application/x-rle

    .rm

    application/vnd.rn-realmedia

    .rmf

    application/vnd.adobe.rmf

    .rmi

    audio/mid

    .rmj

    application/vnd.rn-realsystem-rmj

    .rmm

    audio/x-pn-realaudio

    .rmp

    application/vnd.rn-rn_music_package

    .rms

    application/vnd.rn-realmedia-secure

    .rmvb

    application/vnd.rn-realmedia-vbr

    .rmx

    application/vnd.rn-realsystem-rmx

    .rnx

    application/vnd.rn-realplayer

    .rp

    image/vnd.rn-realpix

    .rpm

    audio/x-pn-realaudio-plugin

    .rsml

    application/vnd.rn-rsml

    .rt

    text/vnd.rn-realtext

    .rtf

    application/msword

    .rtf

    application/x-rtf

    .rv

    video/vnd.rn-realvideo

    .sam

    application/x-sam

    .sat

    application/x-sat

    .sdp

    application/sdp

    .sdw

    application/x-sdw

    .sit

    application/x-stuffit

    .slb

    application/x-slb

    .sld

    application/x-sld

    .slk

    drawing/x-slk

    .smi

    application/smil

    .smil

    application/smil

    .smk

    application/x-smk

    .snd

    audio/basic

    .sol

    text/plain

    .sor

    text/plain

    .spc

    application/x-pkcs7-certificates

    .spl

    application/futuresplash

    .spp

    text/xml

    .ssm

    application/streamingmedia

    .sst

    application/vnd.ms-pki.certstore

    .stl

    application/vnd.ms-pki.stl

    .stm

    text/html

    .sty

    application/x-sty

    .svg

    text/xml

    .swf

    application/x-shockwave-flash

    .tdf

    application/x-tdf

    .tg4

    application/x-tg4

    .tga

    application/x-tga

    .tif

    image/tiff

    .tif

    application/x-tif

    .tiff

    image/tiff

    .tld

    text/xml

    .top

    drawing/x-top

    .torrent

    application/x-bittorrent

    .tsd

    text/xml

    .txt

    text/plain

    .uin

    application/x-icq

    .uls

    text/iuls

    .vcf

    text/x-vcard

    .vda

    application/x-vda

    .vdx

    application/vnd.visio

    .vml

    text/xml

    .vpg

    application/x-vpeg005

    .vsd

    application/vnd.visio

    .vsd

    application/x-vsd

    .vss

    application/vnd.visio

    .vst

    application/vnd.visio

    .vst

    application/x-vst

    .vsw

    application/vnd.visio

    .vsx

    application/vnd.visio

    .vtx

    application/vnd.visio

    .vxml

    text/xml

    .wav

    audio/wav

    .wax

    audio/x-ms-wax

    .wb1

    application/x-wb1

    .wb2

    application/x-wb2

    .wb3

    application/x-wb3

    .wbmp

    image/vnd.wap.wbmp

    .wiz

    application/msword

    .wk3

    application/x-wk3

    .wk4

    application/x-wk4

    .wkq

    application/x-wkq

    .wks

    application/x-wks

    .wm

    video/x-ms-wm

    .wma

    audio/x-ms-wma

    .wmd

    application/x-ms-wmd

    .wmf

    application/x-wmf

    .wml

    text/vnd.wap.wml

    .wmv

    video/x-ms-wmv

    .wmx

    video/x-ms-wmx

    .wmz

    application/x-ms-wmz

    .wp6

    application/x-wp6

    .wpd

    application/x-wpd

    .wpg

    application/x-wpg

    .wpl

    application/vnd.ms-wpl

    .wq1

    application/x-wq1

    .wr1

    application/x-wr1

    .wri

    application/x-wri

    .wrk

    application/x-wrk

    .ws

    application/x-ws

    .ws2

    application/x-ws

    .wsc

    text/scriptlet

    .wsdl

    text/xml

    .wvx

    video/x-ms-wvx

    .xdp

    application/vnd.adobe.xdp

    .xdr

    text/xml

    .xfd

    application/vnd.adobe.xfd

    .xfdf

    application/vnd.adobe.xfdf

    .xhtml

    text/html

    .xls

    application/vnd.ms-excel

    .xls

    application/x-xls

    .xlw

    application/x-xlw

    .xml

    text/xml

    .xpl

    audio/scpls

    .xq

    text/xml

    .xql

    text/xml

    .xquery

    text/xml

    .xsd

    text/xml

    .xsl

    text/xml

    .xslt

    text/xml

    .xwd

    application/x-xwd

    .x_b

    application/x-x_b

    .sis

    application/vnd.symbian.install

    .sisx

    application/vnd.symbian.install

    .x_t

    application/x-x_t

    .ipa

    application/vnd.iphone

    .apk

    application/vnd.android.package-archive

    .xap

    application/x-silverlight-app

     

    38、网络传输协议本质和作用是什么?

    协议本质是双方约定好的一种传输规则,为了让传输数据的双方节点能建立连接,按照约定去传输和解析数据

    39、可以实现一个简单的网络协议吗?

    posted on 2019-05-27 18:09  shoshana~ 阅读( ...) 评论( ...) 编辑 收藏

    转载于:https://www.cnblogs.com/shoshana-kong/p/10932221.html

    展开全文
  • Java-Java编程思想第四版 第十章 练习

    千次阅读 2018-02-18 02:14:43
    PS:(1)变量aa必须定义成Object,这样导入参数时Word类可以向上转型成Object,使toString()可以工作(2)toString()方法必须是public的(3)String word变量不能是static的,否则当它从aaaa变到cccc,指向它的a[0]~a[2...
    练习1:
    
    /* Write a class named Outer that contains an inner class named Innet. 
    * Add a method to Outer that returns an object of type Inner. In main(),
    * create and initialize a reference to an Inner.
    */
    import static net.mindview.util.Print.*;
    class Outer{
        Inner out(){return new Inner();}
        class Inner{
            void in(){print("it's inner class");}
        }
    }
    public class Ja10_1_1{
        public static void main(String[] args){
            Outer ou=new Outer();
            Outer.Inner in=ou.out();
            in.in();
        }
    }
    

    练习2:

    /* Create a class that holds a String, and has a toString() method that
    * displays this String. Add several instances of your new class to a 
    * Sequence ojbect, then display them.
    */
    import static net.mindview.util.Print.*;
    interface Selector{
        boolean end();
        void next();
        Object current();
    }
    class Word{
        private  String word;// this "word" can't be static. Or, the value can't be assigned!
        public Word(String s){word=s;}
        public String toString(){return word;}//toString must be public
    }
    public class Ja10_2_2{
        private Object[] aa;//it must be Object
        private static int i=0;
        private static int j=0;
        public Ja10_2_2(int size){aa=new Object[size];} //the size of Number array must be defined here.
        private class SequenceSelector implements Selector{
            public Object current(){return aa[j];}
            public void next(){j++;}
            public boolean end(){if(j<aa.length) return true; else{j=0;return false;} }
        }
        Selector selector(){return new SequenceSelector();}
        void add(Object s){//it must be Object
            if(i<aa.length){
            aa[i]=s;
            print(aa[1]);
            ++i;
            }
        }
        public static void main(String[] args){
            Ja10_2_2 ja=new Ja10_2_2(3);
            ja.add(new Word("aaaa"));
            ja.add(new Word("bbbb"));
            ja.add(new Word("cccc"));
            Selector sel=ja.selector();
            while(sel.end()){
                print(sel.current());
                sel.next();
            }
        }
    }
    

    PS:(1)变量aa必须定义成Object,这样导入参数时Word类可以向上转型成Object,使toString()可以工作(2)toString()方法必须是public的(3)String word变量不能是static的,否则当它从aaaa变到cccc,指向它的a[0]~a[2]的数组的值会全部变成cccc!(4)数组的大小必须事前定义好(Ja-22-),否则会wei'l

    练习3:

    
    
    /* Modify Exercise 1 so that Outer has a private String field (initialized
    * by the constructor), and Inner has a toString() that displays this field.
    * Create an object of type Inner and display it.
    */
    import static net.mindview.util.Print.*;
    class Outer{
        private String ss;
        Inner out(){ss="dsaf"; return new Inner();}
        class Inner{
            public String toString(){return ss;}
            void in(){print("it's inner class");}
        }
    }
    public class Ja10_2_3{
        public static void main(String[] args){
            Outer ou=new Outer();
            Outer.Inner in=ou.out();
            print(in);
        }
    }
    
    

    练习4:

    import static net.mindview.util.Print.*;
    interface Selector {
      boolean end();
      Object current();
      void next();
      Ja10_3_4 infer();//!
    }	
    
    public class Ja10_3_4 {
      private Object[] items;
      private int next = 0;
      public Ja10_3_4(int size) { items = new Object[size]; }
      public void add(Object x) {
        if(next < items.length)
          items[next++] = x;
      }
      private class SequenceSelector implements Selector {
        private int i = 0;
        public boolean end() { return i == items.length; }
        public Object current() { return items[i]; }
        public void next() { if(i < items.length) i++; }
        public Ja10_3_4 infer(){return Ja10_3_4.this;}//!
      }
      public Selector selector() {
        return new SequenceSelector();
      }	
      public void outerInferred(){print("Ja10_3_4 inferred.");}
      public static void main(String[] args) {
        Ja10_3_4 sequence = new Ja10_3_4(10);
        for(int i = 0; i < 10; i++)
          sequence.add(Integer.toString(i));
        Selector selector = sequence.selector();
        selector.infer().outerInferred();//!
        while(!selector.end()) {
          System.out.print(selector.current() + " ");
          selector.next();
        }
      }
    } 
    

    PS://!处,为新增代码

    练习5:

    import static net.mindview.util.Print.*;
    class Outer{
        class Inner{
            Inner(){print("adsf");}
        }
    }
    public class Ja10_3_5{
        public static void main(String[] args){
           Outer ou=new Outer();
           Outer.Inner in=ou.new Inner();
        }
    }
    
    

    练习6:

    import net.mindview.simple.*;
    /*interface Ja10_4_6a{
        void f();
    }*/
    /*class Ja10_4_6b{
        class Ja10_4_6c implements Ja10_4_6a{
            public void f(){System.out.println("It's Ja10_4_6b");}
    
        }
    }*/
    public class Ja10_4_6 extends Ja10_4_6b{
        public static void main(String[] args){
            Ja10_4_6b ja=new Ja10_4_6b();
            Ja10_4_6a jac=ja.new Ja10_4_6c();
            jac.f();
        }
    }


    练习7:

    import static net.mindview.util.Print.*;
    class Ja10_4_7a{
        private int i=5;
        private void outMethod(){print("It's method of outer");}
        class Ja10_4_7b{
            void f(){i=3;print(i);}
            void inMethod(){outMethod();}
        }
    }
    public class Ja10_4_7{
        public static void main(String[] args){
            Ja10_4_7a jaa=new Ja10_4_7a();
            Ja10_4_7a.Ja10_4_7b jab=jaa.new Ja10_4_7b();
            jab.f();
            jab.inMethod();
        }
    }
    

    练习9:

    /* Create an interface with at least one method, and implement that
    * interface by defining an inner class within a method, which returns a
    * reference to your interface.
    */
    import static net.mindview.util.Print.*;
    interface A{
        void f();
    }
    public class Ja10_5_9{
        A outMethod1(){
            class B implements A{
                public void f(){
                    print("it's B implements A.f()");
                }
            }
            return new B();
        }
        public static void main(String[] args){
            Ja10_5_9 ja=new Ja10_5_9();
            A a=ja.outMethod1();
            a.f();
        }
    }
    

    练习11:

    /* Create a private inner class that implements a public interface.
    * Write a method that returns a reference to an instance of the private
    * inner class, upcast to the interface. Show that the inner class is 
    * completely hidden by trying to downcast to it.
    */
    
    import static net.mindview.util.Print.*;
     interface A{void f();}
    /*public class Ja10_5_11{
        A forReturn(){
            private class B implements A{
                public void f(){print("It's Ja10_5_11.B.f()");}
            }
            return new B();
        }
        public static void main(String[] args){
            Ja10_5_11 ja=new Ja10_5_11();
            A a=ja.forReturn();
            a.f();
        }
    }*/
    class C{
        private class B implements A{
            public void f(){print("It's Ja10_5_11.B.f()");}
        }
        A forReturn(){return new B();}
    }
    public class Ja10_5_11{
        public static void main(String[] args){
            C c=new C();
            A a=c.forReturn();
            a.f();
    
            //!B b=(B)a;
            //!b.f();
        }
    }
    

    PS: 方法内部的内部类,不能设成private?

    练习12:

    /* Repeat Exercise 7 using an anonymous inner class.
    * (Exercise 7: Create a class with a private field and a private method. 
    * Create an inner class with a method that modifies the outer-class field  
    * and calls the outer class method. In a second outer-class method, create
    * an object of the inner class and call its method, then show the effect on
    * the outer-class object.) 
    */
    import static net.mindview.util.Print.*;
    interface  Ja10_4_7b{
        void f();
        void inMethod();
    }
    
    class Ja10_4_7a{
        private int i=5;
        private void outMethod(){print("It's method of outer");}
        Ja10_4_7b bb(){
            return new Ja10_4_7b(){
                private int j=5;
                private void bb(){print(j);}
                {print(j);}
                public void f(){i=3;print(i);}
                public void inMethod(){outMethod();}
            };
        }
    }
    public class Ja10_6_12{
        public static void main(String[] args){
            Ja10_4_7a jaa=new Ja10_4_7a();
            jaa.bb();
        }
    }

    练习13:

    /* Repeat Exercise 9 using an anonymous inner class.
    * (Exercise 9: Create an interface with at least one method, and implement
    * that interface by defining an inner class within a method, which returns
    * a reference to your interface.) 
    */
    import static net.mindview.util.Print.*;
    interface A{
        void f();
    }
    public class Ja10_6_13{
        A outMethod1(){
            return new A(){
                {print("it's inner class A");}
                public void f(){
                    print("it's B implements A.f()");
                }
            };
        }
        public static void main(String[] args){
            Ja10_6_13 ja=new Ja10_6_13();
            A a=ja.outMethod1();
            a.f();
        }
    }
    
    

    练习14:

    /* Modify interfaces/HorrorShow.java to implement DangerousMonster and
    * Vampire using anonymous classes.
    */
    interface Monster {
      void menace();
    }
    
    interface DangerousMonster extends Monster {
      void destroy();
    }
    
    interface Lethal {
      void kill();
    }
    
    interface Vampire extends DangerousMonster, Lethal {
      void drinkBlood();
    }
    
    public class Ja10_6_14 {
      static void u(Monster b) { b.menace(); }
      static void v(DangerousMonster d) {
        d.menace();
        d.destroy();
      }
      static void w(Lethal l) { l.kill(); }
      DangerousMonster monster(){
          return new DangerousMonster(){ 
            public void menace() {}
            public void destroy() {}
        };
      }
      Vampire vampire(){
        return new Vampire(){
            public void menace() {}
            public void destroy() {}
            public void kill() {}
            public void drinkBlood() {}
        };
      }
      public static void main(String[] args) {
          Ja10_6_14 ja=new Ja10_6_14();
        DangerousMonster barney =ja.monster();
        u(barney);
        v(barney);
        Vampire vlad =ja.vampire();
        u(vlad);
        v(vlad);
        w(vlad);
      }
    } 
    

    练习15:

    /* Create a class with a non-default constructor and no default constructor.
    * Create a second class that has a method that returns a reference to an
    * object of the first class. Create the object that you return by making an
    * anonymous inner class that inherits from the first class. 
    */
    import static net.mindview.util.Print.*;
    abstract class A{
        void a(int i){}
    }
    class C extends A{}
    class B{
        A returnInner(final int i){
            return new C(){
                //private int ii=i;
                void a(int ii){print("It's B.C.a("+ii+")");}
            };
        }
    }
    public class Ja10_6_15{
        public static void main(String[] args){
            B b=new B();
            b.returnInner(5).a(8);
        }
    }
    

    练习16:

    /* Modify the solution to Exercise 18 from the Interfaces chapter to use
    * anonymous inner classes.
    * (Exercise 18, Interface: Create a Cycle interface, with implementations
    * Unicycle, Bicycle and Tricycle. Create factories for each type of Cycle,
    * and code that uses these factories.
    */
    import static net.mindview.util.Print.*;
    interface Cycle{void produce();}
    interface CycleFactory{Cycle getCycle();}
    class Unicycle implements Cycle{
        public void produce(){print("it's Unicycle");}
        public static CycleFactory factory=new CycleFactory(){
            public Cycle getCycle(){return new Unicycle();}
        };
        
    }
    class Bicycle implements Cycle{
        public void produce(){print("it's Bicycle");}
        public static CycleFactory factory=new CycleFactory(){
            public Cycle getCycle(){
                return new Bicycle();
            }  
        };
    }
    class Tricycle implements Cycle{
        public void produce(){print("it's Tricycle");}
        public static CycleFactory factory=new CycleFactory(){
            public Cycle getCycle(){return new Tricycle();}
        };
    }
    public class Ja10_6_16{
        static void make(CycleFactory cf){
            Cycle c=cf.getCycle();
            c.produce();
        }
        public static void main(String[] args){
            make(Unicycle.factory);
            make(Bicycle.factory);
            make(Tricycle.factory);
        }
    }
    
    

    练习18:

    /* Create a class containing a nested class. In main(), create an instance of
    * the nested class.
    */
    class C{
         class D{}
    }
    public class Ja10_6_18{
        static class B{
            
        }
        class A{}
        public static void main(String[] args){
            B b=new B();
            //!A a=new A();
            
            Ja10_6_18 ja=new Ja10_6_18();
            A a=ja.new A();
    
            C c=new C();
            C.D d=c.new D();
        }
    }
    
    

    练习19:

    /* Create a class containing an inner class that itself contains an inner
    * class. Repeat this using nested classes. Note the names of the .class files
    * produced by the compiler.
    */
    
    import static net.mindview.util.Print.*;
    public class Ja10_6_19{
        private static class A{
            private static class B{
                void f(){print("It's Ja10_6_19.A.B");}
            }
        }
        public static void main(String[] args){
            A.B b=new A.B();
            b.f();
        }
    }
    

    练习20:

    /* Create an interface containing a nested class. Implement this interface and 
    * create an instance of the nested class.
    */
    import static net.mindview.util.Print.*;
    public interface Ja10_7_20{
        void f();
        class B implements Ja10_7_20{
            public void f(){print("sds");}
            public static void main(String[] args){
                B b=new B();
                b.f();
            }
        }
    }
    

    练习21:

    /* Create an interface that contains a nested class that has a static method that
    * calls the methods of your interface and displays the results. Implement your
    * interface and pass an instance of your implementation to the method. 
    */
    import static net.mindview.util.Print.*;
    interface A{
        public void f();
        public static class B{
            static void ff(Ja10_7_21 i){
                print(i);
            }
        }
    }
    public class Ja10_7_21 implements A{
        public void f(){print("sooos");}
        public static void main(String[] args){
            Ja10_7_21 ja=new Ja10_7_21();
            A.B.ff(ja);
        }
    }
    

    PS:知道了调用方法ff(),只需引用A.B.ff()。B和f()都是静态的

    练习22:

    interface Selector {
      boolean end();
      Object current();
      void next();
    }	
    
    public class Ja10_8_22{
      private Object[] items;
      private int next = 0;
      public Ja10_8_22(int size) { items = new Object[size]; }
      public void add(Object x) {
        if(next < items.length)
          items[next++] = x;
      }
      private class SequenceSelector{ 
        Selector forwardSelector(){
             return new Selector() {
                private int i = 0;
                public boolean end() { return i == items.length; }
                public Object current() { return items[i]; }
                public void next() { if(i < items.length) i++; }
            };
        }
        Selector reverseSelector(){
             return new Selector() {
                private int i = items.length-1;
                public boolean end() { return i == -1; }
                public Object current() { return items[i]; }
                public void next() { if(i > -1) i--; }//[0,length-1]
            };
        
        }
      }
      public Selector selector(int i) {
        if(i==1){return new SequenceSelector().forwardSelector();}
        else{return new SequenceSelector().reverseSelector();}
      }	
      public static void main(String[] args) {
        Ja10_8_22 sequence = new Ja10_8_22(10);
        for(int i = 0; i < 10; i++)
          sequence.add(Integer.toString(i));
        Selector selector = sequence.selector(0);
        while(!selector.end()) {
          System.out.print(selector.current() + " ");
          selector.next();
        }
      }
    }
    
    
    
    

    练习23:

    /* Create an interface U with three methods. Create a class A with a method that
    * produces a reference to a U by building an anonymous inner class. Create a second
    * class B that contains an array of U. B should have one method that accepts and 
    * stores a reference to U in the array, a second method that sets a reference in
    * the array (specified by the method argument) to null, and a third method that
    * moves through the array and calls the methods in U. In main, create a group of A 
    * objects and a single B. Fill the B with U references produced by the A objects. 
    * Use the B to call back into all the A objects. Remove some of the U references
    * from the B.
    */
    import static net.mindview.util.Print.*;
    interface U{void a();void b();void c();}
    class A{
        U aA(){
            return new U(){
                public void a(){print("A.a()");}
                public void b(){print("A.b()");}
                public void c(){print("A.c()");}
            };
        }
    }
    class B{
        private U[] us;
        B(int i){us=new U[i];}
        void addU(U u, int i){
            us[i]=u;
        }
        void eraseU(int i){us[i]=null;}
        void testUs(){for(U u:us){u.a(); u.b(); u.c();}}
    }
    public class Ja10_8_23{
        public static void main(String[] args){
        B bb=new B(5);
        for(int i=0;i<5;i++){
            A aa=new A();
            bb.addU(aa.aA(),i);
        }
        //bb.testUs();
        bb.eraseU(3);
        bb.eraseU(1);
        bb.testUs();
        }
    }
    


    练习24:

    /* In GreenhouseControls.java, add Event inner classes that turn fans on and
    * off. Configure GreenhouseController.java to use these new Event objects.
    */
    import innerclasses.*;
    import innerclasses.controller.*;
    
    public class Ja10_8_24 {
      public static void main(String[] args) {
        GreenhouseControls gc = new GreenhouseControls();
        // Instead of hard-wiring, you could parse
        // configuration information from a text file here:
        gc.addEvent(gc.new Bell(900));
        Event[] eventList = {
          gc.new ThermostatNight(0),
          gc.new LightOn(200),
          gc.new LightOff(400),
          gc.new WaterOn(600),
          gc.new WaterOff(800),
          gc.new ThermostatDay(0),
          gc.new FanOn(0),
          gc.new FanOff(0)
        };	
        gc.addEvent(gc.new Restart(2000, eventList));
          gc.addEvent(
            new GreenhouseControls.Terminate(
              2000));
        gc.run();
      }
    } /* Output
    *///:~
    
    
    
    

    练习25:

    /* Inherit from GreenhouseControls in GreenhouseControls.java to add Event
    * inner classes that turn water mist generators on and off. Write a new
    * version of GreenhouseController.java to use these new Event objects.
    */
    import innerclasses.*;
    import innerclasses.controller.*;
    class GreenhouseControls2 extends GreenhouseControls{
        private boolean jet=false;
        public class JetOn extends Event{
            public JetOn(long delayTime){super(delayTime);}
            public void action(){jet=true;}
            public String toString(){return "Jet is on.";}
        }
        public class JetOff extends Event{
            public JetOff(long delayTime){super(delayTime);}
            public void action(){jet=false;}
            public String toString(){return "Jet is false.";}
        }
    }
    public class Ja10_8_25 {
      public static void main(String[] args) {
        GreenhouseControls2 gc = new GreenhouseControls2();
        // Instead of hard-wiring, you could parse
        // configuration information from a text file here:
        gc.addEvent(gc.new Bell(900));
        Event[] eventList = {
          gc.new ThermostatNight(0),
          gc.new LightOn(200),
          gc.new LightOff(400),
          gc.new WaterOn(600),
          gc.new WaterOff(800),
          gc.new ThermostatDay(0),
          gc.new FanOn(0),
          gc.new FanOff(0),
          gc.new JetOn(0),
          gc.new JetOff(0)
        };	
        gc.addEvent(gc.new Restart(2000, eventList));
          gc.addEvent(
            new GreenhouseControls.Terminate(
              2000));
        gc.run();
      }
    }
    
    
    

    练习26:

    /* Create a class with an inner class that has a non-default constructor
    * (one that takes arguments). Create a second class with an inner
    * class that inherits from the first inner class.
    */
    
    import static net.mindview.util.Print.*;
    class A{
        class inA{
            inA(){print("A.inA()");}
        }
    }
    class B{
        class inB extends A.inA{
            inB(A a){a.super();}
        }
    }
    public class Ja10_8_26{
        public static void main(String[] args){
            A a=new A();
            B b=new B();
            B.inB inb=b.new inB(a);
        }
    }
    
    
    


    展开全文
  • Java编程思想第四版13章 个人练习

    千次阅读 2015-03-26 17:07:49
    练习12:(5)修改groups.java,找出所有不以大写字母开头的单词,不重复的计算其个数。   package thinkjava13; import java.util.HashSet; import java.util.Set; import java.util.regex.Matcher; import ...

     

    练习12:(5)修改groups.java,找出所有不以大写字母开头的单词,不重复的计算其个数。

     

    package thinkjava13;
    
    import java.util.HashSet;
    import java.util.Set;
    import java.util.regex.Matcher;
    import java.util.regex.Pattern;
    
    public class A05Groups  {
    	public static final String POEM="Twas briling,and the slithy toves\n"+
    	"Did gyre and gimble in the wabe,"+
    	"Did gyre and gimble in the wabe,\n"+
    	"All mimsy were the borogoves ,\n"+
    	"And the mome raths outgrabe.\n\n"+
    	"Beware the Jabberwock. my son,\n"+
    	"The jaws that bite ,the claww that catch. \n"+
    	"Beware the Jubjub bird,and shun\n"+
    	"The frumious Bandersnath.";
    	public static void main(String args[]){
    		//(?m):打开多行模式
    		Matcher m=Pattern.compile("(?m)(\\S+)\\s+((\\S+)\\s+(\\S+))$").matcher(POEM);
    		while(m.find()){
    			for(int i=0;i<=m.groupCount();i++){
    				System.out.print(i+"->【"+m.group(i)+"】\t");
    			}
    			System.out.println();
    		}
    		System.out.println("-----------------------------------");
    		Matcher m1=Pattern.compile("(?m)\\W([a-z]+)\\W").matcher(POEM);
    		Set<String> set=new HashSet<String>();
    		int count=0;
    		int total=0;
    		while(m1.find()){
    			String word=m1.group(1);
    			if(set.contains(word)){
    				total++;
    			}else{
    				count++;
    				set.add(word);
    			}
    			m1.region(m1.end()-1, POEM.length());
    		}
    		System.out.println("总共匹配非重复个数:"+count+"\t重复:"+total);
    		System.out.println(set);
    	}
    	/**
    	 * 输出结果如下:
    	 * 0->【the slithy toves】	1->【the】	2->【slithy toves】	3->【slithy】	4->【toves】	
    0->【in the wabe,】	1->【in】	2->【the wabe,】	3->【the】	4->【wabe,】	
    0->【the borogoves ,】	1->【the】	2->【borogoves ,】	3->【borogoves】	4->【,】	
    0->【mome raths outgrabe.】	1->【mome】	2->【raths outgrabe.】	3->【raths】	4->【outgrabe.】	
    0->【Jabberwock. my son,】	1->【Jabberwock.】	2->【my son,】	3->【my】	4->【son,】	
    0->【Jubjub bird,and shun】	1->【Jubjub】	2->【bird,and shun】	3->【bird,and】	4->【shun】	
    0->【The frumious Bandersnath.】	1->【The】	2->【frumious Bandersnath.】	3->【frumious】	4->【Bandersnath.】	
    -----------------------------------
    总共匹配非重复个数:25	重复:15
    [briling, catch, jaws, shun, raths, were, borogoves, claww, mome, frumious, son, the, in, my, wabe, gimble, and, bird, that, bite, slithy, mimsy, outgrabe, gyre, toves]
    
    	 */
    }

     

     

     

     

     

    展开全文
  • (3.2节+(3.8-3.16小节)+综合题) ...import java.util.Scanner; public class T1 { public static void main(String[] args) { Scanner input=new Scanner(System.in); System.out.print("Enter a, b, c:...
  • Java虚拟机JM( Java Virtual Machine)在Java编程里面具有非常重要的地位,约 相当于前面学到的Java运行环境,虚拟机的基本功能如下: (1):通过 Classloader寻找和装载 class文件 (2):解释字节码成为指令并执行,提供 ...
  • } /** * 运行结果 Lily howing 88barking */ } 练习8:(1)编写具有两个方法的类,在一个方法内调用二个方法两次:一次调用时不使用this关键字,二次调用时使用this关键字-- * 这里只是为了验证它...
  • Java编程思想(4版本)1-15章笔记

    千次阅读 多人点赞 2020-11-02 11:17:51
    **注:**大学本科在读学生,趁着课余时间想多了解些Java知识,很多人推荐我读一读《Java编程思想》这本书,网上的口碑也非常不错,于是就买来看看。这本书读起来比较生涩,不适合初学Java的小白读,毕竟是元老级别的...
  • 文章目录基础知识为什么要使用并发编程多线程应用场景并发编程有什么缺点并发编程三个必要因素是什么?在 Java 程序中怎么保证多线程的运行安全?并行和并发有什么区别?什么是多线程多线程的好处多线程的劣势:线程...
  • 三章 练习9
  • 7-30 模式识别方面:个连续相等的数 7-31 合并两个有序列表 7-32 划分列表 7-33 文化:中国生肖 7-34 对字符串中的字符排序 7-35 游戏:猜字游戏 需要书籍或者相关资料可以私聊!!! 7-1 指定等级 import java....
  • Java编程思想(第四版)*第二章 个人练习 创建一个类,它包含一个int域和一个char域, 他们都没有被初始化,将他们打印出来, 以验证java执行了默认初始化。 创建一个Hello,world程序,该程序只要输出这句话即可。 ...
  • Java动态生成word文档(图文并茂)

    千次阅读 2018-05-07 16:39:03
    很多情况下,软件开发者需要从数据库读取数据,然后将数据动态填充到手工预先准备好的Word模板文档里,这对于大批量生成拥有相同格式排版的正式文件非常有用,这个功能应用PageOffice的基本动态填充功能即可实现。...
  • JAVA编程习题及答案_完美

    万次阅读 2017-08-15 20:01:12
    1.test10001显示短句 ...//在屏幕上显示一个短句“Programming in Java is fun!” import java.io.*; public class Test10001{  public static void main(String args[]){  /*----------------------
  • Java8函数式编程(一)

    千次阅读 2017-08-03 22:53:28
    函数式编程详解: 前言: 现在有很多公司都用了jdk8,但是函数式编程也许没有用上,jdk8也提供了很多API,比喻Stream API,等等。流式编程是它提供串行和并行两种模式进行汇聚操作,并发模式能够充分利用多核处理器的...
  • Java面试题大全(2021

    万次阅读 多人点赞 2020-11-25 11:55:31
    发现网上很多Java面试题都没有答案,所以花了很长时间搜集整理出来了这套Java面试题大全,希望对大家有帮助哈~ 本套Java面试题大全,全的不能再全,哈哈~ 一、Java基础知识面试题 1、Java概述 ①. 何为编程 ...
  • 再网上看了很多的java面试题,有很多都是零零碎碎的,有或者是需要付费加密????的,加个vip什么的,故而以下是博主整理的有关java面试题的以下内容,我想以一种幽默风趣????的风格来给大家分享和探讨。另外附加有...
  • Java抽取word里面文本

    千次阅读 2017-08-25 18:25:00
    介绍现在 microsoft word 有好几个版本 97、2003、2007的,这三个版本存储数据的格式上都有相当大的差别,而现在 97 基本上已经退出市场。本文考虑后面二个版本,要求能够读取 word 中的文字内容,而忽略其中的文字...
  • 这是作者的系列网络安全自学教程,主要是关于网安工具和实践操作的在线笔记,特分享出来与博友共勉,希望您们喜欢,一起进步。前文分享了Wireshark抓包原理知识,并结合NetworkMiner工具抓取了图像资源和用户名密码...
  • java 网络编程【10】 HTTP协议详解

    千次阅读 2012-05-03 21:48:43
    【1】http协议概念,http1.0与http1.1 区别: 1.http(Hypertext Transfer Protocol)超文本转出协议,从...它于1990年提出,经过几年的使用与发展,得到不断地完善和扩展。目前在WWW中使用的是HTTP/1.0的,HT
  • 一、 前言 在实际开发中,经常会遇到根据给定模板生成Word文档的需求。大体操作是维护一份模板,再通过给这份模板中的变量赋予指定的值,最后调用转换接口,... 它不是面向最终用户的,而是一个Java类库,是一款程序
  • import java.io.File; import java.io.PrintWriter; public class dishierzhang { public static void main(String[] args) throws Exception { String str1; StringBuilder s1 = new StringBuilder(); File file...
  • Java并发编程的艺术》读书笔记

    千次阅读 2021-11-20 10:08:09
    1、并发编程的挑战 上下文切换 即使是单核处理器也支持多线程处理代码,因为cpu会给每个线程分配时间片,不停的切换线程,让我们感觉线程是在同时执行的 在线程切换的前,需要保留上一个线程任务的状态,以便下一次...
  • java语言程序设计基础篇十二章编程练习题

    万次阅读 多人点赞 2016-09-08 22:21:06
    1package yongheng; import java.util.Scanner;public class Calculator { public static void main(String[] args) { Scanner cin = new Scanner(System.in); String str = cin.nextLine();
  • Java高并发核心编程.卷2,多线程、锁、JMM、JUC、高并发设计模式》 目录 1章 多线程原理与实战 1.2 无处不在的进程和线程 1.2.1 进程的基本原理 1.2.2 线程的基本原理 1.2.3 进程与线程的区别 1.3 创建...
  • 阿里Java面经大全(整合

    万次阅读 多人点赞 2018-08-03 16:10:12
    阿里巴巴,三面,java实习 昨天晚上11点打电话来,问我可以面试不,我说不可以,然后就约到了今天, 1.上来问我项目用的框架,然后问我springmvc里面有的参数的设定,问的是细节,然后问我如果传的多个值是一个...
  • JavaSE实战——网络编程

    千次阅读 2015-09-24 16:00:26
    本篇博客主要介绍了Java基础的网络编程部分。涉及到基本的网络元素,诸如IP地址、端口、协议、套接字等;接着介绍了面向无连接的UDP用户数据报协议、面向连接的TCP传输控制协议,并实现了发送端接收端聊天、客户端...
  • java网络爬虫介绍

    万次阅读 2019-05-19 14:48:44
    二、java常见爬虫框架介绍 三、WebCollector实战 、项目源码下载 五、参考文章 一、网络爬虫基本介绍 1. 什么是网络爬虫   网络爬虫(又被称为网页蜘蛛,网络机器人,在社区中间,更经常的称为网页追逐者...
  • 并发编程面试题(2020最新

    万次阅读 多人点赞 2020-03-14 17:28:01
    文章目录基础知识并发编程的优缺点为什么要使用并发编程(并发编程的优点)并发编程有什么缺点并发编程三要素是什么?在 Java 程序中怎么保证多线程的运行安全?并行和并发有什么区别?什么是多线程,多线程的优劣?...

空空如也

空空如也

1 2 3 4 5 ... 20
收藏数 19,841
精华内容 7,936
关键字:

java网络编程第四版word

java 订阅