JAVA的一些基础知识(持续更新)

这里记录了一些基础、易考点或者小冷门,持续更新,等啥时候(够呛)有时间了,整理个目录出来,有些内容会来自平常论坛浏览所得,如有原作需要链接,底部留言即可。
equals和hashcode的区别:
一句话:同一对象,hashcode一定相同,但是相同的不一定是一个对象。
所以:判断两个对象相同可以用equals,但是之前可以重写hashcode,连hashcode都不相等,自然不用再equals了,提高性能。

java的 基本数据类型:
byte、short、int、long、
double、float、
boolean、char
所占字节和范围:
一句话:都是负的,正的范围就是值-1,为啥-1呢,-1代表从中间劈开,这样正负两边值就一样了。
一句话:几字节就是2的 字节数*8-1 的次方。
1(7次方128)、2(15次方=32768)、4(31次方=2147483648)、8(63次方)
4、8
1(true或false)、2(只有正数即0~65535即2的16次方后再-1,只有正数就不需要从0劈开,自然不需要指数-1)

int与integer的区别:
一句话:integer是int的包装类,int是基本数据类型。
前者是类,需要实例化用,后者是基本数据类型,直接用就行。
前者是类,默认为null,后者默认是0。
前者是类,实例化后也是生成一个指针指向这个对象,而int是直接存储这个值。

谈谈对java多态的理解:
一句话:继承,重写,父类引用指向子类对象(即Child c = new Parent())
最大的好处:解耦。
思想:动态绑定:在执行时,判断引用对象的实际类型,进而确定实际方法。

重写重载的区别:
一句话:重写:同名同参同返回。重载:方法签名相同,参数列表不同。
重写Overriding是父类与子类之间多态性的一种表现
重载Overloading是一个类中多态性的一种表现.

String、StringBuffer、StringBuilder区别
一句话:三者在执行速度上:StringBuilder > StringBuffer > String
由于String是常量,不可改变,拼接时会重新创建新的对象。
StringBuffer是线程安全的,由于StringBuffer有缓冲区。
StringBuilder是线程不安全的。

什么是内部类?内部类的作用
一句话:将一个类定义在另一个类里面或者一个方法里面,这样的类称为内部类。
作用:每个内部类都能独立的继承一个接口的实现,所以无论外部类是否已经继承了某个(接口的)实现,对于内部类都没有影响。相当于A的内部类B,自己爱咋地咋地,A不管你,并且你可以用A的东西,A真是个好爸爸。

抽象类和接口区别:
一句话:一个子类可以继承多个接口,但是只能继承一个父类。
如果你拥有一些方法并且想让它们中的一些有默认实现,那么使用抽象类吧。

泛型中extends和super的区别:
一句话:extends 可用于返回类型限定。super 可用于参数类型限定。
前者:下面的super换成extends就报错,因为这个用于返回,只取不存可以用。
List<? extends Father> list1 = new ArrayList<>();
Object object = list1.get(0);
或者Son son = (Son)list1.get(0);
这样可以。
后者:List<? super Father> list = new ArrayList<>();,你要存,list.add(new Son());son是Father的子类,不报错。

父类的静态方法能否被子类重写:
一句话:不能。即使子类中的静态方法与父类中的静态方法完全一样,也是两个完全不同的方法。

进程和线程的区别:
一句话:一个进程内可拥有多个线程。
进程之间不能共享资源,而线程共享所在进程的地址空间和其它资源。

final,finally,finalize的区别:
final:修饰类、成员变量和成员方法,类不可被继承,成员变量不可变,成员方法不可重写
finally:与try…catch…共同使用,确保无论是否出现异常都能被调用到
finalize:类的方法,垃圾回收之前会调用此方法,子类可以重写finalize()方法实现对资源的回收

Serializable 和Parcelable 的区别:
Serializable 在硬盘上读写 i/o操作 效率很低 java中的
Parcelable 效率高 在内存中读写 对象不能保存到磁盘中 Android中的

string 转换成 integer的方式:
Intrger.parseInt方法

哪些情况下的对象会被垃圾回收机制处理掉?
这个实例没线程去用了,这个实例不被引用了。

要判断怎样的对象是没用的对象。这里有2种方法:
1.采用标记计数的方法:用的对象,标记+1,不用了-1,为0被回收,这样循环的对象无法识别。
2.根搜索算法:从一个根出发,搜索所有的可达对象,这样剩下的那些对象就是需要被回收的

静态代理和动态代理的区别:
前者:由程序员创建或由特定工具自动生成源代码,再对其编译。
后者:在程序运行时,运用反射机制动态创建而成。

Java的异常体系:
Throwable下有Error,Exception
Error是程序无法处理的错误,它是由JVM产生和抛出的,比如OutOfMemoryError(OOM)、ThreadDeath(TD)等。这些异常发生时,Java虚拟机(JVM)一般会选择线程终止。
Exception是程序本身可以处理的异常,这种异常分两大类运行时异常和非运行时异常。程序中应当尽可能去处理这些异常。
异常常见:classNotFound、NullPointer、ArrayIndexOutOfBound(数组下标越界)、MissingResource、arithmetic(计算异常)、illegalargument(方法的参数异常)、.illegalaccess(无访问权限)、ClassCast(强转异常)、SQLException(数据库操作异常)、IOException(输入输出异常)、FileNotFound(文件未找到异常)

Java反射的理解:
对于任意一个类, 都能够知道这个类的所有属性和方法; 对于任意一个对象, 都能够调用它的任意一个方法和属性。

Spring常用注解:
1.声明bean的注解
@Component 组件,没有明确的角色
@Service 在业务逻辑层使用(service层)
@Repository 在数据访问层使用(dao层)
@Controller 在展现层使用,控制器的声明(C)
2.注入bean的注解
@Autowired:由Spring提供
@Inject:由JSR-330提供
@Resource:由JSR-250提供
3.java配置类相关注解
@Configuration 声明当前类为配置类,相当于xml形式的Spring配置(类上)
@Bean 注解在方法上,声明当前方法的返回值为一个bean,替代xml中的方式(方法上)
@Configuration 声明当前类为配置类,其中内部组合了@Component注解,表明这个类是一个bean(类上)
@ComponentScan 用于对Component进行扫描,相当于xml中的(类上)
@WishlyConfiguration 为@Configuration与@ComponentScan的组合注解,可以替代这两个注解
4.切面(AOP)相关注解
@Aspect 声明一个切面(类上)
使用@After、@Before、@Around定义建言(advice),可直接将拦截规则(切点)作为参数。
@After 在方法执行之后执行(方法上)
@Before 在方法执行之前执行(方法上)
@Around 在方法执行之前与之后执行(方法上)
@PointCut 声明切点
在java配置类中使用@EnableAspectJAutoProxy注解开启Spring对AspectJ代理的支持(类上)

@Value 为属性注入值(属性上)
比如:@Value(“Michael Jackson”)String name;

5.SpringMVC相关注解:
@EnableWebMvc 在配置类中开启Web MVC的配置支持,如一些ViewResolver或者MessageConverter等,若无此句,重写WebMvcConfigurerAdapter方法(用于对SpringMVC的配置)。
@Controller 声明该类为SpringMVC中的Controller
@RequestMapping 用于映射Web请求,包括访问路径和参数(类或方法上)
@ResponseBody 支持将返回值放在response内,而不是一个页面,通常用户返回json数据(返回值旁或方法上)
@RequestBody 允许request的参数在request体中,而不是在直接连接在地址后面。(放在参数前)
@PathVariable 用于接收路径参数,比如@RequestMapping(“/hello/{name}”)申明的路径,将注解放在参数中前,即可获取该值,通常作为Restful的接口实现方法。
@RestController 该注解为一个组合注解,相当于@Controller和@ResponseBody的组合,注解在类上,意味着,该Controller的所有方法都默认加上了@ResponseBody。
@ControllerAdvice 通过该注解,我们可以将对于控制器的全局配置放置在同一个位置,注解了@Controller的类的方法可使用@ExceptionHandler、@InitBinder、@ModelAttribute注解到方法上,
这对所有注解了 @RequestMapping的控制器内的方法有效。
@ExceptionHandler 用于全局处理控制器里的异常
@InitBinder 用来设置WebDataBinder,WebDataBinder用来自动绑定前台请求参数到Model中。
@ModelAttribute 本来的作用是绑定键值对到Model里,在@ControllerAdvice中是让全局的@RequestMapping都能获得在此处设置的键值对。

java的集合以及集合之间的继承关系
首先List集合继承与Collection,是一个接口。
list:是有序的,元素可以重复,经常用到的是实现该接口的ArrayList和LinkedList类。
Arraylist: 底层的数据结构使用的是数组结构。
查询速度很快,但是增删稍慢
LinkedList: 底层使用的是链表数据结构。和上面相反。

Arraylist的遍历方式:
用for:for (Object li : list)
用迭代器:ListIterator it = list.listIterator();
这个的add用的是拷贝,比如在3位置add个“1”,就是将3后的先拿出来,在数组最后add“1”,然后在将3后的复制上。

LinkedList的遍历方式:
private LinkedList link;
link.removeLast():先进先出用
link.removeFirst():先进后出用
link.addFirst(obj);增加一个新的。

Map(不继承 Collection ,list和set继承):
HashMap:
HashMap将Entry对象存储在一个数组中,并通过哈希表来实现对Entry的快速访问。由每个Entry中的key的哈希值决定该Entry在数组中的位置。以这种特性能够实现通过key快速查找到Entry,从而获得该key对应的value。在不发生哈希冲突的前提下,查找的时间复杂度是O(1)。

如果两个不同的key计算出的index是一样的,就会发生两个不同的key都对应到数组中同一个位置的情况,也就是所谓的哈希冲突。

HashMap用法:
Map<String, String> map = new HashMap<>(3);
map.put(“welcome”,“to”);
map.put(“java”,“study”);
for (String key : map.keySet()) {
System.out.println("key is "+key);
System.out.println("value is "+ map.get(key));
}

Set:
HashSet :无序,唯一,基于 HashMap 实现的,底层采用 HashMap 来保存元素。
LinkedHashSet :LinkedHashSet 继承自 HashSet,并且其内部是通过 LinkedHashMap 来实现的。有点类似于我们之前说的LinkedHashMap 其内部是基于 HashMap 实现一样,不过还是有一点点区别的。
TreeSet :有序,唯一,红黑树(自平衡的排序二叉树)。

Set:检索元素效率高,删除和插入效率低,插入和删除不会引起元素位置改变。

HashSet 是用一个 hash 表来实现的,因此,它的元素是无序的。添加,删除和 HashSet 包括的方法的持续时间复杂度是 O(1) 。故插入删除修改用这个。
TreeSet 是用一个树形结构实现的,因此,它是有序的。添加,删除和 TreeSet 包含的方法的持续时间复杂度是 O(logn) 。故遍历用这个。

HashSet(不重复)用法:
Set set = new HashSet();
set.add(“1”);

set.remove(“1”);
遍历直接for(Set s :set)

TreeSet用法:
TreeSet set = new TreeSet();
set.add(“aaa”);
顺序遍历:
for(Iterator iter = set.iterator(); iter.hasNext(); ) {
System.out.printf(“asc : %s\n”, iter.next());
}

什么是深拷贝和浅拷贝:
一句话:前者拷贝引用传递,后置新对象连传递带值都拷贝。
浅拷贝:对基本数据类型进行值传递,对引用数据类型进行引用传递般的拷贝,此为浅拷贝。
深拷贝:对基本数据类型进行值传递,对引用数据类型,创建一个新的对象,并复制其内容,此为深拷贝。

开启线程的三种方式(含线程池):
继承Thread类、实现Runable接口和使用线程池
通过实现Runnable接口来创建Thread线程:
  步骤1:创建实现Runnable接口的类:
  Java代码
  class SomeRunnable implements Runnable
  {
  public void run()
  {
  //业务代码
  }
  }
  步骤2:创建一个类对象:
  Runnable oneRunnable = new SomeRunnable();
  步骤3:由Runnable创建一个Thread对象:
  Thread oneThread = new Thread(oneRunnable);
  步骤4:启动线程:
  oneThread.start();

通过继承Thread类来创建一个线程:
步骤1:定义一个继承Thread类的子类:
  Java代码
  class SomeThead extends Thraad
  {
  public void run()
  {
  //业务代码
  }
  }
  步骤2:构造子类的一个对象:
  SomeThread oneThread = new SomeThread();
  步骤3:启动线程:
  oneThread.start();

线程池(以固定线程池为例):
ExecutorService ex=Executors.newFixedThreadPool(5);

	for(int i=0;i<5;i++) {
		ex.submit(new Runnable() {
			
			@Override
			public void run() {
				for(int j=0;j<10;j++) {
					System.out.println(Thread.currentThread().getName()+j);
				}
				
			}
		});
	}
	ex.shutdown();

四大线程池:固定长度newfixed开头,60自动销毁newCache开头,单一newSingle开头,周期newScheduled开头
自定义线程池:
ThreadPoolExecutor

run()和start()方法区别:
一句话:run是在当前线程中调用,没有新的线程启动,start会启动新的线程
start()方法被用来启动新创建的线程,而且start()内部调用了run()方法,这和直接调用run()方法的效果不一样。当你调用run()方法的时候,只会是在原来的线程中调用,没有新的线程启动,start()方法才会启动新线程。

在Java中wait和seelp方法的不同:
sleep()方法导致了程序暂停执行指定的时间,让出cpu该其他线程,但是他的监控状态依然保持者,当指定的时间到了又会自动恢复运行状态。占着茅坑不拉屎。
在调用sleep()方法的过程中,线程不会释放对象锁。
而当调用wait()方法的时候,线程会放弃对象锁,进入等待此对象的等待锁定池,之后调用notify()才行。

java中synchronized的用法:
Java语言的关键字,当它用来修饰一个方法或者一个代码块的时候,能够保证在同一时刻最多只有一个线程执行该段代码。
举例:
public class Thread1 implements Runnable {
public void run() {
synchronized(this) {
for (int i = 0; i < 5; i++) {
System.out.println(Thread.currentThread().getName() + " synchronized loop " + i);
}
}
}
注意,如果还有其他的不加锁的,其他线程会访问不加锁的。
synchronized 用于方法:直到从该方法返回时才将锁释放。
synchronized 用于块:灵活性较高。

synchronized括号里跟的是需要“锁”的对象,这样能保证一个对象一个锁。
private Object lock=new Object();
synchronized(lock);

线程如何关闭?
一种是调用它里面的stop()方法
另一种就是你自己设置一个停止线程的标记 (推荐这种)

讲一下java中的同步的方法(另一种问法:数据一致性如何保证?)
1.即有synchronized关键字修饰的方法。
2.同步代码块(如:双重判断的单例模式)
3.使用特殊域变量(volatile)实现线程同步
4.使用重入锁实现线程同步
5.使用局部变量实现线程同步
主要前三个。

volatile的作用,原理,性能。
作用:1、保持内存可见性 2、防止指令重排
volatile用在JavaScript中最明显。

谈谈对多线程的理解
线程是由一个主线程和很多个子线程组成的,主线程消失,子线程也会消失,但是子线程消失其中一个主线程不会消失

Nginx 是什么?有什么作用?
Nginx 同 Apache 一样都是一种 Web 服务器。
两个应用方向:
Nginx 可以作为一个 HTTP 服务器进行网站的发布处理,另外 Nginx 可以作为反向代理进行负载均衡的实现。
代理举例:买鞋,到店里买,店就是代理,但是厂才是真正的鞋提供者。
正向代理:服务器只清楚请求来自哪个代理服务器,而不清楚来自哪个具体的客户端;正向代理模式屏蔽或者隐藏了真实客户端信息。
反向代理:我知道哪个客户端的请求了,但是我不知道我会把这个请求发送给哪个服务器处理。
负载均衡:将服务器接收到的请求按照规则分发的过程。
Nginx 支持的负载均衡调度算法方式如下:weight 轮询(默认)、ip_hash、fair

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值