今天面试,被问了两个问题。 1.Java的内存管理是怎么样的?什么时候回收一个对象?2.如何实现单链表的倒置。悲催,都答不上来,求高手指教 解决方案 » 免费领取超大流量手机卡,每月29元包185G流量+100分钟通话, 中国电信官方发货 1、JAVA虚拟机自动管理的。当一个对象不可到达时会。会被回收。2.不知道 寄存器 缓存 内存堆栈 外部存储 看程序运行时用到的对象层级关系 一层层保存。当一个对象失去了所有外部指针,也就是没有任何一个指针指向他的时候JVM就回收了。单链表倒置个人感觉最简单的就是放到堆栈里面然后再顺次取出来。一个LINKMAP就OK了 1.java内存管理是怎么样的。这个问题太笼统了!java是对内存分区管理,基本上分为:java堆、java虚拟机栈、本地方法栈、程序计数器、方法区。大概的话就划分为这些区域进行管理。其中方法区和堆是线程共有的。(关于每个区是干什么的,你就去搜一下吧,太多了)java回收对象是根据根搜索算法来回收的,当判定了该对象不可用之后其实并没有就回收了,其实相当于处于“死缓”阶段,要真正的宣告一个对象死亡,至少要经历两次标记过程。标记过程是啥呀的你也去搜一下吧,要写的话一大堆。2.至于单链表的倒置,你可以考虑创建一个链表,然后每次把之前链表的第一个节点移除,并放到新建的链表的第一个。以LinkedList为例:LinkedList<String> list = new LinkedList<String>(); list.add("a"); list.add("b"); list.add("c"); list.add("d"); LinkedList<String> list1 = new LinkedList<String>(); while(list.size() > 0){ list1.addFirst(list.removeFirst()); } System.out.println(list1); //[d, c, b, a] 栈内存:当超过变量的作用域后,Java会自动释放掉为该变量所分配的内存空间堆内存:由Java虚拟机的自动垃圾回收器管理 LinkedList<String> list = new LinkedList<String>(); list.add("a"); list.add("b"); list.add("c"); list.add("d"); for (int i = 0; i < list.size(); i++) { list.add(list.remove(list.size() - i - 1)); } System.out.println(list); 1.JVM认为该对象没用的时候自动回收该对象,可以使用finalize()建议进行回收,但仅仅是建议,并不一定回收.2.JAVA中有很多链表集合,至于倒置没用过 链表倒置 简单 啊···可以吧使用 reverse这个方法··楼主试试链表的话可以先转换类型 1.在内存中有四个区内存,code segament,date segament,stack,heap.对象是在heap中分配的,在堆中某个对象的没有被引用,JAVA虚拟机就会自动的回收分配给它的内存,以便给另外的对象使用!2.链表中有倒置的方法,很简单的,查查API就清楚了!希望对你有所帮助! java的内存管理:内存分为堆和栈,堆存放对象,栈存放对象的地址和基本数据类型。对象的回收由java虚拟机的垃圾回收器来自动回收,它会不定时的扫描内存中的对象,发现对象不再使用时就回收,程序员不能手工回收(虽然可以调用System.gc(),但是不会马上执行)。可以创建一个新的单项链表,新链表的尾节点为旧链表的头节点,遍历旧链表,把遍历到的节点的next指针指向新节点的头节点即可。(LinkedList是双向链表,这个不符合题意的。。) 链表倒置是这样的:从链表的头部开始遍历链表,要保存三个链表的地址值p、q、rp表示当前节点,q表示p的下一个节点,r表示q的下一个节点每一次的循环时,循环体如下:q->next=pp=qq=rr=r->next即:q=p->next (p表示当前节点)r=q->nextwhile(r->next){ q->next=p; p=q q=r r=r->next}q->next=pr->next=qreturn r(现在的r变成表头了) 给个C代码吧:LinkList* reverseList(LinkList *p){ LinkList *q,*r; q=(LinkList *)malloc(sizeof(LinkList)); r=(LinkList *)malloc(sizeof(LinkList)); q=p->next ; //(p表示当前节点) r=q->next ; while(r->next) { q->next=p; p=q; q=r; r=r->next; } q->next=p; r->next=q; return r ; // (现在的r变成表头了)} good,要的就是这个效果,请问你这里表头是不是不保存数据的? /** * */package com.handy.ds;/** * @author handy 2012-3-15 */class Node { int data; Node next; public Node() { } public Node(int data, Node next) { this.data = data; this.next = next; }}public class SingleLinkedList { private Node head; /** * @return the head */ public Node getHead() { return head; } /** * @param head * the head to set */ public void setHead(Node head) { this.head = head; } public SingleLinkedList() { head = new Node(); } public boolean isEmpty() { if (head.next == null) return true; else return false; } public boolean addToLast(int elem) { if (isEmpty()) { head.next = new Node(elem, null); return true; } else { Node curr = head.next, prev = null; while (curr != null) { prev = curr; curr = curr.next; } Node newNode = new Node(elem, null); prev.next = newNode; return true; } } public boolean addToFirst(int elem) { if (isEmpty()) { head.next = new Node(elem, null); return true; } else { Node p = new Node(elem, head.next); head.next = p; return true; } } public void printList() { if (head.next == null) { System.out.print("空"); } for (Node p = head.next; p != null; p = p.next) System.out.print(p.data + ","); System.out.println(); } public boolean insert(int posValue, int elem) { if (isEmpty() && posValue == 0) { head.next = new Node(elem, null); return true; } else { Node prev = head, curr = head.next, newNode = new Node(elem, null); while (curr != null && curr.data != posValue) { if (curr.next == null) return false; prev = curr; curr = curr.next; } newNode.next = curr; prev.next = newNode; return true; } } public int removeFirst() { if (isEmpty()) { return -1; } else { Node temp = head.next; if (temp.next != null)// 有两个以上节点 head = temp.next; else head.next = null; // 一个节点 return temp.data; } } public int removeLast() { if (isEmpty()) { return -1; } else { int temp = 0; Node prev = head, curr = head.next; while (curr != null) { if (curr.next == null) { temp = curr.data; prev.next = null; // System.out.println(1); } prev = curr; curr = curr.next; return temp; } return temp; } } public boolean remove(int elem) { if (isEmpty()) return false; else { Node prev = head, curr = head.next; while (curr != null && curr.data != elem) { if (curr.next == null) { return false; } prev = curr; curr = curr.next; } prev.next = curr.next; return true; } } // 1.将单链表逆置 public boolean reverse1() { if (isEmpty()) return false; Node p = head, q = head.next; Node r; while (q != null) { r = q.next; q.next = p; p = q; q = r; } head.next.next = null; head.next = p; return true; } // 2.将单链表逆置 public boolean reverse2() { if (isEmpty()) return false; int size = 0; for (Node p = head.next; p != null; p = p.next) size++; int[] array = new int[size]; int i; Node p; for (p = head.next, i = 0; p != null && i < size; p = p.next, i++) array[i] = p.data; for (p = head.next, i = 0; p != null && i < size; p = p.next, i++) p.data = array[size - 1 - i]; return true; }} package com.handy.ds;/** * @author handy * */public class TestLink { /** * @param args */ public static void main(String[] args) { // TODO Auto-generated method stub SingleLinkedList sll = new SingleLinkedList(); sll.printList();// 空, sll.addToFirst(3); sll.printList();// 3, sll.addToLast(4); sll.printList();// 3,4, sll.remove(3); sll.printList();// 4, sll.removeFirst(); sll.printList();// 空 sll.removeFirst(); sll.printList();// 空 System.out.println(sll.isEmpty());// true sll.removeFirst(); sll.printList();// 空 sll.removeLast(); sll.printList();// 空 sll.remove(5); sll.printList();// 空 sll.addToLast(4); sll.printList();// 4 sll.addToLast(5); sll.printList();// 4,5, // 在元素3之前插入6 sll.insert(3, 6); sll.printList();// 4,5, // 在元素3之前插入6 sll.insert(5, 3); sll.printList();//4,3,5, sll.reverse1(); sll.printList();//5,3,4, sll.reverse2(); sll.printList();//4,3,5, }} 面试的时候我说的是使用reverse2方法进行链表逆置,貌似是可以,但是效率,明显太低了~~ 请问要这两句来干嘛?q=(LinkList *)malloc(sizeof(LinkList)); r=(LinkList *)malloc(sizeof(LinkList)); 这里原链表的头的next应该改成NULL才对吧,貌似少了这一步 不同文件夹内的java文件相互调用的javac 编译问题 希望能帮我看看这段代码。没有把数据写入数据库 还有一个题目 有空的请看一下。 关于List中分页的问题,有没有什么好的办法解决呢? 一个连接数据库的问题 帮帮忙,我的javac有问题,请帮助解决 谁有vc++考题或习题 关于文本格式的问题 有谁搞过vrml和java的联合应用,eai方式。 问一个timer的问题 小弟刚学习java 求高手给看看这个简单的程序哪里错了 谢了 在线等哈 数据溢出的疑问
当一个对象不可到达时会。会被回收。
2.不知道
当一个对象失去了所有外部指针,也就是没有任何一个指针指向他的时候JVM就回收了。单链表倒置个人感觉最简单的就是放到堆栈里面然后再顺次取出来。一个LINKMAP就OK了
java回收对象是根据根搜索算法来回收的,当判定了该对象不可用之后其实并没有就回收了,其实相当于处于“死缓”阶段,要真正的宣告一个对象死亡,至少要经历两次标记过程。标记过程是啥呀的你也去搜一下吧,要写的话一大堆。
2.至于单链表的倒置,你可以考虑创建一个链表,然后每次把之前链表的第一个节点移除,并放到新建的链表的第一个。以LinkedList为例:LinkedList<String> list = new LinkedList<String>();
list.add("a");
list.add("b");
list.add("c");
list.add("d");
LinkedList<String> list1 = new LinkedList<String>();
while(list.size() > 0){
list1.addFirst(list.removeFirst());
}
System.out.println(list1);
//[d, c, b, a]
堆内存:由Java虚拟机的自动垃圾回收器管理
LinkedList<String> list = new LinkedList<String>();
list.add("a");
list.add("b");
list.add("c");
list.add("d");
for (int i = 0; i < list.size(); i++) {
list.add(list.remove(list.size() - i - 1));
}
System.out.println(list);
2.JAVA中有很多链表集合,至于倒置没用过
链表的话可以先转换类型
2.链表中有倒置的方法,很简单的,查查API就清楚了!希望对你有所帮助!
p表示当前节点,q表示p的下一个节点,r表示q的下一个节点
每一次的循环时,循环体如下:
q->next=p
p=q
q=r
r=r->next
即:
q=p->next (p表示当前节点)
r=q->next
while(r->next)
{
q->next=p;
p=q
q=r
r=r->next
}
q->next=p
r->next=q
return r(现在的r变成表头了)
{
LinkList *q,*r;
q=(LinkList *)malloc(sizeof(LinkList));
r=(LinkList *)malloc(sizeof(LinkList));
q=p->next ; //(p表示当前节点)
r=q->next ;
while(r->next)
{
q->next=p;
p=q;
q=r;
r=r->next;
}
q->next=p;
r->next=q;
return r ; // (现在的r变成表头了)
}
*
*/
package com.handy.ds;/**
* @author handy 2012-3-15
*/
class Node {
int data;
Node next; public Node() { } public Node(int data, Node next) {
this.data = data;
this.next = next;
}
}public class SingleLinkedList {
private Node head; /**
* @return the head
*/
public Node getHead() {
return head;
} /**
* @param head
* the head to set
*/
public void setHead(Node head) {
this.head = head;
} public SingleLinkedList() {
head = new Node();
} public boolean isEmpty() {
if (head.next == null)
return true;
else
return false;
} public boolean addToLast(int elem) {
if (isEmpty()) {
head.next = new Node(elem, null);
return true;
} else {
Node curr = head.next, prev = null;
while (curr != null) {
prev = curr;
curr = curr.next;
}
Node newNode = new Node(elem, null);
prev.next = newNode;
return true;
} } public boolean addToFirst(int elem) { if (isEmpty()) {
head.next = new Node(elem, null);
return true;
} else {
Node p = new Node(elem, head.next);
head.next = p;
return true;
}
} public void printList() {
if (head.next == null) {
System.out.print("空");
}
for (Node p = head.next; p != null; p = p.next)
System.out.print(p.data + ",");
System.out.println(); } public boolean insert(int posValue, int elem) {
if (isEmpty() && posValue == 0) {
head.next = new Node(elem, null);
return true;
} else {
Node prev = head, curr = head.next, newNode = new Node(elem, null);
while (curr != null && curr.data != posValue) {
if (curr.next == null)
return false;
prev = curr;
curr = curr.next;
}
newNode.next = curr;
prev.next = newNode;
return true;
} } public int removeFirst() {
if (isEmpty()) {
return -1;
} else {
Node temp = head.next;
if (temp.next != null)// 有两个以上节点
head = temp.next;
else
head.next = null; // 一个节点
return temp.data;
} } public int removeLast() { if (isEmpty()) {
return -1;
} else {
int temp = 0;
Node prev = head, curr = head.next; while (curr != null) {
if (curr.next == null) {
temp = curr.data;
prev.next = null;
// System.out.println(1);
}
prev = curr;
curr = curr.next;
return temp;
}
return temp;
} } public boolean remove(int elem) {
if (isEmpty())
return false;
else {
Node prev = head, curr = head.next;
while (curr != null && curr.data != elem) {
if (curr.next == null) {
return false;
} prev = curr;
curr = curr.next; } prev.next = curr.next; return true;
}
} // 1.将单链表逆置
public boolean reverse1() {
if (isEmpty())
return false; Node p = head, q = head.next;
Node r; while (q != null) {
r = q.next;
q.next = p;
p = q;
q = r; }
head.next.next = null;
head.next = p;
return true;
} // 2.将单链表逆置
public boolean reverse2() {
if (isEmpty())
return false;
int size = 0;
for (Node p = head.next; p != null; p = p.next)
size++;
int[] array = new int[size];
int i;
Node p;
for (p = head.next, i = 0; p != null && i < size; p = p.next, i++)
array[i] = p.data;
for (p = head.next, i = 0; p != null && i < size; p = p.next, i++)
p.data = array[size - 1 - i]; return true;
}}
* @author handy
*
*/
public class TestLink { /**
* @param args
*/
public static void main(String[] args) {
// TODO Auto-generated method stub
SingleLinkedList sll = new SingleLinkedList();
sll.printList();// 空,
sll.addToFirst(3);
sll.printList();// 3,
sll.addToLast(4);
sll.printList();// 3,4,
sll.remove(3);
sll.printList();// 4,
sll.removeFirst();
sll.printList();// 空
sll.removeFirst();
sll.printList();// 空
System.out.println(sll.isEmpty());// true
sll.removeFirst();
sll.printList();// 空
sll.removeLast();
sll.printList();// 空
sll.remove(5);
sll.printList();// 空
sll.addToLast(4);
sll.printList();// 4
sll.addToLast(5);
sll.printList();// 4,5,
// 在元素3之前插入6
sll.insert(3, 6);
sll.printList();// 4,5,
// 在元素3之前插入6
sll.insert(5, 3);
sll.printList();//4,3,5,
sll.reverse1();
sll.printList();//5,3,4,
sll.reverse2();
sll.printList();//4,3,5,
}}
请问要这两句来干嘛?
q=(LinkList *)malloc(sizeof(LinkList));
r=(LinkList *)malloc(sizeof(LinkList));
这里原链表的头的next应该改成NULL才对吧,貌似少了这一步