Java基础方面
int a = 1;
int m1 = ++a +3;
结果 :m1 = 5;a=2;
++a表示先赋值
int a = 1;
int m = a+++3;
结果 m = 4; a= 2;
a++表示后赋值
int a = 2;
int result = (a++ > 2)?(++a):(a+=3);
结果是//6
中软 面试题
1、 一个类是否继承多个接口?
2、 一个类是否可以继承多个超类?
3、 接口是否可以继承接口?
4、 抽象类是否可以实现接口?
一个接口可以继承多个接口. interface C extends A, B {}是可以的. 一个类可以实现多个接口: class D implements A,B,C{} 但是一个类只能继承一个类,不能继承多个类 class B extends A{} 在继承类的同时,也可以继承接口: class E extends D implements A,B,C{}
基类、超类、父类都是一个意思,不同说法而已。
比如: class A extends B{} 这就可以说B是A的基类,B是A的超类,B是A的父类;反过来,A就是B的子类。
抽象类是可以实现接口的,抽象类可以继承实体类,但是有个条件,条件是,实体类必须要有明确的构造函数
5、 抽象类和接口区别?
public abstract class People {
public int age;
public void Num() {
}
public abstract String Name();
}
· 抽象类:
· 抽象方法:它只有声明,而没有具体的实现。抽象方法的声明格式为:abstract void fun();
· 如果一个类含有抽象方法,则称这个类为抽象类,抽象类必须在类前用abstract关键字修饰。
· 特点:
· 抽象方法必须为public或者protected(因为如果为private,则不能被子类继承,子类便无法实现该方法),缺省情况下默认为public。
· 抽象类不能用来创建对象
· 如果一个类继承于一个抽象类,则子类必须实现父类的抽象方法。如果子类没有实现父类的抽象方法,则必须将子类也定义为为abstract类
· 接口:
· 接口中可以含有 变量和方法。但是要注意,接口中的变量会被隐式地指定为public static final变量(并且只能是public static final变量,用private修饰会报编译错误),而方法会被隐式地指定为public abstract方法且只能是public abstract方法(用其他关键字,比如private、protected、static、 final等修饰会报编译错误)
· 接口中所有的方法不能有具体的实现,也就是说,接口中的方法必须都是抽象方法
· 区别:
· 语法:
· 抽象类可以提供成员方法的实现细节,而接口中只能存在public abstract 方法;
· 抽象类中的成员变量可以是各种类型的,而接口中的成员变量只能是public static final类型的;
· 接口中不能含有静态代码块以及静态方法,而抽象类可以有静态代码块和静态方法;
· 一个类只能继承一个抽象类,而一个类却可以实现多个接口。
· 设计:
· 抽象类是对一种事物的抽象,即对类抽象,而接口是对行为的抽象。抽象类是对整个类整体进行抽象,包括属性、行为,但是接口却是对类局部(行为)进行抽象。举个简单的例子,飞机和鸟是不同类的事物,但是它们都有一个共性,就是都会飞。那么在设计的时候,可以将飞机设计为一个类Airplane,将鸟设计为一个类Bird,但是不能将 飞行 这个特性也设计为类,因此它只是一个行为特性,并不是对一类事物的抽象描述。此时可以将 飞行 设计为一个接口Fly,包含方法fly( ),然后Airplane和Bird分别根据自己的需要实现Fly这个接口。然后至于有不同种类的飞机,比如战斗机、民用飞机等直接继承Airplane即可,对于鸟也是类似的,不同种类的鸟直接继承Bird类即可。从这里可以看出,继承是一个 "是不是"的关系,而 接口 实现则是 "有没有"的关系。如果一个类继承了某个抽象类,则子类必定是抽象类的种类,而接口实现则是有没有、具备不具备的关系,比如鸟是否能飞(或者是否具备飞行这个特点),能飞行则可以实现这个接口,不能飞行就不实现这个接口。
6、private、protected、public和default的访问限制
| 类内部 | 本包 | 子类 | 外部包 |
public | √ | √ | √ | √ |
protected | √ | √ | √ | × |
default | √ | √ | × | × |
private | √ | × | × | × |
l 如何将日期类型转换为xxxx年xx月xx日格式字符串?
l 如何将Iso-8859-1编码字符串转换为gb2312编码字符串?
l 如何将字符串bbbwlirbbb转换为bbbhhtccc?
SimpleDateFormat sdf = new SimpleDateFormat("yyyy年MM月dd日");
System.out.println(sdf.format(new Date()));
new String(str.getBytes("ISO8859-1"),"GB2312")
a. replace("wlirbbb", "hhtccc");
l ArrayLIst list = new ArrayList(20);扩充几次
A 0 B 1 C 2 D 3
本题需要注意的是:调用的是带参的构造方法。
另外也要注意:
1、如果不指定容量,而初始大小为10,动态增长时,增长到当前容量的1.5倍。
2、 与之类似的还有,HashMap的初始大小为16,增长时,直接容量翻番,如源代码。
7、java中集合图
8、java Inner Class和Static Nested Class的区别
Eclipse中OutClassTest类
9、Equals和==区别
Eclipse中 equals类
10、short s1=1;s1=s1+1; short s1=1;s1+=1;以上代码有什么问题
short s=1; s=s+1; 自然是编译不通过的 提示损失精度 那么 short s=1; s+=1; 为什么能编译通过那? 还有一个问题 隐式类型转换可以从小到大自动转,即byte->short->int->long如果反过来会丢失精度,必须进行显示类型转换 而s+=1的意思与s = s+1不同,s=s+1这句先执行s+1然后把结果赋给s,由于1为int类型,所以s+1的返回值是int,编译器自动进行了隐式类型转换 所以将一个int类型赋给short就会出错,而s+=1不同由于是+=操作符,在解析时候s+=1就等价于s = (short)(s+1),翻番来讲就是 s+=1 <=> s = (s的类型)(s+1)
11、math.round(15.2)等于多少math.round(-15.2)等于多少
看eclipse api
12、在不申请额外变量情况下,交换两个变量值x=3 y=5
1>算术运算x=y-x //x=2 y=5
Y=y-x //x=2 y=3
X=y+x //x=5 y=3
2> 指针地址操作 麻烦
3>位运算麻烦
13、jsp有哪些动作 作用分别是什么
JSP共有以下6种基本动作
1. jsp:include:在页面被请求的时候引入一个文件。
2.jsp:useBean:寻找或者实例化一个JavaBean。
3.jsp:setProperty:设置JavaBean的属性。
4. jsp:getProperty:输出某个JavaBean的属性。
5. jsp:forward:把请求转到一个新的页面。
6.jsp:plugin:根据浏览器类型为Java插件生成OBJECT或EMBED标记。
14、jsp动态include和静态include区别
<%@ include file=” ”%>
<jsp:include page=” ” flush=”true”/>
1)静态导入是将被导入页面的代码完全融入,两个页面融合成一个整体的servlet;而动态导入则在servlet中使用include方法来引入被导入页面的内容。
2)静态导入时被导入的页面的编译指令会起作用,而动态导入时被导入的页面的编译指令则失去作用,只是插入被导入页面的body内容。
3)动态包含可以包含相同变量,而静态包含不行。
4)如果被包含文件经常变动,则应该使用动态包含,而使用静态包含时,改变被包含文件后,有可能不能及时更新
15、什么是对象序列化? 如何实现? 为什么要用
对象序列化可以将一个对象保存到一个文件,可以将通过流的方式在网络上传输,可以将文件的内容读取转化为一个对象。所谓对象流也就是将对象的内容流化,可以对流化后的对象进行读写操作,也可将流化后的对象传输于网络之间。序列化是为了解决在对象流进行读写操作时引发的问题。
序列化的实现:将需要被序列化的类实现serializable接口,该接口没有需要实现的方法,implements Serializable只是为了标注该对象是可被序列化的,然后使用一个输出流(如FileOutputStream)来构造一个ObjectOutputStream(对象流)对象,接着使用ObjectOutputStream对象的writeObject(Object obj)方法就可以将参数obj的对象写出,要恢复的话则用输入流。
将类序列化成流之后可以通过互联网传输给别人,你也可以反序列化将别人的序列化流转换成内存中的对象,就这么简单
16、spring框架中如何解决web页面乱码问题
采用Spring框架自带的过滤器CharacterEncodin
<filter>
<filter-name>encodingFilter</filter-name>
<filter-class>
org.springframework.web.filter.CharacterEncodingFilter
</filter-class>
<init-param>
<param-name>encoding</param-name>
<param-value>UTF-8</param-value>
</init-param>
<init-param>
<param-name>forceEncoding</param-name>
<param-value>true</param-value>
</init-param>
</filter>
<filter-mapping>
<filter-name>encodingFilter</filter-name>
<url-pattern>*</url-pattern>
</filter-mapping>
16、 Java多线程有哪几种实现方式? Java中的类如何保证线程安全? 请说明ThreadLocal的用法和适用场景
java的同步机制,大概是通过:
1.synchronized;
2.Object方法中的wait,notify;
3.ThreadLocal机制
来实现的, 其中synchronized有两种用法:
1.对类的方法进行修饰
2.synchronized(对象)的方法进行修饰
在同步机制中,通过对象的锁机制保证同一时间只有一个线程访问变量。这时该变量是多个线程共享的,使用同步机制要求程序慎密地分析什么时候对变量进行读写,什么时候需要锁定某个对象,什么时候释放对象锁等繁杂的问题,程序设计和编写难度相对较大。
而ThreadLocal则从另一个角度来解决多线程的并发访问。ThreadLocal会为每一个线程提供一个独立的变量副本,从而隔离了多个线程对数据的访问冲突。因为每一个线程都拥有自己的变量副本,从而也就没有必要对该变量进行同步了。ThreadLocal提供了线程安全的共享对象,在编写多线程代码时,可以把不安全的变量封装进ThreadLocal。
当然ThreadLocal并不能替代同步机制,两者面向的问题领域不同。同步机制是为了同步多个线程对相同资源的并发访问,是为了多个线程之间进行通信 的有效方式;而ThreadLocal是隔离多个线程的数据共享,从根本上就不在多个线程之间共享资源(变量),这样当然不需要对多个线程进行同步了。所 以,如果你需要进行多个线程之间进行通信,则使用同步机制;如果需要隔离多个线程之间的共享冲突,可以使用ThreadLocal,这将极大地简化你的程 序,使程序更加易读、简洁。
Java code
1 2 3 4 5 6 7 8 9 10 | private static ThreadLocal<Connection> connectionHolder = new ThreadLocal<Connection>() { public Connection initialValue() { return DriverManager.getConnection(DB_URL); } };
public static Connection getConnection() { return connectionHolder.get(); } |
这个就是为每个线程都会开一个连接,而感觉如下也是一个线程开一个连接:
Java code
1 2 3 | public static Connection getConnection() { return DriverManager.getConnection(DB_URL); } |
ThreadLocal 是多线程中的免锁解决方案之一。 就是每个线程对于ThreadLocal 都有一个备份 线程池 SimpleDateFormat
前端js
动态给table添加行 删除行
桌面js文件夹
after append appendTo三个函数的区别
after() 方法在被选元素后插入指定的内容。
append() 方法在被选元素的结尾(仍然在内部)插入指定内容
appendTo() 方法在被选元素的结尾(仍然在内部)插入指定内容
js中创建对象和函数几种方式
函数:1》function 函数名( 参数列表 ) { 函数体 }
2》var 函数名 = new Function(“参数列表”,”函数体”);
var sum = new Function("num1,num2","return num1+num2");
// 函数调用
var result1 = sum(120,130,66);
alert(result1);
3》var 函数名 = function(参数列表) { 函数体 }
var funname = function(a,b){
alert(a); // abc
alert(b); // true
}
// 函数调用
funname("abc",true);
对象:1》工程模式
2》构造函数模式
3》原型
闭包理解
1、 作用:1读取函数内部的变量 2变量的值始终保持在内存中
数据库方面
左链接 右链接 内链接区别
SELECT
u.id,
u.`username`,
u.`address`,
o.`id` oid,
o.`user_id`,
o.`createtime`,
o.`note`,
o.`number`
FROM `USER` u
LEFT JOIN `orders` o ON o.`user_id` = u.`id`
SELECT *,COUNT(*) FROM sc GROUP BY sid ;
SELECT sc.`SID`,s.`SN`,AVG(sc.`G`),COUNT(*) FROM sc JOIN s ON sc.`SID`=s.`SID`
GROUP BY sid HAVING COUNT(*) >=3 ORDER BY AVG(sc.`G`) DESC;
SELECT NAME , AVG(price) FROM pro GROUP BY NAME HAVING AVG(price)<2;
SELECT DISTINCT username FROM test_user WHERE turename IN (SELECT turename FROM test_user GROUP BY turename HAVING COUNT(*) >1);
SELECT * FROM test_user WHERE deptid LIKE '%A%' ORDER BY age LIMIT 0,2;
设计类
客户表customercId name address ctype_id
客户类型表customertypectype_Id ctype_name 折扣
产品表productp_idp_namec_role(核算规则)
订单表ordero_ido_no订单编号 o_num订单数量 o_price订单金额 p_ide_id(员工表外间)
角色表roler_idr_name
员工表empotye_ide_name(员工姓名) le_id(上级领导id)r_id(一个员工只有一个角色,多角色不考虑)
Jvm方面
gc原理
框架方面
Struts核心和工作原理
一、struts2的核心组件
1.全局配置文件struts.properties
2.映射文件struts.xml
3.过滤器FilterDispatcher
4.业务控制器Action
5.值栈ValueStac
一个请求在Struts2框架中的处理大概分为以下几个步骤
1、客户端初始化一个指向Servlet容器(例如Tomcat)的请求
2、这个请求经过一系列的过滤器(Filter)(这些过滤器中有一个叫做ActionContextCleanUp的可选过滤器,这个过滤器对于Struts2和其他框架的集成很有帮助,例如:SiteMesh Plugin)
3、接着FilterDispatcher被调用,FilterDispatcher询问ActionMapper来决定这个请是否需要调用某个Action
FilterDispatcher是控制器的核心,就是mvc中c控制层的核心。下面粗略的分析下我理解的FilterDispatcher工作流程和原理:FilterDispatcher进行初始化并启用核心doFilter
4、如果ActionMapper决定需要调用某个Action,FilterDispatcher把请求的处理交给ActionProxy
5、ActionProxy通过ConfigurationManager询问框架的配置文件,找到需要调用的Action类 ,这里,我们一般是从struts.xml配置中读取。
6、ActionProxy创建一个ActionInvocation的实例。
7、ActionInvocation实例使用命名模式来调用,在调用Action的过程前后,涉及到相关拦截器(Intercepter)的调用。
8、一旦Action执行完毕,ActionInvocation负责根据struts.xml中的配置找到对应的返回结果。返回结果通常是(但不总是,也可能是另外的一个Action链)一个需要被表示的JSP或者FreeMarker的模版。在表示的过程中可以使用Struts2 框架中继承的标签。在这个过程中需要涉及到ActionMapper
Spring ioc aop
反射 http://blog.csdn.net/liujiahan629629/article/details/18013523
动态代理 http://layznet.iteye.com/blog/1182924
Springmvc流程
Struts2接受参数的几种方式
http://caizhilin2010.iteye.com/blog/1407234
Springmvc获取参数的几种方式
http://www.cnblogs.com/xiaoxi/p/5695783.html
向页面传值
http://blog.csdn.net/z69183787/article/details/41653875
设计模式
1、 手写单例模式
2、 1.多线程安全单例模式实例一(不使用同步锁)
3、
4、 1 public class Singleton {
5、 2 private static Singleton sin=new Singleton(); ///直接初始化一个实例对象
6、 3 private Singleton(){ ///private类型的构造函数,保证其他类对象不能直接new一个该对象的实例
7、 4 }
8、 5 public static Singleton getSin(){ ///该类唯一的一个public方法
9、 6 return sin;
10、 7 }
11、 8 }
12、
13、 上述代码中的一个缺点是该类加载的时候就会直接new 一个静态对象出来,当系统中这样的类较多时,会使得启动速度变慢 。现在流行的设计都是讲“延迟加载”,我们可以在第一次使用的时候才初始化第一个该类对象。所以这种适合在小系统。
14、 2.多线程安全单例模式实例二(使用同步方法)
15、
16、 1 public class Singleton {
17、 2 private static Singleton instance;
18、 3 private Singleton (){
19、 4
20、 5 }
21、 6 public static synchronized Singleton getInstance(){ //对获取实例的方法进行同步
22、 7 if (instance == null)
23、 8 instance = new Singleton();
24、 9 return instance;
25、 10 }
26、 11 }
27、
28、 上述代码中的一次锁住了一个方法, 这个粒度有点大 ,改进就是只锁住其中的new语句就OK。就是所谓的“双重锁”机制。
29、 3.多线程安全单例模式实例三(使用双重同步锁)
30、
31、 1 public class Singleton {
32、 2 private static Singleton instance;
33、 3 private Singleton (){
34、 4 }
35、 5 public static Singleton getInstance(){ //对获取实例的方法进行同步
36、 6 if (instance == null){
37、 7 synchronized(Singleton.class){
38、 8 if (instance == null)
39、 9 instance = new Singleton();
40、 10 }
41、 11 }
42、 12 return instance;
43、 13 }
44、 14
45、 15 }
46、
工厂模式: (简单工厂,工厂方法,抽象工厂)
编程题
算法题
一、冒泡(Bubble)排序
冒泡排序(BubbleSort)的基本思想是:依次比较相邻的两个数,将小数放在前面,大数放在后面。如此重复下去,直至最终完成排序。
时间复杂度为O(n*n),适用于排序小列表。
void BubbleSortArray()
{
int i,j,temp;
for(i=1;i<n;i++)
{
for(j=0;i<n-i;j++)
{
if(a[j]>a[j+1]) //比较交换相邻元素
{
temp=a[j]; a[j]=a[j+1]; a[j+1]=temp;
}
}
}
}
二、选择排序
选择排序的基本思想是:每一趟从待排序的数据元素中选出最小的一个元素,顺序放在已排好序的数列的最后,直到全部待排序的数据元素排完。
时间复杂度为O(n*n),适用于排序小列表。
void SelectSortArray()
{
int i,j,min_index;
for(i=0;i<n-1;i++)
{
min_index=i;
for(j=i+1;j<n;j++) //每次扫描选择最小项
if(arr[j]<arr[min_index]) min_index=j;
if(min_index!=i) //找到最小项交换,将这一项移到列表中的正确位置
{
int temp;
temp=arr[i]; arr[i]=arr[min_index]; arr[min_index]=temp;
}
}
}
常用查找算法
顺序查找
从第一个元素开始顺序比较查找。
二分查找
二分查找前提条件: 已排序的数组中查找
二分查找的基本思想是: 首先确定该查找区间的中间点位置: int mid = (low+upper) / 2;
然后将待查找的值与中间点位置的值比较:
若相等,则查找成功并返回此位置。
若中间点位置值大于待查值,则新的查找区间是中间点位置的左边区域。
若中间点位置值小于待查值,则新的查找区间是中间点位置的右边区域。
下一次查找是针对新的查找区间进行的。
public class Search{
public static void main(String [] args){
int[] array={13,4,56,7,88,7,78,66,34,56};
System.out.println("待查找的数组序列为:");
for(int arr:array){
System.out.print(arr+" ");
}
//顺序查找
System.out.println("\n"+"顺序查找66的下标为:"+"\n"+sequentialSearch(array,66));
//排序数组
System.out.println("排序后的数组序列为:");
Sort(array);
//二分法查找
System.out.println("\n"+"二分法查找88的下标为:"+"\n"+binarySearch(array,88));
}
//顺序查找
public static int sequentialSearch(int[] a,int num){
int n=a.length;
for(int i=0;i<n;i++){
if(a[i]==num){
return i;
}
}
return -1;
}
//二分查找
public static int binarySearch(int [] a,int num){
//起点
int low=0;
//终点
int upper=a.length-1;
//避免出现下标越界异常
while(low<=upper){
//中间点
int mid=(low+upper)/2;
//中间点的值小于要查找的值,更改查找的起点为中间点位置后一位
if(a[mid]<num){
low=mid+1;
}
//中间点的值大于要查找的值,更改查找的终点为中间点位置前一位
else if(a[mid]>num){
upper=mid-1;
}
else{
return mid;
}
}
return -1;
}
//排序数组
public static void Sort(int[] a){
int n=a.length;
//i是比较的次数,共比较n-1次
for(int i=1;i<n;i++){
//j是进行比较的第一个元素的下标
for(int j=0;j<n-1;j++){
if(a[j]>a[j+1]){
int temp=a[j+1];
a[j+1]=a[j];
a[j]=temp;
}
}
}
//遍历已排序数组
for(int k=0;k<n;k++){
System.out.print(a[k]+" ");
}
}
}