牛客Java刷题总结

1. java.awt**:**提供了绘图和图像类,主要用于编写GUI程序,包括按钮、标签等常用组件以及相应的事件类。

2. java.lang**:**java的语言包,是核心包,默认导入到用户程序,包中有object类,数据类型包装类,数学类,字符串类,系统和运行时类,操作类,线程类,错误和异常处理类,过程类。

3. java.io**:**包含提供多种输出输入功能的类。

4. java.net**:** 包含执行与网络有关的类,如URL,SCOKET,SEVERSOCKET等。

5. java.applet**:**包含java小应用程序的类。

6. java.util**:**包含集合框架、遗留的 collection 类、事件模型、日期和时间设施、国际化和各种实用工具类(字符串标记生成器、随机数生成器和位数组、日期Date类、堆栈Stack类、向量Vector类等)。集合类、时间处理模式、日期时间工具等各类常用工具包。

7. java.sql**:**提供使用 JavaTM 编程语言访问并处理存储在数据源(通常是一个关系数据库)中的数据的 API

方法重写

1. 参数 方法名 返回值类型相同
2. 子类访问权限大于等于父类
3. 子类抛出异常小于等于父类

final

final类的方法能否被同一个包的类访问不是由final决定,final只管能不能修改,不管访问

switch

switch的执行是相当于一堆if 从上到下,而不是else if,所以中间需要使用break 进行阻断
switch 的括号里 可填入的类型有 String char int short byte;
https://www.nowcoder.com/test/question/done?tid=51697096&qid=26058#summary

try catch finally

/*
try 中如果有了一场那么就跳到catch中,
如果try中有return 并且存在finally 的话,那么先执行finally 在执行return
finally 无论有没有都会执行
不管catch 是否捕获异常 finally中的语句块都是要被执行的
在try 语句块或catch语句中执行到System.exit(0) 会直接推出程序
finally 块中的return 语句会覆盖try块中的return返回

finally 中的语句块在catch 语句块中的return 语句执行后执行, 但是只是在执行了return 后,会将结果记下,然后执行finally 中的结果,最终在返回记下的结果
*/

取余符号中含有负数

 System.out.println(12%5); 2
 System.out.println(-12%5); -2
 System.out.println(12%-5); 2
 System.out.println(-12%-5); -2
 被取余的符合和答案的符号一致
 

servlet 的service方法到底是怎么执行的

servlet 的service方法通过重写do***()方法来执行

service方法,一般来说这个方法是不需要重写的,因为在HttpServlet中已经有了很好的实现,它会根据请求的方式,调用doGet,doPos以及其他的doXXXt方法,也就是说service是用来转向的,所以我们一般写一个servlet,只需要重写doGet或者doPost就可以了。

servlet 的生命周期

牛客Java刷题总结_第1张图片

服务器启动的时候(web.xml配置load-on-startup = 1),默认为0 或者第一次请求该servlet时,就会初始化一个对象,也就是会执行初始化方法(init),该servlet对象去处理所有对象的客户端请求,在service(req,resp)方法中执行,使用destroy方法去销毁


Java的三大注解

2.@Override 注解表名子类中覆盖了超类中的某个方法,如果写错了覆盖形式,编译器会报错
3.@Deprecated 表明不希望别人在以后使用这个类,方法,变量等等
4.@Suppresswarnings 达到抑制编译器产生警告的目的,但是不建议使用,因为后期编码人员看不懂编译器提示的警告,不能更好的选择更好的类去完成任务

父类与 子类的初始化

如果一个类有其父类的话,那么在在创建一个子类的实例的时候,会调用指定的父类的构造函数,
如果没有指定,就会默认调用无参的构造函数,如果父类没有无参构造,那么就会报错

赋值符号

<<表示左移位
>>表示带符号右移位
>>>表示无符号右移
但是没有<<<运算符

Collection接口的继承体系

								Collection
				List									Set
	ArrayLIst  LinkedList Vector		hashset linkedHashSet  TreeSet

java中的字节流和字符流

字节流:
InputStream  
|-- FileInputStream (基本文件流)  
|-- BufferedInputStream  
|-- DataInputStream  
|-- ObjectInputStream
字符流
Reader 
|-- InputStreamReader (byte->char 桥梁) 
|-- BufferedReader (常用) 
Writer 
|-- OutputStreamWriter (char->byte 桥梁) 
|-- BufferedWriter 
|-- PrintWriter (常用)

可以获取cookie的方法

request.getHeader
request.getCookies


1)Cookie[] getCookies()
返回一个数组,包含客户端发送该请求的所有的 Cookie 对象。

2)Object getAttribute(String name)
以对象形式返回已命名属性的值,如果没有给定名称的属性存在,则返回 null。

3)String getHeader(String name)
以字符串形式返回指定的请求头的值。Cookie也是头的一种;

4)String getParameter(String name)
以字符串形式返回请求参数的值,或者如果参数不存在则返回 null

java 小数处理

 double d1=12.5;
System.out.println("Ceil d1="+Math.ceil(d1));//13.0 // 向下取整
System.out.println("floor d1="+Math.floor(d1));//12.0 向上取整
System.out.println("Round d1 = "+ Math.round(d1));//13 四舍五入
对于 Math.round 正数四舍五入  负数六舍五入
System.out.println(String.format("%.2f", d1));//12.50 四舍五入保留两位小数

String StringBuilder StringBUffer

一般来讲的运行效率
StringBuilder > StringBuffer > String

区别
StringBuffer 可变字符序列 效率低 线程安全
StringBuilder 可变字符序列, 效率高 线程不安全

String 使用陷阱

img

类的初始化过程

初始化 父类中的静态成员变量和静态代码块
初始化子类中的静态成员变量 和 静态代码块
初始化父类中的普通成员变量在执行父类的静态构造方法
初始化子类中的普通成员变量再执行子类中的静态构造方法

接口和抽象类的区别

1. 关键字
抽象类
1.8 以前 抽象类的方法默认为 protected
1.8 时 抽象类的默认访问权限为default
可以定义调用 静态方法
但是 public 和 protect 也都可以

接口 1.8 以前接口中的方法必须是public
	1.8 允许 public abstract static 和 strictfp(精确浮点)
	1.9 时接口中的方法可以时private
2.抽象类单继承 接口可以多实现,并且在接口之间可以实现多继承
3. 抽象类允许包含某些方法的实现,而接口是不允许的;
接口中的变量 是 public static final 类型
接口中的方法 默认是 public abstract

线程中的join方法

线程中的join方法,是将该线程加入到当前的线程,比如 在线程B中 A.join(),那么之后当A执行完之后才回去执行线程B

Java关键字牛客Java刷题总结_第2张图片

在看题的时候要区分标识符和关键字i

标识符的明明规范是
Java标识符命名规范是:
1)只能包含字母a-zA-Z,数字0-9,下划线_和美元符号$;
2)首字母不能为数字;
3)关键字和保留字不能作为标识符。

Java中的位运算操作

&按位与
|按位或
~按位取反
^按位异或
>>右移
>>>无符号右移
<<左移

表达式(short)10/10.2*2运算后结果类型是

首先要注意的是 (short)10/10.2*2 而不是 (short) (10/10.2*2),又因为式子中存在浮点数,所以结果会进行自动类型的提升,浮点数默认为double,所以答案是double

父类和子类之间的调用

只要是被子类重写的方法,不被super调用都是调用子类方法
假定Base b = new Derived(); 调用执行b.methodOne()后,输出结果是什么?

public class Base
{
   public void methodOne()
   {
      System.out.print("A");
      methodTwo();
   }
 
   public void methodTwo()
   {
      System.out.print("B");
   }
}
 
public class Derived extends Base
{
   public void methodOne()
   {
      super.methodOne();
      System.out.print("C");
   }
 
   public void methodTwo()
   {
      super.methodTwo();
      System.out.print("D");
   }
}结果为ABDC

JavaEE中的包

javax.servlet
javax.servlet.jsp
java.servlet.jsp.el
java.servlet.jsp.tagext
而最用得多的就是
javax.servlet
javax.servlet.http
这两个包了.

mysql中的组合索引


常见的代码优化技术

常见的代码优化技术有:复写传播,删除死代码, 强度削弱,归纳变量删除

(下面抄几页PPT和别人的博客,QAQ,关键是编译原理没认真学过,咱家不太会。。。)

如果有同学有研究过这部分内容,并总结过,有更好的答案,请联系我删除本篇非原创解答

复写传播:
图片说明

复写语句:形式为f = g 的赋值
优化过程中会大量引入复写
复写传播变换的做法是在复写语句f = g后,尽可能用g代表f
复写传播变换本身并不是优化,但它给其他优化带来机会
	常量合并(编译时可完成的计算)
	死代码删除
死代码删除
	死代码是指计算的结果决不被引用的语句
	一些优化变换可能会引起死代码
代码外提
	代码外提是循环优化的一种
	循环优化的其它重要技术
		归纳变量删除
		强度削弱
while(i <= limit - 2) ...
// 代码外提后变成
t = limit - 2;
while(i <= t) ...

归纳变量删除
复制代码

j = j - 1
t4 = 4 * j
t5 = a[t4]
if t5 > value goto B3

j和t4的值步伐一致地变化,这样的变量叫作归纳变量
在循环中有多个归纳变量时,也许只需要留下一个
这个操作由归纳变量删除过程来完成
对本例可以先做强度削弱,它给删除归纳变量创造机会
强度削弱
强度削弱的本质是把强度大的运算换算成强度小的运算,例如将乘法换成加法运算。

Java中四种包的访问权限

public 	当前类 同包 子类 其他
protect 当前类 同包 子类 
default 当前类 同包
private 当前类

已知有下列Test类的说明,在该类的main方法的横线处,则下列哪个语句是正确的?()
public class Test
{
private float f = 1.0f;
int m = 12;
static int n = 1;
public static void main (String args[])
{
Test t = new Test();
————————
}
}
A t.f = 1  B this.n = 1; C Test.m = 1; D Test.f = 1;

A : 虽然是在main方法中,但仍然是在当前类中,所以仍然是可以调用private 变量
B : this 不能在静态方法中使用
C : 使用类名只能调用静态变量
D : 和 C 相同

JDBC 中 Statement PrepareStatement 和 CallableStatement 的区别

联系

1. Statement PrerpareStatement 和 CallableStatement 都是接口
2. Statement 继承自Wrapper, PrepareStatement 继承自Statement, CallableStatement 继承自PrepareStatement

不同点

包含方法
2.  Statement 接口提供了执行语句和获取结果的基本方法
	PrepareStatement 接口添加了处理IN参数的方法
	CallableStatement接口添加了处理OUT参数的方法
性能
3. 	Statement 普通的不带参的查询sql;支持批量更新 批量删除
	PrepareStatement 可变参数的sql,编译一次多次执行,效率高
					 安全性好,可以防止sql注入的风险
					 支持批量更新批量删除
	CallableStatement 支持调用存储过程,提供了对输出和输入/输出参数(INOUT)的支持;
	


    JDBC提供了Statement、PreparedStatement 和 CallableStatement三种方式来执行查询语句,其中 Statement 用于通用查询, PreparedStatement 用于执行参数化查询,而 CallableStatement则是用于存储过程
    https://blog.csdn.net/qq_35448976/article/details/68107591

System.gc()

用于自主垃圾回收
但是 这个方法只是提醒JVM可以进行一次Full GC,但是真正什么时候执行,还是不确定的

Java中实现同步的两种方式

同步块

对于同步来说,都是使用synchronized 方法
每一个对象都有一个监视器,或者叫锁
同步块实例

package ticket; 
class Tickets { 
    public static void main(String[] args)
    {
        sellTickets st = new sellTickets(); //四个线程同时卖这100张票,注意是同一个对象创建四个线程,他们共享同一个变量ticket new Thread(st).start(); new Thread(st).start(); new Thread(st).start(); new Thread(st).start();
    }
} 

class sellTickets implements Runnable {
    int ticket = 100;
    Object o = new Object();
    @Override public void run() { while(true)
        { //每一个对象都有一个监视器,或者叫做锁。同步块示例 synchronized (o) { if(ticket > 0)
                { //存在的隐藏的问题当ticket=1,它的时间片到期了进入到if语句中,第二个线程进入到if语句然后时间片到期 try { //线程睡眠,该方法需要写异常 Thread.sleep(10);
                    } catch (InterruptedException e) {
                        e.printStackTrace();                   
                    } //第几个线程卖出了第多少张票 System.out.println(Thread.currentThread().getName() + "sell tickets" + ticket);
                    ticket--;
                }
            }
        }
    }
}
Java和 C++ 都具有封装 继承 和多态

下面复制语句正确的是

double d  = 5.3e12 正确
float f = 11.1 错误,在Java中默认的浮点数是double,所以这里要实现强转,
					在Java中定义float变量的方法 (float)11.1 或者11.1f
					
					

ServletConfig接口默认是哪里实现的?

牛客Java刷题总结_第3张图片

GenericServlet类的实现接口中包括了ServletConfig接口,但是它自身的init(ServletConfig config)方法又需要外界给它传递一个实现ServletConfig的对象,就是说GenericServlet和ServletConfig的依赖关系既是继承关系,也是一种关联关系。

Java中的字符流和字节流

牛客Java刷题总结_第4张图片

一般辨认 字符流都是writer 和 Reader
字节流都是 Stream

Java中并发编程的同步器

常用

CountDowmLatch

Semaphore

不常用

Barrer

Exchanger

Socket 通信编程


判断操作是否需要同步

判断是否是原子操作,是则不需要

Java内存区域

牛客Java刷题总结_第5张图片

Java的jvm内存可分为三个区, 堆 栈方法区

每个线程包含一个栈区,栈中只保存方法中(不包括对象的成员变量)的基础数据类型和自定义对象的引用(不是对象),对象都存放在堆区中
每个栈中的数据(原始类型和对象引用)都是私有的,其他栈不能访问。
栈分为3个部分:基本类型变量区、执行环境上下文、操作指令区(存放操作指令)。
堆区:
存储的全部是对象实例,每个对象都包含一个与之对应的class的信息(class信息存放在方法区)。
jvm只有一个堆区(heap)被所有线程共享,堆中不存放基本类型和对象引用,只存放对象本身,几乎所有的对象实例和数组都在堆中分配。
方法区:
又叫静态区,跟堆一样,被所有的线程共享。它用于存储已经被虚拟机加载的类信息、常量、静态变量

局部内部类(不加访问修饰符,只能加 abstract 和 final)

public class OutterType {   
    public void function() {
        /** 局部内部类Inner*/
        class Inner {
            public void print() {
                System.out.println("局部内部类...");
            }
        }
    }
}

外部类

外部类的修饰符只能是 public default

成员内部类(可以使用public protected private 进行修饰)

class Circle {
    double radius = 0;
     
    public Circle(double radius) {
        this.radius = radius;
    }
     
    class Draw {     //内部类
        public void drawSahpe() {
            System.out.println("drawshape");
        }
    }
}

接口中的变量

接口中的变量默认是由 
public static final 进行修饰的

ArrayLIst 和 LinkedList 比较

ArrayList 增删慢 查询快
/*
	由于是基于数组是心啊,需要连续的内存空间,如果删除数组中间的值,为了保证下标有效性,所以要将后面的数据往前移,所以删除慢,
	当插入A 到 B 的前面的时候,要将 B 往后的对象都往后移一位,所以慢
	因为数组的大小是固定的,如果数组满了,就要重新分配空间,然后将旧的数据copy到新new的数组中,所以增加慢
*/
/*
	因为是连续空间,可以通过下标查询数据 所以查询块
*/

LinkedList 增删快 查询慢

/*
	由于是链表实现,当前节点的next 指向下一个节点,prev 指向上一个节点,不需要连续的存储空间,所以增删快,因为不是连续内存空间,所以不能使用下标查询,只能通过 next 遍历
*/


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

/*
公式-n=~n+1可推出~n=-n-1,所以~10=-11再加5结果为-6
*/

final 关键字

/*
	修饰类 那么这个类不能再被继承
	
	修饰变量 那么这个变量只能被赋值一次 并且 需要被初始化
	
	修饰方法 那么这个方法就不能再被重写 可以被重载

*/

Java中创建对象的方法

1. 使用new 关键字
2. 使用反射的Class 类的newInstance() 方法
3. 使用泛着的 Construcor 类的newInstance方法
4. 使用 使用对象克隆clone()方法: ObjectName obj = obj.clone(); 
5. 使用反序列化(ObjectInputStream)的readObject()方法:
try (ObjectInputStream ois = new ObjectInputStream(new FileInputStream(FILE_NAME))) { ObjectName obj = ois.readObject(); }

Integer 的自动装箱 和 自动拆箱

牛客Java刷题总结_第6张图片

在这里 a1 == a2 Integer 自动装箱的范围是 -127 ~ 128,所以不相等
d1 = d2 d1 自动拆箱得到 2017 所以 和 d2 相等

四种引用

强
弱
虚
软

二维数组创建方法

float []f[] = new float[6][6];

float f[][] = new float[6][6];

float [][]f = new float[6][6];

float [][]f = new float[6][];

数组的比较

数组的 equals 是继承于Object 也即是说 ==,所以不会比较其中的内容

Arrays.equals(nums,nums) 是重写过了的,比较的是 其中的值

Object 中的方法

clone
equals
finallize
getClass()
notify
notityAll
hashCode
toString
wait()

count = count ++

count = count++  原理是 temp = count; count = count+1 ; count = temp;   因此count始终是0 这仅限于java 与c是不一样的


HashMap特点

HashMap不能保证元素的顺序, 键值都可以是 null

值传递和引用传递

值传递 call by value
引用传递 call by reference
值传递不改变实际的值
引用传递会改变实际的值
值传递和引用传递都不会改变相应的地址

volatile 和 synchronized 的功能

volatile 保证 有序性 和 可见性

synchronized 保证 原子性 有序性 可见性

Java的数据库链接库JDBC使用到了那种设计模式

桥接模式 jdbc 提供两套接口,一个面向数据库厂商,一个面向数据库的使用者

数据类型

byte Boolean short char int float long double
1     1       2     2    4   4     8     8

import java.util.*;

只能访问该目录下的类不能访问该目录下的子目录的类

字符界面下接受用户从键盘输入,需要import的包是:

java.io包

关于静态块和构造块的加载

public class B
{
    public static B t1 = new B();
    public static B t2 = new B();
    {
        System.out.println("构造块");
    }
    static
    {
        System.out.println("静态块");
    }
    public static void main(String[] args)
    {
        B t = new B();
    }
}
// 在加载静态域的时候,是根据代码的顺序进行加载的,  加载构造函数和构造块永远是按照先构造块后构造函数进行加载的
1.程序入口main方法要执行首先加载类 B,
2.静态域: 分为静态变量,静态方法,静态块。这里涉及到的是静态变量和静态块,当执行到静态域的时候,按照静态域的顺序加载,并且静态域只在类的第一次加载的时候执行。
3.每次new 对象的时候,会执行一次构造快和构造方法,构造快总是在构造方法前执行。
4.根据前三点,首先加载静态类B,执行静态域的第一个静态变量,t1,此时因为静态域已经加载过了,所以加载构造块和构造器,输出构造块和构造方法(这里的构造方法并没有输出什么),在加载t2的构造块并输出 构造块
5.此时在加载t的时候加载的静态域中的静态变量加载完了,下来加载静态块,输出静态块
6.此时 t的静态域加载完了,开始加载构造块和构造方法,输出 构造块

新线程的起点

public void run(){

}
start 方法是启动一个新的线程,当执行run方法的时候,线程才开始执行

Applet 类


你可能感兴趣的:(笔记,java)