• 面试2——java基础2


    11、MVC设计模型

    mvc设计模型是一种使用model-view-controller(模型-视图-控制器)设计创建web应用程序的模式。是一种开发模式,好处是可以将界面和业务逻辑分离。

    model:是程序的主体,主要包含业务数据和业务逻辑。是应用程序中处理应用程序数据逻辑的部分。通常模型对象负责在数据库中存取数据。

    view:视图层,就是UI界面,用于跟用户进行交互。一般所有的JSP、Html等页面就是View层。是应用程序中处理数据显示的部分。通常视图是依据模型数据创建的

    controller:是应用程序中处理用户交互的部分。通常控制器负责从视图读取数据,控制用户输入,并向模型发送数据


    12.什么是反射

    在运行状态中,对于任意一个类,都能知道这个类的所有属性和方法,对于任意一个对象,都能够调用它的任意方法和属性。

    class Test{
        public void f(){
            System.out.println("base");
        }
    }
    class Sub extends Test{
        public void f(){
            System.out.println("sub");
        }
    }
    public class Test2{
        public static void main(String[] args) {
            try {
            //其中一种获得类的方法。 Class c
    = Class.forName("Sub"); Sub v = (Sub) c.newInstance(); v.f(); }catch (Exception e){ e.printStackTrace(); } } }

     反射能做什么?

    在运行时判断任意一个对象所属的类

    在运行时构造任意一个类的对象

    在运行时判断任意一个类所具有的成员变量和方法。

    在运行时调用任意一个对象的方法

    生成动态代理

    反射机制获取类的三种方法:

    //第一种方式:  
            Classc1 = Class.forName("Employee");  
            //第二种方式:  
            //java中每个类型都有class 属性.  
            Classc2 = Employee.class;  
       
            //第三种方式:  
            //java语言中任何一个java对象都有getClass 方法  
            Employeee = new Employee();  
            Class c3 = e.getClass(); //c3是运行时类 (e的运行时类是Employee)
    // 创建对象:获取类以后我们来创建它的对象,利用newInstance
    
            Class c =Class.forName("Employee");  
      
            //创建此Class 对象所表示的类的一个新实例  
            Object o = c.newInstance(); //调用了Employee的无参数构造方法.  

     13.java中的内部类和外部类

    外部类:包含内部类的类称为外部类,外部类的修饰符只能是public,abstract,final。

    内部类:内部类主要包括静态内部类,成员内部类,局部内部类和匿名内部类。内部类可以是静态static的,也可用public,default,protected和private修饰

    静态内部类就是被声明为static的内部类,它可以不依赖于外部类实例而被实例化,静态内部类不能与外部类具有相同的名称,不能访问外部类的普通成员变量,只能访问外部类中的静态成员和静态方法。 

    public class Test1 {
        static  double a = 1.333d;
        int b;
        static  class  Test{//  静态内部类
            public static void  main(String args[]){
                System.out.println(a);
                System.out.println(b); //访问外部非静态成员变量报错
            }
        }
    }

    成员内部类:即普通内部类,静态内部类去掉static关键字就是成员内部类,它可以自由的访问外部类的所有成员变量和方法(静态,非静态都可),只有外部类被实例化之后,这个类才能被实例化,需要注意的一点就是:非静态内部类中,不能有静态成员变量和静态方法

    public class Test1 {
        static  double a = 1.333d;
        int b = 3;
        public  class Test2{//成员内部类
    //        static  int aa;//成员内部类不能声明静态成员变量和静态方法。
           public  void  sum(){
               System.out.println(a+b);
           }
        }
        public static void main(String[] args) {
            Test1 test1 = new Test1();
            test1.new Test2().sum();  //外部类调用成员内部类中的方法。
        }
    }

    局部内部类:指定义在一个方法代码块中的类,作用范围仅是所在的代码块,是内部类中最少使用的一种类型。局部内部类像局部变量一样,不能被public,protected,private以及static修饰,只能访问方法中定义为final类型的局部变量

    public class Test1 {
        static  double a = 1.333d;
        int b = 3;
        private  String out = "this in outer";
        
        public static void main(String[] args) {
            Test1 test1 = new Test1();
           // test1.new Test2().sum();  //外部类调用成员内部类中的方法。
            //test1.Test3();
            test1.Test3();
        }
    
        public void Test3(){
            final int c = 12;
            final double d = 33.333d;
            class innerclass{
                private  String out = "this is inner";
                public void method(){
                    System.out.println(d+c);//内部类访问外部方法的变量,需要有final进行修饰。
                    System.out.println(a);
                    System.out.println(out);//局部内部类可以直接访问外部类的变量,即使是私有的
                    System.out.println(Test1.this.out);//访问外部类中相同名称的变量
                }
            }
            innerclass innerclass = new innerclass();//在代码块中对局部内部类进行实例化。
            innerclass.method();
        }
    }

    匿名内部类:是一种没有类名的内部类,不使用关键字class,extends,implements,没有构造函数,他必须继承其他类或者其他接口,

    • 匿名内部类不能有构造函数
    • 匿名内部类不能定义静态成员/方法和类
    • 匿名内部类不能是public,protected,privated,static
    • 只能创建匿名内部类的一个实例
    • 一个匿名内部类一定是在new的后面,这个匿名类必须继承一个父类或实现一个接口
    • 因匿名内部类属局部内部类,所有局部内部类的所有限制都对其生效。
    public class OuterClass {
                public InnerClass getInnerClass(final int   num,String str2){
                    return new InnerClass(){
                        int number = num + 3;
                        public int getNumber(){
                            return number;
                        }
                    };        /* 注意:分号不能省 */
                }
                public static void main(String[] args) {
                    OuterClass out = new OuterClass();
                    InnerClass inner = out.getInnerClass(2, "chenssy");
                    System.out.println(inner.getNumber());
                }
            }
            interface InnerClass {
                int getNumber();
            }    

     14. 解释内存中的栈(stack)、堆(heap)和静态区(static area)的用法

    定义一个基本的数据类型,一个对象的引用,函数调用的现场保存都使用内存中的栈空间;而通过关键字new和构造器创建的对象放在堆里;程序中的字变量(literal)如直接书写的100,hello和常量都是放在静态区中。

    String str = new String("hello")  str存放在栈上,用new创建出来的字符串对象放在堆上,而“hello”这个字面量放在静态区


    15. 获取数组的长度的方法为数组名.length;获取字符串的长度为length();二者不能混淆。


    16. String、StringBuffer和StringBulider的区别?

    它们都是final类,都不允许继承

    public final class String
    extends Object
    implements Serializable, Comparable<String>, CharSequence
    
    
    public final class StringBuffer
    extends Object
    implements Serializable, CharSequence
    
    
    public final class StringBuilder
    extends Object
    implements Serializable, CharSequence

    String长度不可以变,StringBuffer、StringBuilder长度可变

    String长度不可变的原理(

     private final char value[];
    //用final修饰的对象值可变,但是引用不变,即:value指向不可变,但是value[]数组的值可变,但因为有private关键字对其进行封装达到value[]数组值也不可变的目的

    ),StringBuffer和StringBulider是长度可变的。

    StringBuffer是线程安全的,

    StringBuilder不是线程安全的,StringBuffer在StringBuilder的方法之上添加了synchronized修饰,保证线程安全。

    StringBuilder拥有更好的性能

    如果一个String类型的字符串,在编译时就可以确定一个字符串常量。此时,String的性能比StringBuilder更好


    17. Java内存分配位置

    a:基础数据类型直接在栈空间分配。

    b:方法的形式参数,直接在栈空间分配,当方法调用完成后从栈空间回收。

    c:引用数据类型,需要new来创建的,现在栈空间分配一个地址空间,实际的类变量的值放在堆空间中。

    d:方法的引用参数,在栈空间分配一个地址空间,并指向堆空间的对象区,当方法调用完后从栈空间回收。

    e:局部变量new出来时,在栈空间和堆空间中都分配空间,当局部变量生命周期结束后,栈空间立即被回收,堆空间区域等待GC回收。

    f:方法调用时传入的实际参数,先在栈空间分配,在方法调用完成后从栈空间释放。

    g:字符串常量在DATA区域分配,this在堆空间分配。

    h:创建的数组在栈空间分配数组名称,在堆空间分配数组实际的大小。

     类中的成员变量,存放在堆区;方法中的局部变量,存放在栈区


     18:static关键字的用法:

    “static方法就是没有this的方法。在static方法内部不能调用非静态方法,反过来是可以的。而且可以在没有创建任何对象的前提下,仅仅通过类本身来调用static方法。这实际上正是static方法的主要用途。”————《Java编程思想》

    1) static方法

    用static进行修饰方法的方法一般称为静态方法,静态方法不依赖任何对象就可以进行访问。在静态方法中不可以访问类的非静态成员变量和非静态成员方法,因为非静态成员方法/变量都是必须依赖具体的对象才能够被调用。但是要注意的是在非静态成员方法中是可以访问静态成员方法/变量的。

    public class T1 {
        static int aaa = 111;
        int b = 19;
        public static void name1() {
            System.out.println("这是一个静态方法");
            System.out.println(aaa);
            //System.out.println(b);//报错,不能访问非静态变量
        }
        public void name() {
            System.out.println("这不是一个静态方法");
            System.out.println(b);
            System.out.println(aaa);
            //T1.name1();
        }
        public static void main(String[] args) {
            // TODO Auto-generated method stub
            //T1.name1();//直接可以通过类名.方法名访问
            //int a =  10;
            T1 t1 = new T1();
            //t1.name(a);
            t1.name();//访问非静态方法必须通过实例化对象,进行访问。
        }
    }

    2)static变量

    static变量也称作静态变量,静态变量和非静态变量的区别是:静态变量被所有的对象所共享,在内存中只有一个副本,它当且仅当在类初次加载时会被初始化。而非静态变量是对象所拥有的,在创建对象的时候被初始化,存在多个副本,各个对象拥有的副本互不影响。static成员变量的初始化顺序按照定义的顺序进行初始化。

    3)static代码块

    static关键字还有一个比较关键的作用就是 用来形成静态代码块以优化程序性能。static块可以置于类中的任何地方,类中可以有多个static块。在类初次被加载的时候,会按照static块的顺序来执行每个static块,并且只会执行一次。


    19.Java执行顺序

    public class Parent {
        static int t = parentstaticmethod();//父类静态成员变量
        {
            System.out.println("父类非静态方法代码块");
        }
        static{
            System.out.println("父类静态方法代码块");
        }
        public Parent(){
            System.out.println("父类构造方法");
        }
        public static int parentstaticmethod(){
            System.out.println("父类静态方法");
            return 19;
        }
        public static void main(String[] args) {
            Child child = new Child();
        }
    }
     class Child extends Parent{
         {
                System.out.println("子类非静态方法代码块");
            }
            static{
                System.out.println("子类静态方法代码块");
            }
            public Child(){
                System.out.println("子类构造方法");
            }
            public static int childstaticmethod(){
                System.out.println("子类静态方法");
                return 19;
            }    
    }

    结果

    父类静态方法
    父类静态方法代码块
    子类静态方法代码块
    父类非静态方法代码块
    父类构造方法
    子类非静态方法代码块
    子类构造方法
    View Code

    20.序列化和反序列化

    当两个进程在进行远程通信时,彼此可以发送各种类型的数据。无论是何种类型的数据,都会以二进制序列的形式在网络上传送。发送方需要把这个Java对象转换为字节序列,才能在网络上传送;接收方则需要把字节序列再恢复为Java对象。

    在很多应用中,需要对某些对象进行序列化,让它们离开内存空间,入住物理硬盘,以便长期保存。比如最常见的是Web服务器中的Session对象,当有 10万用户并发访问,就有可能出现10万个Session对象,内存可能吃不消,于是Web容器就会把一些seesion先序列化到硬盘中,等要用了,再把保存在硬盘中的对象还原到内存中。

    序列化:把java对象转换为字节序列的过程

    反序列化:把字节序列恢复为java对象的过程

    import java.io.File;
    import java.io.FileInputStream;
    import java.io.FileNotFoundException;
    import java.io.FileOutputStream;
    import java.io.IOException;
    import java.io.ObjectInputStream;
    import java.io.ObjectOutputStream;
    import java.text.MessageFormat;
    
    public class TestObjSerializeAndDeserialize {
        static String pathname =  "d:/Person.txt";
        public static void main(String[] args) throws Exception {
            // TODO Auto-generated method stub
             SerializePerson();
             Person person =deSerializePerson();
             String pattern ="name={0},age={1},sex={2}";
             Object[] arguments = {person.getName(),person.getAge(),person.getSex()};
             System.out.println(MessageFormat.format(pattern, arguments));
             
        }
        private static void SerializePerson() throws FileNotFoundException,IOException{
            Person person = new Person();
            person.setAge(25);
            person.setName("nana");
            person.setSex("女");
            ObjectOutputStream oo =  new ObjectOutputStream
                    (new FileOutputStream(new File(pathname)));
            oo.writeObject(person);
            System.out.println("对象序列化成功!");
            oo.close();    
        }
        public static  Person deSerializePerson() throws Exception,IOException{
            ObjectInputStream oiStream = new ObjectInputStream
                    (new FileInputStream(new File(pathname)));
            Person person = (Person) oiStream.readObject();
            System.out.println("反序列号成功");
            return person;
        }
    }
  • 相关阅读:
    TWinHttp之二
    日志池
    TWinHTTP
    TJSONTableObject跨平台解析JSON
    TSQLTableJSON解析JSON
    TDocVariantData解析JSON
    Vue.js常用指令汇总(v-if//v-show//v-else//v-for//v-bind//v-on等)
    VUE -- 十分钟入门 Less
    VUE -- ejs模板的书写
    Go VUE --- vuejs在服务器部署?
  • 原文地址:https://www.cnblogs.com/znn93/p/9203553.html
Copyright © 2020-2023  润新知