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,九九乘法表