视频地址:
代码:问输出的 i、j、k 的值
int i = 1;i = i++;int j = i++;int k = i + ++i * i++;System.out.println("i = " + i);System.out.println("j = " + j);System.out.println("k = " + k);
运行结果:
关于int k = i + ++i * i++;
我认为是:int k =(i++) + i * i++;
,例如,不妨把中间的i换成j,再看一下字节码文件:
是给第一个变量i++了,而不是++j
singleton 单例:一个系统中只有一个实例对象可以被获取和使用,例如,jvm运行环境的Runtime类:
饿,急于创建,在类初始化就创建了
public class SingletonHungry {public static void main(String[] args) {System.out.println(SH01.INSTANCE);System.out.println(SH02.INSTANCE);System.out.println(SH03.INSTANCE);}
}/*** 方式1:直接实例化*/
class SH01{/*** 使用final强调这是一个单例*/public static final SH01 INSTANCE = new SH01();private SH01(){ }
}/*** 方式2:使用枚举类*/
enum SH02{/*** 只有一个可用的变量,达到单例的效果*/INSTANCE;
}/*** 方式3:静态代码块*/
class SH03{public static final SH03 INSTANCE;String name;static {// 例如,要从配置文件获取值String config = null;try {Properties properties = new Properties();properties.load(ClassLoader().getResourceAsStream("application.properties"));config = Property("spring.application.name");} catch (IOException e) {e.printStackTrace();}//创建对象INSTANCE = new SH03(config);}private SH03(String name){this.name = name;}
}
public class SingletonLazy {public static void main(String[] args) {//方式1在多线程的情况下是不安全的:Runnable runnable = () -> System.out.Instance());new Thread(runnable).start();new Thread(runnable).start();//方式2在多线程的情况下是安全的:runnable = () -> System.out.Instance());new Thread(runnable).start();new Thread(runnable).start();//方式3System.out.Instance());System.out.Instance());}
}/*** 方式1:线程不安全版*/
class SL01{/*** 静态变量私有化,防止直接用类名获取到null*/private static SL01 instance;private SL01(){}public static SL01 getInstance(){if (instance == null){try {Thread.sleep(100);} catch (InterruptedException e) {e.printStackTrace();}instance = new SL01();}return instance;}
}/*** 方式2:线程安全版* * 为什么用volatile ?* instance = new Singleton(); 这段代码其实是分为三步执行* 1. 为 instance 分配内存空间* 2. 初始化 instance* 3. 将 instance 指向分配的内存地址* 但是由于 JVM 具有指令重排的特性,会使执行顺序有可能变成 1 3 2,指令重排在单线程环境下不会出现问题,但是在多线程环境下会导致一个线程获得一个还没有初始化的实例。比如线程 T1 执行了 1、3,此时线程 T2 获取 instance 发现不为空,但是 instance 还未被初始化。* 使用 volatile 可以禁止 JVM 指令重排,保证在多线程环境下也能正常运行。*/
class SL02{/*** 静态变量私有化,防止直接用类名获取到null*/private volatile static SL02 instance;private SL02(){}public static SL02 getInstance(){// 判断是否为null,为null才加锁创建,提升性能if (instance == null){synchronized (SL02.class){// 即使进来了,可能前一个刚好创建好了if (instance == null){try {Thread.sleep(100);} catch (InterruptedException e) {e.printStackTrace();}instance = new SL02();}}}return instance;}
}/*** 方式3:内部类*/
class SL03{/*** 静态变量私有化,防止直接用类名获取到null*/private static SL03 instance;private SL03(){}private static class Inner{// 静态内部类不会自动随着外部类的加载和初始化而初始化,而是要单独的加载和初始化,而且只会被加载一次private static final SL03 INSTANCE = new SL03();}public static SL03 getInstance() {return Inner.INSTANCE;}
}
部分结果:结果显示,第一种方式在多线程情况下是不安全的,获取到两个实例:
题目:输出结果是?
class Father {private int i = method();private static int j = staticMethod();static {System.out.print(1 + " ");}Father() {System.out.print(2 + " ");}{System.out.print(3 + " ");}public int method() {System.out.print(4 + " ");return 1;}public static int staticMethod() {System.out.print(5 + " ");return 1;}
}public class Son extends Father {private int i = method();private static int j = staticMethod();static {System.out.print(6 + " ");}Son() {System.out.print(7 + " ");}{System.out.print(8 + " ");}@Overridepublic int method() {System.out.print(9 + " ");return 1;}public static int staticMethod() {System.out.print(10 + " ");return 1;}public static void main(String[] args) {new Son();System.out.println();new Son();}
}
运行结果:
5 1 10 6 9 3 2 9 8 7
9 3 2 9 8 7
分析:
先进行类初始化,也即执行<clinit>()方法,(只会被初始化一次)
父类
先对父类进行类初始化静态代码块、静态变量
初始化(谁在前,谁先进行)再进行实例初始化,也即执行<init>()方法,(每一次创建实例对象都会被执行)
父类
,先对父类进行类初始化;如果父类的方法在当前类被重写,则使用被重写后的方法非静态代码块、非静态变量
的初始化(谁在前,谁先进行)构造器
方法overload是方法重载
override是方法重写,要求以下内容相同:
运行结果?
运行结果:
题目:
想要跳到第n步台阶,只能是从第n-1或者n-2跳上来的,要求跳到第n机有多少种走法,只需知道跳到第n-1步和n-2步有多少种走法,求和即可。即:
public class P05 {public static void main(String[] args) {int n = 20;//秒表统计运行时间StopWatch watch = new StopWatch();watch.start();int res = method1(n);System.out.println("res1 = " + res);watch.stop();watch.start();res = method2(n);System.out.println("res2 = " + res);watch.stop();//查看运行时间StopWatch.TaskInfo[] taskInfo = TaskInfo();for (StopWatch.TaskInfo info : taskInfo) {System.out.TimeNanos());}}/*** 迭代实现* @param n* @return*/private static int method2(int n) {if (n == 1 || n == 2){return n;}// i1表示跳到n-2的走法,i2表示跳到n-1的走法int i1 = 1, i2 = 2;int tmp;for (int i = 3; i <= n; i++) {//新的i2tmp = i1 + i2;//新的i1i1 = i2;i2 = tmp;}return i2;}/*** 递归实现* @param n* @return*/private static int method1(int n) {if (n == 1 || n == 2){return n;}return method1(n - 1) + method1(n -2);}
}
运行结果:可见递归慢很多,但是它代码简单
public class P06 {static int s;int i;int j;{int i = 1;i++;j++;s++;}private void test(int j) {i++;j++;s++;}public static void main(String[] args) {P06 problem1 = new P06();P06 problem2 = new P06();st(100);st(200);st(300);System.out.println("i = " + problem1.i + ", j = " + problem1.j + ", s = " + problem1.s);System.out.println("i = " + problem2.i + ", j = " + problem2.j + ", s = " + problem2.s);}
}
结果:
分析:
代码:
//简单的创建两类A、B
class A{ }
class B{ }//将A、B两个类加入容器,分别设置为单例和多例
@Configuration
class Config{@Bean@Scope(ConfigurableBeanFactory.SCOPE_SINGLETON)public A a(){return new A();}@Bean@Scope(ConfigurableBeanFactory.SCOPE_PROTOTYPE)public B b(){return new B();}
}//多次获取A、B
@SpringBootApplication
public class JavaInterviewQuestionsApplication {public static void main(String[] args) {ConfigurableApplicationContext run = SpringApplication.run(JavaInterviewQuestionsApplication.class, args);System.out.Bean(A.class));System.out.Bean(A.class));System.out.Bean(B.class));System.out.Bean(B.class));}
}
部分结果:观察到A获取两次是一个对象,B获取两次是两个对象
常用的是前两种
REQUIRED
:A和B都定义事务,A调用B,则B的事务不生效REQUIRED_NEW
:A和B都定义事务,A调用B,B的事务生效设置示例: @Transactional(propagation = Propagation.REQUIRED)
例如:可设置事务的隔离级别为可重复读,则在它管辖范围内的代码,多次读取相同数据获得的结果是一致的:@Transactional(isolation = Isolation.REPEATABLE_READ)
protected void doDispatch(HttpServletRequest request, HttpServletResponse response) throws Exception {// 1、找controller// 2、找interceptorHandlerExecutionChain mappedHandler = getHandler(processedRequest);// 找HandlerAdapter(哪个HandlerAdapter能处理当前handle?遍历所有HandlerAdapter的supports方法)HandlerAdapter ha = Handler());// 执行拦截器preHandle方法if (!mappedHandler.applyPreHandle(processedRequest, response)) {return;}// 执行HandlerAdapter的handle方法;解析参数、执行controller、解析返回值、返回ModelAndViewModelAndView mv = ha.handle(processedRequest, response, Handler());// 倒序执行拦截器postHandle方法mappedHandler.applyPostHandle(processedRequest, response, mv);// 1、视图解析器解析出view// 2、渲染// 3、倒序执行拦截器的afterCompletion方法processDispatchResult(processedRequest, response, mappedHandler, mv, dispatchException);}
其中,doDispatch完整源码:
protected void doDispatch(HttpServletRequest request, HttpServletResponse response) throws Exception {HttpServletRequest processedRequest = request;HandlerExecutionChain mappedHandler = null;boolean multipartRequestParsed = false;WebAsyncManager asyncManager = AsyncManager(request);try {ModelAndView mv = null;Exception dispatchException = null;try {processedRequest = checkMultipart(request);multipartRequestParsed = (processedRequest != request);// Determine handler for the current request.mappedHandler = getHandler(processedRequest);if (mappedHandler == null) {noHandlerFound(processedRequest, response);return;}// Determine handler adapter for the current request.HandlerAdapter ha = Handler());// Process last-modified header, if supported by the handler.String method = Method();boolean isGet = "GET".equals(method);if (isGet || "HEAD".equals(method)) {long lastModified = ha.getLastModified(request, Handler());if (new ServletWebRequest(request, response).checkNotModified(lastModified) && isGet) {return;}}if (!mappedHandler.applyPreHandle(processedRequest, response)) {return;}// Actually invoke the handler.mv = ha.handle(processedRequest, response, Handler());if (asyncManager.isConcurrentHandlingStarted()) {return;}applyDefaultViewName(processedRequest, mv);mappedHandler.applyPostHandle(processedRequest, response, mv);}catch (Exception ex) {dispatchException = ex;}catch (Throwable err) {// As of 4.3, we're processing Errors thrown from handler methods as well,// making them available for @ExceptionHandler methods and other scenarios.dispatchException = new NestedServletException("Handler dispatch failed", err);}processDispatchResult(processedRequest, response, mappedHandler, mv, dispatchException);}catch (Exception ex) {triggerAfterCompletion(processedRequest, response, mappedHandler, ex);}catch (Throwable err) {triggerAfterCompletion(processedRequest, response, mappedHandler,new NestedServletException("Handler processing failed", err));}finally {if (asyncManager.isConcurrentHandlingStarted()) {// Instead of postHandle and afterCompletionif (mappedHandler != null) {mappedHandler.applyAfterConcurrentHandlingStarted(processedRequest, response);}}else {// Clean up any resources used by a multipart request.if (multipartRequestParsed) {cleanupMultipart(processedRequest);}}}}
select user_id userId, money from account;
mapUnderscoreToCamelCase = true
<resultMap id="BaseResultMap" type="com.ljy.domain.Account"><id property="id" column="id" jdbcType="INTEGER"/><result property="userId" column="user_id" jdbcType="INTEGER"/><result property="money" column="money" jdbcType="DOUBLE"/>
</resultMap>
执行
chkconfig --list
,运行级别有七种:
解释:
两种持久化方式:RDB (Redis DataBase) 、AOF (Append Only File);
mysql官方对索引的定义为:索引是帮助mysql高效获取数据的数据结构。可也得出索引的本质是数据结构。
优势:
劣势:
适合创建索引的情况:
不适合建索引:
数据类型:
异步
并行
排队
支付宝支付成功后,会有回调通知(如果支付宝未收到success,会继续发送回调通知),支付模块收到支付宝的回调通知,一边通过 消息队列
给订单模块通知支付完成,一边响应success
弊端:
本文发布于:2024-02-03 01:34:15,感谢您对本站的认可!
本文链接:https://www.4u4v.net/it/170689525347783.html
版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系,我们将在24小时内删除。
留言与评论(共有 0 条评论) |