java笔试

1,简单描述数组(vector)与链表(list)的区别以及应用场景。
(java)java中vetcor和ArrayList的区别
首先看这两类都实现List接口,而List接口一共有三个实现类,分别是ArrayList、Vector和LinkedList。List用于存放多个元素,能够维护元素的次序,并且允许元素的重复。
3个具体实现类的相关区别如下:

1.ArrayList是最常用的List实现类,内部是通过数组实现的,它允许对元素进行快速随机访问。数组的缺点是每个元素之间不能有间隔,当数组大小不满足时需要增加存储能力,就要讲已经有数组的数据复制到新的存储空间中。当从ArrayList的中间位置插入或者删除元素时,需要对数组进行复制、移动、代价比较高。因此,它适合随机查找和遍历,不适合插入和删除。

2.Vector与ArrayList一样,也是通过数组实现的,不同的是它支持线程的同步,即某一时刻只有一个线程能够写Vector,避免多线程同时写而引起的不一致性,但实现同步需要很高的花费,因此,访问它比访问ArrayList慢。

3.LinkedList是用链表结构存储数据的,很适合数据的动态插入和删除,随机访问和遍历速度比较慢。另外,他还提供了List接口中没有定义的方法,专门用于操作表头和表尾元素,可以当作堆栈、队列和双向队列使用。

查看Java源代码,发现当数组的大小不够的时候,需要重新建立数组,然后将元素拷贝到新的数组内,ArrayList和Vector的扩展数组的大小不同。

ArrayList中:

public boolean add(E e) {
     ensureCapacity(size + 1);  // 增加元素,判断是否能够容纳。不能的话就要新建数组
     elementData[size++] = e;
     return true;
 }
  public void ensureCapacity(int minCapacity) {
     modCount++; 
     int oldCapacity = elementData.length;
     if (minCapacity > oldCapacity) {
         Object oldData[] = elementData; // 此行没看出来用处,不知道开发者出于什么考虑
         int newCapacity = (oldCapacity * 3)/2 + 1; // 增加新的数组的大小
         if (newCapacity < minCapacity)
        newCapacity = minCapacity;
             // minCapacity is usually close to size, so this is a win:
             elementData = Arrays.copyOf(elementData, newCapacity);
     }
 }

Vector中:

private void ensureCapacityHelper(int minCapacity) {
     int oldCapacity = elementData.length;
     if (minCapacity > oldCapacity) {
         Object[] oldData = elementData;
         int newCapacity = (capacityIncrement > 0) ?
        (oldCapacity + capacityIncrement) : (oldCapacity * 2);
         if (newCapacity < minCapacity) {
        newCapacity = minCapacity;
         }
        elementData = Arrays.copyOf(elementData, newCapacity);
     }
 }

关于ArrayList和Vector区别如下:
1.ArrayList在内存不够时默认是扩展50% + 1个,Vector是默认扩展1倍。
2.Vector提供indexOf(obj, start)接口,ArrayList没有。
3.Vector属于线程安全级别的,但是大多数情况下不使用Vector,因为线程安全需要更大的系统开销。
(c++):(由于笔试时没有看过C++,所以不知道考的是c++的内容,这里先写一点,后续加上)http://blog.csdn.net/alex_xhl/article/details/37692297
List封装了链表,Vector封装了数组, list和vector得最主要的区别在于vector使用连续内存存储的,他支持[]运算符,而list是以链表形式实现的,不支持[]。

Vector对于随机访问的速度很快,但是对于插入尤其是在头部插入元素速度很慢,在尾部插入速度很快。List对于随机访问速度慢得多,因为可能要遍历整个链表才能做到,但是对于插入就快的多了,不需要拷贝和移动数据,只需要改变指针的指向就可以了。另外对于新添加的元素,Vector有一套算法,而List可以任意加入。
2,C中的malloc和C++中的new有什么区别?
1,malloc与free是C++/C语言的标准函数,new/delete是C++的运算符。它们都可以用于申请动态内存和释放内存。
2,对于非内部数据类型的对象而言,光用malloc/free无法满足动态对象的要求。对象在创建的同时要自动执行构造函数,对象在消亡之前要自定执行析构函数。由于malloc/free是库函数而不是运算符,不在编译器控制权限内,不能够把执行构造函数和析构函数的任务强加于malloc/free。
3,因此C++语言需要一个能完成动态内存分配和初始化工作的运算符new,以一个能完成清理与释放内存工作运算符delete。注意new/delete不是库函数。
4,C++程序经常要调用C函数,而C程序只能用malloc/free管理动态内存
new是操作符,malloc是分配内存的函数,供你调用
new是保留字,不需要头文件支持。malloc需要头文件库函数支持。
new建立的是一个对象。malloc分配的是一块内存。
new建立的对象你可以把它当成一个普通的对象,用成员函数访问,不要直接访问它的地址空间。malloc分配的是一块内存区域,就用指针访问好了,而且还可以在里面移动指针。
  简而言之:
  new 是一个操作符,可以重载
  malloc是一个函数,可以覆盖
  new 初始化对象,调用对象的构造函数,对应的delete调用相应的析构函数
  malloc仅仅分配内存,free仅仅回收内存
malloc函数
原型:extern void*malloc(unsigned int num_bytes);
用法:#include<malloc.h>
功能:分配长度为num_bytes字节的内存块
说明:如果分配成功则返回指向被分配内存的指针,否则返回空指针NULL。当内存不再使用时,应使用free()函数将内存块释放。
举例:

//malloc.c
#include<syslib.h>
#include<malloc.h>
main(){
    char *p;
    clrscr();//清空显示
    p=(char*)malloc(100);
    if(p)
    printf("Memory Allocated at:%x",p);
    else
    printf("Not Enough Memory!\n");
    free(p);
    getchar();
    return 0;
}

函数声明(函数原型):
void *malloc(int size);
说明:malloc向系统申请分配指定size个字节的内存空间。返回类型是void*类型。
void*表示未确定类型的指针。C,C++规定,void* 类型可以强制转换为任何其它类型的指针。从函数声明上可以看出。malloc 和 new 至少有两个不同: new 返回指定类型的指针,并且可以自动计算所需要大小。比如:
int *p;
p = new int; //返回类型为int* 类型(整数型指针),分配大小为 sizeof(int);
或:
int* parr;
parr = new int [100]; //返回类型为 int* 类型(整数型指针),分配大小为 sizeof(int) * 100;
而 malloc 则必须由我们计算要字节数,并且在返回后强行转换为实际类型的指针。
int* p;
p = (int *) malloc (sizeof(int));
第一、malloc 函数返回的是 void * 类型,如果你写成:p = malloc (sizeof(int)); 则程序无法通过编译,报错:“不能将 void* 赋值给 int * 类型变量”。所以必须通过 (int *) 来将强制转换。
第二、函数的实参为 sizeof(int) ,用于指明一个整型数据需要的大小。如果你写成:
int* p = (int *) malloc (1);
代码也能通过编译,但事实上只分配了1个字节大小的内存空间,当你往里头存入一个整数,就会有3个字节无家可归,而直接“住进邻居家”!造成的结果是后面的内存中原有数据内容全部被清空。
malloc 也可以达到 new [] 的效果,申请出一段连续的内存,方法无非是指定你所需要内存大小。
比如想分配100个int类型的空间:
int* p = (int ) malloc ( sizeof(int) 100 ); //分配可以放得下100个整数的内存空间。 另外有一点不能直接看出的区别是,malloc 只管分配内存,并不能对所得的内存进行初始化,所以得到的一片新内存中,其值将是随机的。 除了分配及最后释放的方法不一样以外,通过malloc或new得到指针,在其它操作上保持一致。

3,二进制数组11101101转换为十八(18)进制数是多少?

4,操作系统的主要功能有哪些?列出你所知道的操作系统?

5,请写出下面代码在32位和64位操作系统下的输出结果?

void_test(){
    char x[] = "csdn123";
    cahr y[20] = "csdn123";
    wchar_t wch[] = L"csdn123";

    printf("%d,%d,%d,%d,%d,%d,%d,%d",
        sizeof(char),sizeof(char*),
        sizeof(x),strlen(x),
        sizeof(y),strlen(y),
        sizeof(wch),wcslen(wch)
        );          
}

6,请写出下面有什么错误(如果有的话),如何修改?

void swap(int *p1, int *p2){
    int *p;
    *p = *p1;
    *p1 = *p2;
    *p2 = *p;
}
void swap(int *p1, int *p2) 
{ 
    int *p;
    *p=*p1; //这句话有错,因为int *p是一个指针,并且在定义之后未初始化,所以其指向的地址也是不
    //确定的。直接让*p=*p1会让一个随机地址里的内容等于*p1的内容,所以可能导致系统崩溃。编译
    //也不会通过。
    *p1=*p2; 
    *p2=*p; 
}

可如此更改

void swap(int *p1, int *p2) 
{
    int tmp=0; 
    int *p=&tmp; 
    *p=*p1; 
    *p1=*p2; *p2=*p; 
}申请一个临时变量让P去指向就不会出错了。

或者更简单

void swap(int *p1, int *p2) 
{
    int tmp=0; 
    tmp=*p1; 
    *p1=*p2;
     *p2=tmp; 
}

7,请写出下面的输出结果

void main(void){
    int a[5] = {1,2,3,4,5};
    int *ptr = (int*)(&a+1);
    printf("%d,%d",*(a+1),*(ptr-1));
}

8,实现函数:输入年月日时分秒(字符串),输出该年月日时分秒后的n秒对应的时间(字符串),比如2014-12-31 23:59:56 ,n=10,则输出2015-01-01 00:00:06,(不允许使用系统函数),输入输出的时间格式:YYYY-MM-DD hh:mm:ss

package com.xhd.ths;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.Date;

public class Timetran {
    public static void main(String args[]) throws ParseException{
        String time = "2014-12-31 23:59:56";//输入时间
        int sends = 10;//输入秒数
        String newtime = printTime(a,b);//新输出时间
        System.out.println(newtime);
    }
    public static String printTime(String time,int sends) throws ParseException{
        SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
        Date date =sdf.parse(time);
        //获取时间戳
        long longTime =date.getTime();
        //时间戳里的单位是毫秒
        longTime+=sends*1000;
        Date date1 = new Date(longTime);
        return sdf.format(date1);
    }

}

9,实现函数:十进制转二进制 char*dec_to_bin(int_input,char*_output,int_len);
例如:输入0x7FF00FEF 输出:11111111111000000001111111101111

A,请估算一下在大学期间你总共写过多少行代码?你认为最得意的代码是什么?请简单描述一下。
B,在多CPU,多核时代,如何在软件开发层面提升软件的性能?在实现个过程是会遇到哪些问题?
C,如果你可以为自己熟悉的语言增加新的特性,你最想加的特性是哪些?

1,(JAVA)实现一个线程类有几种方式?有几种启动方式?请编码实现,并启动。
这篇博客介绍的比较详细:http://blog.csdn.net/aboy123/article/details/38307539
java5以前有两种方式:分别是使用new Thread()和new Thread(runnable)形式,第一种直接调用thread的run方法。第二种调用runnable的run方法。
第一种:
new Thread(){}.start();表示调用Thread子类对象的run方法,new Thread的匿名子类的实例对象,子类加上run方法后的代码如下:

new Thread(){
   public void run(){
   }
}.start()
class MyThread extends Thread(){
    public void run(){
    //do
    }
};
//创建并启动线程
MyThread mythread = new MyThread();
mythread.start();

第二种:
new Thread(new Runnable(){}).start();这表示调用Thread对象接受的Runnable对象的run方法,new Runnable(){}表示一个Runnable的匿名子类的实例对象,runnable的子类加上run方法后的代码如下:

new Thread(new Runnable(){
               public void run(){
               }    
        }
   ).start();
class MyThread implements Runnable{
        public void run(){
        //do
    }
}
//创建并启动一个线程
MyThread mythread = new MyThread();
new Thread(mythread).start();

第三种:实现Callable接口,重写call函数
Callable是类似于Runnable的接口,实现Callable接口的类和实现Runnable的类都是可被其它线程执行的任务。
Callable和Runnable有几点不同:
①Callable规定的方法是call(),而Runnable规定的方法是run().
②Callable的任务执行后可返回值,而Runnable的任务是不能返回值的
③call()方法可抛出异常,而run()方法是不能抛出异常的。
④运行Callable任务可拿到一个Future对象,Future表示异步计算的结果。它提供了检查计算是否完成的方法,以等待计算的完成,并检索计算的结果.通过Future对象可了解任务执行情况,可取消任务的执行,还可获取任务执行的结果。

2,(JAVA)画出JAVA中集合类的继承关系图。
这里写图片描述

3,(JAVA)实现函数:输出九九乘法表。

package com.xhd.ths;

public class Nine {
    public static void main(String[] args){
        System.out.println();
        int i;
        int j;
        for(i=1;i<=9;i++){
            for(j=1;j<=i;j++){
                System.out.println(j+"*"+i+"="+i*j+"\t");               
            }
            System.out.println();
        }
    }

}

4,(C/C++)实现一个适用于多线程的单列模式的类。
5,(C/C++)windows平台的动态链接库(DLL)有哪几种调用方式?比较一下优缺点。
6,(C/C++)实现函数:输入一个文本文件的文件名(文件大小在100M-6G之间)和一个关键字字符串,要求在文件中搜索并统计关键字的搜索次数。
7,(搜索)请写出k-means算法的伪代码
8,(搜索)我们有1000个公司名称,如何从互联网上获得更多的公司名称?
9,(搜索)请描述你所知道的分类算法,并列出影响分类结果的各种因素。
10,(PHP)用最简短的代码编写一个获取3个数字中最大值的函数。
11,(PHP)请描述==和===的区别,并列出什么情况下一定要===,什么情况下用==更合适(需要自己创建一个应用场景,来说明它们在实际应用中的用途)
12,(PHP)请简述php中传值和传引用的区别,什么时候传值什么时候传引用?如何传引用?
13,(PHP)在php程序开发中使用echo,print()和print_r()打印有什么区别?

面试题:1树的概念,有两个变量,如何在不使用第三个变量的情况下相互换两个变量的值。
2,面向对象的三大特性,多态具体是什么。
3,重载和重写的区别
4,使用过JAVA哪些开源框架
5,数据库中inner join和left join的区别
6,九九乘法表

发布了52 篇原创文章 · 获赞 9 · 访问量 12万+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章