-
==对于基本类型来说是值比较,对于引用数据类型来说是地址的比较;而equals默认情况下是引用比较,只是很多类重新编写了equals方法, 比如String、Integer等把它变成了值比较,所以一般情况下比较的是值是否相等。
-
取整方法
-
Math.floor(floor:地板)
向下求最接近它的整数,它的值肯定会小于或等于这个浮点数
Math.floor(-1.6) // -2.0 Maht.floor(0.1) // 0 Math.floor(1.6) // 1
-
Math.ceil(天花板)
向上取接近的整数,它返回的肯定会大于或等于函数参数
Math.ceil(-1.6) // -1.0 Math.ceil(1.6) // 2.0
-
Math.rint
该方法返回最接近参数的整数,如果有两个数同样接近,则会返回偶数的那个
Math.rint(-1.1) //-1.0 Math.rint(-1.5) //-2.0 Math.rint(0.5) //0.0 Math.rint(1.6) //2.0 Math.rint(1.2) //1.0
-
Math.round
round方法,四舍五入,但是参数是负数的时候,就不是四舍五入了
源码:
Math.round(x) = Math.floor(x + 0.5)
Math.round(-1.1) // -1 Math.round(-1.6) // -2 Math.round(2.4) // 2 Math.round(2.5) // 3
-
-
接口和抽象类的区别
- 相同点
- 都不能被实例化
- 接口的实现类或抽象类的子类都只有实现了接口或者抽象类中的方法后才能实例化
- 不同点
- 接口只有定义,不能有方法的实现,java1.8中可以定义default方法体,而抽象类可以有定义与实现,方法可在抽象类中实现。
- 实现接口的关键词为implement,继承抽象类的关键字为extends。一个类可以实现多个接口,但是一个类只能继承一个抽象类。所以,使用接口可以间接地实现多重继承
- 接口强调特定功能的实现,而抽象类强调所属关系
- 接口成员变量默认为public static final,必须赋初值,不能被修改;其所有的成员方法都是public、abstract的。抽象类中成员变量默认default,可在子类中被重新定义,也可被重新赋值;抽象方法被abstract修饰,不能被private、static、synchronized和navite等修饰,必须以分号结尾,不带花括号。
- 抽象类可以有构造方法,接口不能有
- 相同点
-
迭代器
List<String> list = new ArrayList<String>(); list. add("王磊"); list. add("的博客"); Iterator<String> iterator = list.iterator(); while (iterator.hasNext()) { String obj = iterator.next(); System.out.println(obj); }
Iterator的特点是更加安全,因为它可以确保,在当前遍历的集合元素被更改的时候,就会抛出ConcurrentModificationException异常(modification:修改)
-
并发和并行的区别
- 并发:多个任务在同一个CPU核上,按细分的时间片轮流(交替)执行,从逻辑上来看那些任务是同时执行
- 并行:多个处理器或多核处理器同时处理多个任务
并发=两个队列和一台咖啡机
并行=两个队列和两台咖啡机
-
线程和进程的区别
一个程序下至少有一个进程,一个进程下至少有一个线程,一个进程也可以有多个线程来增加程序的执行效率
-
创建线程有几种方法
- 继承Thread并重写run方法
- 实现Runnable接口,没有返回值
- 实现Callable接口,可以拿到返回值,可以看作是Runable的补充
-
线程状态
-
新建状态(New):线程被创建后,就进入新建状态
-
就绪状态(Runnable):也被称为可执行状态。线程对象被创建后,其他线程调用了该对象的start()方法,从而来启动该线程。例如,thread.start()。处于就绪状态的线程,随时可能被CPU调度执行
-
运行状态(Running):线程获取CPU权限进行执行。需要注意的是,线程只能从就绪状态进入到运行状态。
-
阻塞状态(Blocked):阻塞状态是线程因为某种原因放弃CPU使用权,暂停运行。知道线程进入就绪状态,才有机会转到运行状态。阻塞状态分为三种:
- 等待阻塞:通过调用线程的wait()方法,让线程等待某工作的完成
- 同步阻塞:线程在获取synchronized同步锁失败(因为锁被其他线程占用),它就会进入同步阻塞状态。
- 其他阻塞:通过调用线程的sleep()或join()或发出了I/O请求时,线程会进入到阻塞状态。当sleep()状态超时、join()等待线程终止或超时、或者I/O处理完毕时,线程重新转入就绪状态
-
死亡状态(Dead):线程执行完了或者因异常退出了run()方法,该线程结束生命周期
-
-
sleap和wait的区别
- 类的不同:sleep()来自Thread,wait()来自Object
- 释放锁:sleep()不释放锁,wait()会释放锁
- 用法不同:sleep()时间到会自动恢复;wait()可以使用notify()/notifyAll()直接唤醒
-
线程的run()方法和start()的区别
start()方法用于启动线程,run()方法用于执行线程的运行时代码。run()方法可以重复调用,而start()只能调用一次
-
线程池
池化思想:线程池、字符串常量池、数据库连接池
用于提高资源的利用率
new ThreadPoolExecutor(核心线程数, 最大线程数, 存活时间, 存活时间单位, 等待队列, 线程工厂, 拒绝策略);
ExecutorService executorService = new ThreadPoolExecutor(3, 5, 1, TimeUnit.SECONDS, new ArrayBlockingQueue<>(3), Executors.defaultThreadFactory(), new ThreadPoolExecutor.AbortPolicy()); for (int i = 0; i < 8; i++) { executorService.execute(() -> { System.out.println(Thread.currentThread().getName() + "--->办理业务"); }); } executorService.shutdown();
-
线程池状态
- running:这是最正常的状态,接受新的任务,处理等待队列中的任务。
- shutdown:不接受新的任务提交,但是会继续处理等待队列中的任务。
- stop:不接受新的任务提交,不再处理等待队列中的任务,中断正在执行任务的线程。
- tidying:所有的任务都销毁了,workCount 为 0,线程池的状态在转换为 TIDYING 状态时,会执行钩子方法 terminated()。
- terminated:terminated()方法结束后,线程池的状态就会变成这个。
-
Java序列化同一个对象,并不会将此对象序列化多次得到多个对象,只会记录已序列化对象的编号。如果序列化一个可变对象(对象内的内容可更改)后,更改了对象内容,再次序列化,并不会再次将此对象装换为字节序列,而只是保存序列化编号。
-
动态代理:在运行时动态的生成代理类什么是动态代理,实现动态代理的方式:JDK动态代理和cglib动态代理
-
JSP和servlet的区别:JSP是servlet的扩展,本质上就是servlet的简易方式。servlet的应用逻辑是在Java文件中,并且完全是从表示层中的html里分离开的,而JSP是java和Html组合而成的一个扩展名为JSP的文件。JSP用于视图,而servlet主要用于控制逻辑
-
JSP的内置对象
- request:封装客户端的请求,其中包含来自get或post请求的参数
- response:封装服务端对客户端的响应
- pageContext:通过该对象可以获取其他对象
- session:封装用户会话的对象
- application:封装服务器运行环境的对象
- out:输出服务器响应的输出流对象
- config:Web应用的配置对象
- page:JSP页面本身(相当于Java程序中的this)
- exception:封装页面抛出异常的对象
-
JSP的4种作用域
- page:代表与一个页面相关的对象和属性。
- request:代表与客户端发出的一个请求相关的对象和属性。一个请求可能跨越多个页面,涉及多个 Web 组件;需要在页面显示的临时数据可以置于此作用域。
- session:代表与某个用户与服务器建立的一次会话相关的对象和属性。跟某个用户相关的数据应该放在用户自己的 session 中。
- application:代表与整个 Web 应用程序相关的对象和属性,它实质上是跨越整个 Web 应用程序,包括多个页面、请求和会话的一个全局作用域。
-
cookie和session的区别
- cookie 和session的区别是:cookie数据保存在客户端,session数据保存在服务器端。
- 两个都可以用来存私密的东西,同样也都有有效期的说法,区别在于session是放在服务器上的,过期与否取决于服务期的设定,cookie是存在客户端的,过去与否可以在cookie生成的时候设置进去。
- cookie数据存放在客户的浏览器上,session数据放在服务器上 ;
- cookie不是很安全,别人可以分析存放在本地的COOKIE并进行COOKIE欺骗,如果主要考虑到安全应当使用session ;
- session会在一定时间内保存在服务器上。当访问增多,会比较占用你服务器的性能,如果主要考虑到减轻服务器性能方面,应当使用COOKIE ;
- 单个cookie在客户端的限制是3K,就是说一个站点在客户端存放的COOKIE不能3K;
- 所以将登陆信息等重要信息存放为SESSION;其他信息如果需要保留,可以放在COOKIE中。
- cookie和session的共同之处在于:cookie和session都是用来跟踪浏览器用户身份的会话方式。
- cookie 是一种发送到客户浏览器的文本串句柄,并保存在客户机硬盘上,可以用来在某个WEB站点会话间持久的保持数据。
- session其实指的就是访问者从到达某个特定主页到离开为止的那段时间。 Session其实是利用Cookie进行信息处理的,当用户首先进行了请求后,服务端就在用户浏览器上创建了一个Cookie,当这个Session结束时,其实就是意味着这个Cookie就过期了。
-
session的工作原理
- 用户第一次请求服务器时,会在服务端产生一个sessionId
- 把sessionId返回给客户端,保存在cookie中
- 下次访问服务端的时候会带上这个sessionId,判断服务端是否有与之相对应的sessionId,这样就可以工作了。
-
如何避免SQL注入
- 使用预处理PreparedStatement
- 使用正则表达式过滤掉特殊字符
-
throw和throws的区别
- throw:是真实抛出一个异常
- throws:是声明可能会抛出一个异常
-
异常
-
try-catch-finally那个部分可以省略?
try-catch-finally 其中 catch 和 finally 都可以被省略,但是不能同时省略,也就是说有 try 的时候,必须后面跟一个 catch 或者 finally。
-
try-catch-finally 中,如果 catch 中 return 了,finally 还会执行吗?
finally 一定会执行,即使是 catch 中 return 了,catch 中的 return 会等 finally 中的代码执行完之后,才会执行。
-
forward 和 redirect 的区别?
forward 是转发 和 redirect 是重定向:
- 地址栏 url 显示:foward url 不会发生改变,redirect url 会发生改变;
- 数据共享:forward 可以共享 request 里的数据,redirect 不能共享;
- 效率:forward 比 redirect 效率高。
-
设计模式
- 单例模式:保证被创建一次,节省系统开销。
- 工厂模式(简单工厂、抽象工厂):解耦代码。
- 观察者模式:定义了对象之间的一对多的依赖,这样一来,当一个对象改变时,它的所有的依赖者都会收到通知并自动更新。
- 一个对象必须通知其他对象,而并不知道这些对象是谁。
- 需要在系统中创建一个触发链,A对象的行为将影响B对象,B对象的行为将影响C对象……,可以使用观察者模式创建一种链式触发机制。
- 外观模式:提供一个统一的接口,用来访问子系统中的一群接口,外观定义了一个高层的接口,让子系统更容易使用。
- 模版方法模式:定义了一个算法的骨架,而将一些步骤延迟到子类中,模版方法使得子类可以在不改变算法结构的情况下,重新定义算法的步骤。
- 状态模式:允许对象在内部状态改变时改变它的行为,对象看起来好像修改了它的类。
-
索引:是用于快速查找数据的一种数据结构
-
什么是自动专配
什么是自动配置?举例来讲,当你通过@Autowired或@Resource注解,自动注入一个类实例之前,被注入进来的这个类实例需要被spring容器纳管,不然肯定会注入失败。往往我们会在xml通过
bean id="dfdf"
或者在类定义上使用@Component、@Configuration等注解,来实现其被spring容器管理。而对于jar包中的类,则稍微复杂一点,要根据jar包中类的实现进行相应引入。
而spring boot的自动配置功能,会对我们配置的一些类,自动注入到spring容器中。特别是对于依赖的jar包中的一些类,在我们的工程用到这些类实例时,直接@Autowired或@Resource注解注入使用就可以了。
1
最新推荐文章于 2022-11-12 20:18:44 发布