牛客网题错题总结---java(2020.3.25)

文章目录

          • 前言
        • 1.socket编程图解
        • 2.HashMap中是用哪些方法来解决哈希冲突的?
        • 3.Java运算符优先级
        • 4.java实例变量,局部变量,类变量和final变量
        • 5.修饰符的权限
        • 6.选择
        • 7.非访问权限修饰符
        • 8.偶遇一张神图
        • 9.JavaBean
        • 10.Ant 和 Maven
        • 11.补码
        • 12.多态问题
        • 13.容器
        • 14.构造方法
        • 15.接口多继承
        • 16.Servlet的生命周期:
        • 17.下列那些方法是线程安全的(所调用的方法都存在)(ACD)

前言

之前一直使用word总结,导致有了一堆文件,而且看得时候很不方便。今天突然想的可以用这个总结,比较方便。
今天是最惨的一次 ,一次就错了17个,一共30题, 醉了。
总结了下,今天格外没耐心,错了不少不该错的。

1.socket编程图解

牛客网题错题总结---java(2020.3.25)_第1张图片

2.HashMap中是用哪些方法来解决哈希冲突的?

HashMap底层是数组+链表+红黑树(JDK1.8)来实现的,根据key的hash值查找对应的位桶。
1.当前索引数组为空,则将键值对以链表形式插入。
2.当前索引数组已经存在,则判断当前链表是红黑树还时链表,然后插入。如果是链表插入到最后一个,判断长度是否大于8,大于8将链表转成红黑树。
所以是拉链法解决冲突。

  • 解决哈希冲突常用的两种方法是:开放定址法和链地址法
    • 开放定址法:当冲突发生时,使用某种探查(亦称探测)技术在散列表中形成一个探查(测)序列。沿此序列逐个单元地查找,直到找到给定 的关键字,或者碰到一个开放的地址(即该地址单元为空)为止(若要插入,在探查到开放的地址,则可将待插入的新结点存人该地址单元)。查找时探查到开放的 地址则表明表中无待查的关键字,即查找失败。
    • 链地址法:将所有关键字为同义词的结点链接在同一个单链表中。若选定的散列表长度为m,则可将散列表定义为一个由m个头指针组成的指针数 组T[0…m-1]。凡是散列地址为i的结点,均插入到以T[i]为头指针的单链表中。T中各分量的初值均应为空指针。
  • 哈希冲突解决方法:
    - 开放地址法
    - 链地址法(拉链法)
    - 再散列
    - 建立一个公共溢出区

3.Java运算符优先级

	    int a =100,b=50,c=a---b,d=a---b;
        System.out.println(a);
        System.out.println(b);
        System.out.println(c);
        System.out.println(d);
        //98 50 50 49

牛客网题错题总结---java(2020.3.25)_第2张图片

4.java实例变量,局部变量,类变量和final变量

  • 定义在类中的变量是类的成员变量,可以不进行初始化,Java会自动进行初始化
    • 如果是引用类型默认初始化为null
    • 如果是基本类型例如int则会默认初始化为0
  • 局部变量是定义在方法中的变量,必须要进行初始化,否则不同通过编译
  • 被static关键字修饰的变量是静态的,静态变量随着类的加载而加载,所以也被称为类变量
  • 被final修饰发变量是常量

5.修饰符的权限

修饰符 类内部 同一个包 子类 任何地方
private Y
defalut Y Y
protected Y Y Y
public Y Y Y Y

6.选择

A.ConcurrentHashMap使用synchronized关键字保证线程安全 错
B.HashMap实现了Collction接口 错
C.Array.asList方法返回java.util.ArrayList对象 错
D.SimpleDateFormat是线程不安全的 对

  • ConcurrentHashMap 使用segment来分段和管理锁,segment继承自ReentrantLock,因此ConcurrentHashMap使用ReentrantLock来保证线程安全
  • public class HashMap<K,V> extends AbstractMap<K,V>
    implements Map<K,V>, Cloneable, Serializable
    
  • Arrays.asList() 返回 java.util.Arrays.ArrayList 对象,这里的 ArrayList 是 Arrays 私有的内部类

7.非访问权限修饰符

  • static 修饰符,用来创建类方法和类变量。
  • final 修饰符,用来修饰类、方法和变量,final 修饰的类不能够被继承,修饰的方法不能被继承类重新定义,修饰的变量为常量,是不可修改的。
  • abstract 修饰符,用来创建抽象类和抽象方法。
  • synchronized 用于多线程的同步。
  • volatile 修饰的成员变量在每次被线程访问时,都强制从共享内存中重新读取该成员变量的值。而且,当成员变量发生变化时,会强制线程将变化值回写到共享内存。这样在任何时刻,两个不同的线程总是看到某个成员变量的同一个值。
  • transient:序列化的对象包含被 transient 修饰的实例变量时,java 虚拟机(JVM)跳过该特定的变量。

8.偶遇一张神图

作者主页
牛客网题错题总结---java(2020.3.25)_第3张图片

9.JavaBean

(1)懂得将 Bean 放在哪个目录下:在 Resin 中 JavaBean 放在 doc\web-inf\classes 目录 中。
(2)懂得如何使用 JBuilder 定义一个 Bean;其中的语法规范不一定要记住,但要理解
其中的结构。
(3)Java 文件和 Bean所定义的类名一定要相同,并且是大小写敏感。
(4)Bean中要声明公共方法,与 Bean的名字相同。
(5)懂得如何在JSP 文件中引用JavaBean,其实就是jsp:useBean的语句。
(6)一定要紧记Java 是区分大小写的。

10.Ant 和 Maven

Ant和Maven都是基于Java的构建(build)工具。理论上来说,有些类似于(Unix)C中的make ,但没有make的缺陷。Ant是软件构建工具,Maven的定位是软件项目管理和理解工具。
Ant特点 ›
没有一个约定的目录结构 ›必须明确让ant做什么,什么时候做,然后编译,打包 ›没有生命周期,必须定义目标及其实现的任务序列 ›没有集成依赖管理
Maven特点
›拥有约定,知道你的代码在哪里,放到哪里去 ›拥有一个生命周期,例如执行 mvn install 就可以自动执行编译,测试,打包等构建过程 ›只需要定义一个pom.xml,然后把源码放到默认的目录,Maven帮你处理其他事情 ›拥有依赖管理,仓库管理

11.补码

int i = 5;
int j = 10;
System.out.println(i + ~j);
//-6

计算机本身储存的就是补码:
那么10的补码就是10的原码:0000 0000 0000 1010——这是补码,因为现在是计算机在计算
~10的补码就是:1111 1111 1111 0101
~10的反码就是:1111 1111 1111 0100——补码减1
~10的原码就是:1000 0000 0000 1011——反码取反:这个才是正常二进制数,换算为整数为-11
原码才可以对应为正常的整数,补码只有转换为原码才能被正常人类识别。

12.多态问题

多态问题中,无论向上或向下转型,都记住一句话就可以了。
编译看左边,运行看右边。
意思编译时候,看左边有没有该方法,运行的时候结果看 new 的对象是谁,就调用的谁。

13.容器

牛客网题错题总结---java(2020.3.25)_第4张图片

14.构造方法

  • 构造方法是一种特殊的方法,具有以下特点。
    (1)构造方法的方法名必须与类名相同。
    (2)构造方法没有返回类型,也不能定义为void,在方法名前面不声明方法类型。
    (3)构造方法的主要作用是完成对象的初始化工作,它能够把定义对象时的参数传给对象的域。
    (4)一个类可以定义多个构造方法,如果在定义类时没有定义构造方法,则编译系统会自动插入一个无参数的默认构造器,这个构造器不执行任何代码。
    (5)构造方法可以重载,以参数的个数,类型,顺序

15.接口多继承

  • 接口可以多继承可以被多实现,因为接口中的方法都是抽象的,这些方法都被实现的类所实现,即使多个父接口中有同名的方法,在调用这些方法时调用的时子类的中被实现的方法,不存在歧义;
  • 同时,接口的中只有静态的常量,但是由于静态变量是在编译期决定调用关系的,即使存在一定的冲突也会在编译时提示出错;
  • 而引用静态变量一般直接使用类名或接口名,从而避免产生歧义,因此也不存在多继承的第一个缺点。 对于一个接口继承多个父接口的情况也一样不存在这些缺点。
  • 所以接口可以多继承。

16.Servlet的生命周期:

  • init():仅执行一次,负责在装载Servlet时初始化Servlet对象
  • service() :核心方法,一般HttpServlet中会有get,post两种处理方式。在调用doGet和doPost方法时会构造servletRequest和servletResponse请求和响应对象作为参数。
  • destory():在停止并且卸载Servlet时执行,负责释放资源

17.下列那些方法是线程安全的(所调用的方法都存在)(ACD)

吐槽下这个题在牛客上的简直神级排版(全都堆在一块) 让我云里雾里。

  • A
    public class MyServlet implements Servlet {
    	public void service (ServletRequest req, ServletResponse resp) {
    		BigInteger I = extractFromRequest(req);
    		encodeIntoResponse(resp,factors);
    	}
    }
    
  • B
    public class MyServlet implements Servlet {
    	private long count =0;
    	public long getCount() {
    		return count;
    	}
    	public void service (ServletRequest req, ServletResponse resp) {
    		BigInteger I = extractFromRequest(req);
    		BigInteger[] factors = factor(i);
    		count ++;
    		encodeIntoResponse(resp,factors);
    	}
    }
    
  • C
    public class MyClass {
    	private int value;
    	public synchronized int get() {
    		return value;
    	}
    	public synchronized void set (int value) {
    		this.value = value;
    	}
    }
    
  • D
    public class Factorizer implements Servlet {
    	private volatile MyCache cache = new MyCache(null,null);
    	
    	public void service(ServletRequest req, ServletResponse resp) {
    		BigInteger i = extractFromRequest(req);
    		BigInteger[] factors = cache.getFactors(i);
    		if (factors == null) {
    		factors = factor(i);
    		cache = new MyCache(i,factors);
    	}
    		encodeIntoResponse(resp,factors);
    }
    

这几个类都没有类属性,不存在共享资源,为了满足题目的意思,应该是多线程情况下使用同一个对象,以达到使成员成为共享资源的目的;
A:没有成员(没有共享资源),线程安全;
B:假设存在线程1和线程2,count初始值为0,当线程1执行count++中count+1(此时未写回最终计算值),这时线程2执行count++中读取count,发生数据错误,导致线程1线程2的结果都为1,而不是线程1的结果为1,线程2的结果为2,线程不安全;
C:成员私有,对成员的set get方法都加重量级锁,线程安全;
D:volatile有两个作用:可见性(volatile变量的改变能使其他线程立即可见,但它不是线程安全的,参考B)和禁止重排序;这里是可见性的应用,类中方法对volatile修饰的变量只有赋值,线程安全.

你可能感兴趣的:(牛客错题整理)