常见面试题

命名规则:

工程名:一般小写
Package名字:小写
类名:每个单词的首字母大写
属性和方法名:小驼峰 首个单词首字母小写,其余单词首字母大写
static final修饰的认为是常量:常量属性全大写

基本数据类型

数值型:
整型(整数 byte short int long)
浮点型(小数float double(默认))
字符型:char(单个字符,2字节)
布尔型:Boolean(true/false 经常用作开关)

引用数据类型(类、接口、数组)

char 型变量中能不能存贮一个中文汉字?#

可以,char占两个字节

运算符

逻辑与或与按位与或的区别:
逻辑与 false&&true false (有短路操作, 只能参与逻辑运算,不可以参与位运算)
按位与 false&true false (无短路操作, 可以参与位运算)
++i 先加后赋值
i++ 先赋值后加
+= x+=y;----- x=x+y;
逻辑运算符:
&& and
|| or
! not

位运算符:
& and
| 或
^ 异或

<< 左移 左移一位*2 左移2位 *22 左移n位 *2n

右移 右移一位/2 右移2位 /22 右移n位 /2n

用最有效率的方法算出 2 乘以 8 等於几?

2 << 3
因为将一个数左移 n 位,就相当于乘以了 2 的 n 次方,那么,一个数乘以 8 只要将其左移 3 位即可,
而位运算 cpu 直接支持的,效率最高,所以,2 乘以 8 等於几的最效率的方法是 2 << 3。

三元运算符

表达式1?表达式2:表达式3

        boolean b=(1>2)?true:false;
        System.out.println(b);------>false
        int i=(2>3)?1:0;
        System.out.println(i);------>0

分支

if/switch
switch
每个分支判断条件类型相同 switch支持的表达式类型为int、byte、char、short,String(JDK17+)

switch 语句能否作用在 byte 上----->能
能否作用在 long 上, ----->不能
能否作用在 String 上 ----->jdk1.7后能

假设switch –a分支没有break,那么他会继续向下执行,直到遇到break;
@Test
public void test2() {
char c='b';
switch (c) {
//a或者b进行相同的处理
case 'a':
//如果选择了a,那么执行什么
case 'b':
//如果选择了a,那么执行什么
System.out.println("您选择了a或者b");
break;
default://如果上述情况都不满足,就默认
break;
}

while与 dowhile区别

while直接判断是否成立 ---->有可能一次都没执行

do----while 先执行一次,然后再判断条件是否成立 ---->至少执行一次

for/foreach

for(int i=0;i<=100;i+=2){
      
}
for(循环到的对象类型   引用名称:循环谁){
    引用名称。。。。。。。
 }

死循环

while(true){
}

for(;;)

循环中断:

两种:
中断整个循环:break;
中断当次循环,进行到下一次循环(跳过本次循环,进行下一次)continue;

  1. break语句用于终止某个语句块的执行。用在循环语句体中,可以强行退出整个循环。

  2. “break;”语句:可以出现在while、do…while、for、switch语句体中。

  3. “break label”语句 :可以出现在任何语句体中。

循环的中断

  1. continue语句用在循环语句体中,用于终止某次循环过程,跳过本次循环,开始下一次循环过程
  2. “continue;” 语句:只能出现在循环语句while、do…while、for中,不能用在switch语句中

Break label:为每层循环定义个别名,break可以指定跳出哪一外名字的循环。

练习题

1.一球从100米高度自由落下,每次落地后反跳回原高度的一半;再落下,求它在第10次落地时,共经过多少米?第10次反弹多高?

 @Test
 public void test18(){
     /**
      * 1.一球从100米高度自由落下,每次落地后反跳回原高度的一半; 再落下
      * 求它在第10次落地时,共经过多少米?第10次反弹多高?
      */
     double h=100.00;
     //从第2次开始算,跳的高度 100+50+25+12.5+...
     //h/1+h/2+h/4+h/8
     double sum=100.00;
     for(int i=1;i<=9;i++){
         System.out.println("h="+h);
         sum+=h/2*2;
         h=h/2;
        
     }
     System.out.println("最终h="+h/2);
     System.out.println("sum="+sum);
 }

2.打印出所有的"水仙花数",所谓"水仙花数"是指一个三位数,其各个位数字立方和等于该数本身。
个位数字的立方+十位数字的立方+百位数字的立方的和= 它本身

@Test
public void test1() {
   for(int i=100;i<=999;i++){
       int bai=i/100;
       int shi=i/10%10;
       int ge=i%10;
       if(bai*bai*bai+shi*shi*shi+ge*ge*ge==i){
           System.out.println(i);
       }
       
   }
}

153
370
371
407

3、int total = 0;
for ( int i = 0; i < 4; i++ ){
if ( i == 1) continue;
if ( i == 2) break;
total += i;
}
则执行完该程序段后total的值为:( )。
A、0 B、1 C、3 D、6

数组

 第一种通过下标放值
//数组定义
      int a[]=new int[5];
 //数组第一个元素为1
      a[0]=1;
    //数组第2个元素为1
      a[1]=456;
     //数组第3个元素为1
      a[2]=123;
      a[3]=567;
      a[4]=2;
System.out.println(a[1]);     
第二种 通过new +{}组合方式
//数组初始化 方括号不写数字,根据初始化个数自动确定数组长度
数组类型  数组名[ ] = new 数据类型[ ]{元素1,元素2,…}
int a[]=new int[]{1,456,123,567,2};
第三种 直接初始化
数组类型  数组名[ ] = {元素1,元素2,…}
int a[]={1,456,123,567,2};

@Test
    public void test3() {
     //先建立一个一维数组,长度为100,存放1-100之间的数
     //存放完之后再写一段程序,把数组的每个元素打印出来
     int a[]=new int[100];
     int i=0;
     for(i=0;i<100;i++){
         //a[0]=1;a[1]=2  
         a[i]=i+1;
     }
     for(i=0;i<100;i++){
         System.out.println(a[i]);
     }
    
    }
多维数组:
定义
数组类型   数组名 [  ] [  ]
数组类型[  ] [  ]   数组名
数组类型[  ]   数组名 [  ]
int  a[ ] [ ] ;
int[ ][ ]  b ;
int[ ]  c[ ] ;
多维数组的创建
数组名 = new  数据元素类型[ 行数 ] [ 列数 ]
数组名 = new  数据元素类型[ 行数 ] [   ] ;
a = new  int [3][4] ;
 a = new  int [3][ ] ;
 a = new  int [ ][4]  ; //非法

int[][] array ={{1,2,3,4,5},{1,2,3,4,5},{1,2,3,4,5}} ;

方法定义与调用

[访问权限控制符] [修饰符] 返回值类型 方法名(参数类型 形参,参数类型 形参,…)

{
    方法体 //方法做什么业务
}

3、重载(编译时)和重写(运行时)##

运行时多态的三个必要条件:
1、必须有继承或实现(子类继承父类 实现类实现接口)
2、必须有重写 (子类重写父类的方法, 实现类覆盖接口的方法)
3、父类的引用指向子类的对象 也就是要有向上转型

重写:方法的定义完全相同,只是方法方法体不同
相同的方法名、相同的参数列表(参数类型,参数顺序)、相同的返回值类型
一定发生在子类当中,与父类同名,同参,同返回值类型的方法,子类覆盖方法的访问权限要不小于父类中被覆盖方法的访问权限

重载:同一个类中相同的方法名参数必须不同(参数类型不同或参数个数不同)、返回值可以相同也可以不同

请说出作用域 public ,private ,protected ,以及不写时的区别

作用域 当前类 同一package 子孙类 其他 package
public √ √ √ √
protected √ √ √ ×
default √ √ × ×
private √

继承和多态

类单继承
接口可以多继承
同一个类可以实现多个接口

构造方法

构造方法名与类名相同,无返回值类型,也不需要用void补位
如果你没有写有参构造,系统为你生成无参构造
如果你写了有参构造,不会再为你自动生成无参构造,这时候如果想用无参构造,需要重写

如何给新实例的对象赋值

1、属性的set方法赋值
2、通过有参构造方法赋值

变量类型

局部变量
方法级别的变量
局部变量只能在该方法里的有效
实例变量
成员变量 类级别
如果是公有的,其他类也能访问到
如果是私的的,当前类的所有方法都可以访问他
静态变量
第三种静态变量
用static修饰的变量 static修饰的变量是可以共享的变量
书写格式:访问权限 访问修饰 变量类型 变量名

java 中实现多态的机制是什么?

父类的引用指向子类的实例(接口与实现类之间 父类与子类之间)

抽象类与接口的区别

抽象类和接口都不能实例化
1)接口里的方法都是抽象的,而抽象类可以有非抽象方法。
2)类是单继承,多实现
3)接口和接口之间可以多继承(接口可以合并)
4)抽象类可以理解为抽象方法和非抽象方法的混合体,而接口中的方法全是抽象方法,是一套纯粹的规范。

  1. 接口里的属性必须是static final的,但抽象类无限制
  2. *接口里不能有构造方法,抽象类可以有构造方法

static与final

用static修饰的内容系统启动时就会加载进来,适合做一些初始化工作
Static 修饰的元素主要用来实现各个类之间共享,特别是属性

修饰:属性:
      方法
      代码块
需要注意的问题
   只能修饰类成员,不能修饰局部变量(不能修饰方法体里的变量)。 
•   用static修饰变量(属性)
   所有对象共享
•   也称为类变量
   用static修饰的成员变量,它们在类被载入时创建,只要类存在,static变量就存在(参考java虚拟机视频)
   两种方式访问:
•   直接访问:类名.属性;
•   实例化后访问:对象名.属性
•   用static修饰方法
   不需要实例化,可以直接访问
•   也称为类方法
   两种方式访问:
•   直接访问:类名.方法名()
•   实例化后访问:对象名.方法名()
•   注意事项
   静态方法里只能直接访问静态成员,而不能直接访问类中的非静态成员
   静态方法中不能使用this、super关键字
   静态方法不能被非静态方法覆盖,静态方法不能修饰构造器
•   静态代码块
   一个类中由static关键字修饰的,不包含在任何方法体中的代码块
   当类被载入时,静态代码块被执行,且只被执行一次
   静态块经常用来进行类属性的初始化

Final(终极的不可修改的)

可以修饰的内容:类 变量(属性) 方法
   类:不能被继承(没有下一代),可被实例化
   变量:常量,不能被重新赋值
       方法:不能被重写。

单例

•   单例模式实现:
–   拥有一个私有构造方法 
–   提供一个自身静态私有的成员变量
–   提供一个公有的静态的方法(返回实例化后的对象)

public class Singleton {
    /*• 单例模式实现:
    –   拥有一个私有构造方法 
    –   提供一个类型为自身的  静态的私有的成员变量(属性)
    –   提供一个公有的静态的方法(返回实例化后的对象)*/
    //step 2 提供一个类型为自身的  静态的私有的成员变量
    private static final Singleton instance=new Singleton();
    //step 1拥有一个私有构造方法 
    private Singleton (){
        
    }
    //step 3提供一个公有的静态的方法
    public static Singleton getSingleton(){
        return instance;
    }
    
    public static void main(String[] args) {
        Singleton s1=Singleton.getSingleton();
        Singleton s2=Singleton.getSingleton();
        System.out.println(s1);
        System.out.println(s2);
        
    }
}

final, finally, finalize 的区别

final 用于声明属性,方法和类,分别表示属性不可变,方法不可覆盖,类不可继承。
finally 是异常处理语句结构的一部分,表示总是执行。
finalize 是 Object 类的一个方法,在垃圾收集器执行的时候会调用被回收对象的此方法,
可以覆盖此方法提供垃圾收集时的其他资源回收,例如关闭文件等。JVM 不保证此方
法总被调用

String StringBuffer StringBuilder区别

String是不可变字符串常量,对它的改动都创建了新的对象;
StringBuffer与StringBuilder代表一组可以改变的字符串
StringBuffer是线程安全的
StringBuilder是线程不安全的,效率高于StringBuffer,单线程操作可以使用StringBuilder

String与 Math是否可被继承,为什么

不可以,因为被final修饰

计算子串在父串中出现的次数

public void test3(){
        System.out.println("请输入字符串1");
        String s1 = new Scanner(System.in).next();
        System.out.println("请输入字符串2");
        String s2 = new Scanner(System.in).next();
        //引进计数器用于记录次数
        int count = 0;
        while(s1.indexOf(s2)!=-1){
            System.out.println("存在");
            count++;
            s1=s1.substring(s1.indexOf(s2)+s2.length());
            System.out.println(s1);
        }
        System.out.println(count);
        //indexOf求子串在整串的次数
        //键盘输入
        //首先判断是否存在子串abc在父串中存在,如果存再计算次数
    }

List Set map

数组是定长的 可以存放基本类型和引用类型 访问较快 java.lang包中
集合是可变长的 集合只能存放引用类型 java.util包内

Set与list map
Set - 无序的集合;不允许重复(可用于去重)
List有序的集合;允许重复
Map key-value key-唯一标识 value实际存放的数据 适合根据指定唯一标识来查找

set的类型

• Set接口的实现类
HashSet — HashSet的特性在于其内部对象的散列存取,即采用哈希技术
TreeSet — TreeSet存入的顺序跟存储的顺序不同,但是存储是按照排序存储的

ArrayList与linkedlist区别

ArrayList--内部基于数组实现,随机查询速度快,插入删除速度慢;
(建议用普通for循环读取)
LinkedList--内部基于链表实现,随机查询速度慢,插入删除速度快
(用迭代器读取会比较快)

Map接口有两个实现:

HashMap:按hashcode排序 基于数组的
TreeMap:按自然顺序 基于红黑二叉树的
LinkedHashMap;按存入的顺序 基于链表的

冒泡算法(略)

扑克牌

package com.neuedu.test;

public interface Card {
    // 匹配情况
        String[] cases = { "花色点数都相同", "花色相同", "点数相同", "不相同" };
        // 花色
        String[] suits = { "红桃", "黑桃", "梅花", "方块" };
        // 牌面值
        String[] faces = { "2", "3", "4", "5", "6", "7", "8", "9", "10", "J", "Q", "K", "A" };

        // 判断两张牌的牌型
        String showPokerHands(Card card);

        public String getSuit();

        public String getFace(); 
}

package com.neuedu.test;

public class SuitException extends Exception {

    public SuitException(String message) {
        super(message);
    }
}

package com.neuedu.test;

public class FaceException extends Exception {

    public FaceException(String message) {
        super(message);
    }

}

package com.neuedu.test;

public class CardImpl implements Card {
    private String face;
    private String suit;

    public CardImpl(String face, String suit) throws SuitException, FaceException {
        // 判断花色是否在suits范围内。如果花色不对抛SuitException
        boolean suitFlag = false;// 不在花色范围内
        for (String mysuit : suits) {
            if (mysuit.equals(suit)) {
                suitFlag = true;// 花色合法
            }
        }
        if (suitFlag == false) {
            throw new SuitException("花色不合法");
        }
        boolean faceFlag = false;// 不在花色范围内
        for (String myface : faces) {
            if (myface.equals(face)) {
                faceFlag = true;// 花色合法
            }
        }
        if (faceFlag == false) {
            throw new FaceException("花色不合法");
        }
        // 判断花色是否在faces范围内。如果牌面不对抛FaceException
        this.face = face;
        this.suit = suit;
    }

    @Override
    public String showPokerHands(Card card) {
        // 判断花色和点数都相同
        if (face.equals(card.getFace()) && suit.equals(card.getSuit())) {
            return cases[0];
        } else if (face.equals(card.getFace())) {
            return cases[2];
        } else if (suit.equals(card.getSuit())) {
            return cases[1];
        } else {
            return cases[3];
        }
    }

    @Override
    public String getSuit() {
        // TODO Auto-generated method stub
        return null;
    }

    @Override
    public String getFace() {
        // TODO Auto-generated method stub
        return null;
    }

    public static void main(String[] args) throws SuitException, FaceException {
        // 创建一张红桃3,一张黑桃6,调用方法判断两张牌的牌型。
        CardImpl card1 = new CardImpl("3", "红桃");
        CardImpl card2 = new CardImpl("6", "黑桃");
        String result = card1.showPokerHands(card2);
        System.out.println(result);
    }
}
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 210,978评论 6 490
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 89,954评论 2 384
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 156,623评论 0 345
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 56,324评论 1 282
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 65,390评论 5 384
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 49,741评论 1 289
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 38,892评论 3 405
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 37,655评论 0 266
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 44,104评论 1 303
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 36,451评论 2 325
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 38,569评论 1 340
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 34,254评论 4 328
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 39,834评论 3 312
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 30,725评论 0 21
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,950评论 1 264
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 46,260评论 2 360
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 43,446评论 2 348

推荐阅读更多精彩内容