几道面试题

本文解析了Java中的几个基础知识,包括按位运算符的应用、char类型如何存储汉字、线程中的sleep()方法与wait()方法的区别以及Java中启动线程的不同方式。

1.System.out.println(4|7),问输出的结果?

 此题关键点在“|”符,以前只知道它代表“或者”的意思,没想到它的全称是“按位或”,即是按二进制位运算。

 所以此题的正解是:

  4的2进制值是 00000100

  7的2进制值是 00000111

  按位或运算后为 00000111 也就是 7

题目延伸:System.out.println(4&7) ,输出结果?

  &:位运算是对整数的进制位进行操作
  4的二进制:0100
  7的二进制:0111
  首先,二进制与运算规则:1&1=1 1&0=0 0&0=0
  然后我们列出表
  DCBA
  0100
  0111
  这样们得到
  A:0
  B:0
  C:1
  D:0
  最好得到:
  DCBA
  0100
  结果0100
  好明显就是:4了

2 一个char类型的变量可以保存一个汉字吗?

  以前对char类型占多少个字节这种问题,总是朦朦胧胧,看到这条面试题时,当时考虑,char类型只占一个字节,而一个汉字要占两个字节,所以保存不了。

  后来被面试官一顿乱喷,说这么基础的问题都不懂,实在难以理解。随后再网上找来答案,原来这道题还涉及到java的编码问题。

  java采用的是unicode编码方式,C采用的是ASCII编码方式。而ASCII和Unicode又有何种区别呢?

   ASCII就是编码英文的26个字母和一些常见的符号,之后扩展了一半。总之是一个字节来做编码,大于128的部分是一些特殊符号。但ASCII是无法编码别的东西的,比如说是不               存在“中文的ascii码需要2个字符”这种说法的。ASCII就只有一个字节。
   Unicode是足够编码地球上所有的语言了,所以ASCII中所能表示的,Unicode当然全部包括了。Unicode本身是只有2个字节的,之所以出现UTF-8,UTF-16等等之类,那是为     了针对不同的应用环境,提高整体编码效率,比如如果某篇文章里绝大部分是英语(单字节就能表示),就比较适合使用utf-8,而如果绝大部分是中文(需要双字节),可能  就utf-16比较合适了。

   最简单的说就是,unicode有每个编码的字符有本身就占两个字节,而ascii编码的字符本身只占一个字节;

   所以在java中一个char类型的字符占了两个字节,而一个汉字也刚好为两个字节,当然能够存放一个汉字了。(在C中不行,这也是为什么搞混的原因)

  测试一下:

  

public class Test {
    public static void main(String[] args) {
       String myName="My name is 于祥通";
       char xiang='于'; //合法的
       System.out.println("我的姓氏为:"+xiang); //输出:我的姓氏为:于
       System.out.println(myName.substring(0, 1)); //输出:M
       System.out.println(myName.substring(myName.length()-1, myName.length())); //输出:通
    }
}

  substring 处理的最小单元就是一个字符,也就是一个char类型,2个字节 。

3. 线程中sleep()方法和wait()的区别?

  1,这两个方法来自不同的类分别是Thread和Object 

  2,最主要是sleep方法没有释放锁,而wait方法释放了锁,使得其他线程可以使用同步控制块或者方法。 

  3,wait,notify和notifyAll只能在同步控制方法或者同步控制块里面使用,而sleep可以在任何地方使用    synchronized(x){       x.notify()      //或者wait()    } 

  4,sleep必须捕获异常,而wait,notify和notifyAll不需要捕获异常

4. 线程有多少种的启动方式?

 4.1.继承Thread

public class java_thread extends Thread{
	public static void main(String args[])
	{
		(new java_thread()).run();
		System.out.println("main thread run ");
	}
	public synchronized  void run()
	{
		System.out.println("sub thread run ");
	}

}

 4.2 实现Runnable接口

public class java_thread implements Runnable{
	public static void main(String args[])
	{
		(new Thread(new java_thread())).start();
		System.out.println("main thread run ");
	}
	public void run()
	{
		System.out.println("sub thread run ");
	}

}

 4.3直接在函数体使用

void java_thread()
{

     Thread t = new Thread(new Runnable(){
            public void run(){
            mSoundPoolMap.put(index, mSoundPool.load(filePath, index));
            getThis().LoadMediaComplete();
            }});
		t.start();
}

  4.4.比较:

  实现Runnable接口优势:

  1)适合多个相同的程序代码的线程去处理同一个资源

  2)可以避免java中的单继承的限制

  3)增加程序的健壮性,代码可以被多个线程共享,代码和数据独立。

  继承Thread类优势:

  1)可以将线程类抽象出来,当需要使用抽象工厂模式设计时。

  2)多线程同步

  在函数体使用优势

  1)无需继承thread或者实现Runnable,缩小作用域。

                                                                ----例子来自网上

 

转载于:https://www.cnblogs.com/asdzheng/archive/2013/06/02/3114074.html

<think>嗯,用户让我根据C语言的数据结构出几道面试题,并且给出答案。首先,我需要确定用户的需求是什么。他们可能是正在准备面试的求职者,或者是面试官需要题目来考察候选人。不管怎样,题目需要覆盖C语言中常见的数据结构,同时难度要适中,既有基础题也有稍微复杂一点的题目。 首先,回忆一下C语言中常用的数据结构有哪些。基础的有数组、链表、栈、队列,然后是树、图,以及哈希表、堆等。考虑到面试题的常见性,链表、树、栈、队列这些应该是重点。此外,算法题通常会结合这些数据结构,比如反转链表、二叉树遍历等。 接下来要考虑题目的类型。用户可能希望有代码实现题,也有一些理论题,比如时间复杂度或者结构定义的题目。不过根据之前的例子,用户提供的SQL题都是需要写代码的,所以可能更偏向于编程题。不过数据结构题除了代码实现,也可能涉及概念性问题,比如优缺点比较。 然后,我需要设计每个问题,确保覆盖不同的数据结构。例如,链表可以出反转链表的问题,树可以出遍历或者验证二叉搜索树,栈和队列可以出实现或用栈实现队列,哈希表可以出设计题目,堆可以涉及优先队列的实现,图的话可能最短路径或者遍历,但图的问题可能比较复杂,可以作为进阶题。 接下来,每个题目需要参考答案,并且答案要准确。例如,反转链表的递归和迭代方法,二叉树的中序遍历递归和迭代,设计哈希表需要考虑冲突处理的方法,比如链地址法或者开放寻址法。 还要注意题目的难度梯度,从基础到中等,避免一开始就太难的题目,让用户逐步深入。比如先链表、栈,然后树、哈希表,最后堆和图。 另外,用户可能希望题目能够考察面试者对内存管理的理解,因为C语言需要手动管理内存。所以在链表或树的问题中,可能需要考虑内存分配和释放,比如在代码实现中是否处理了动态分配的内存。 还要考虑到边界条件,比如空指针、单节点链表等,这些在参考答案中也需要体现,确保代码的健壮性。 最后,总结部分需要指出考察的重点,比如指针操作、递归、内存管理等,帮助用户理解每个题目背后的考察点。 现在,具体想每个题目: 1. 反转单链表:经典题目,迭代和递归两种方法,考察指针操作和递归理解。 2. 用栈实现队列:考察对栈和队列特性的理解,以及如何用两个栈模拟队列。 3. 验证二叉搜索树:需要理解BST的定义,以及如何通过中序遍历或递归验证每个节点的值范围。 4. 设计哈希表:考察哈希表的基本实现,包括哈希函数、冲突处理,链地址法的应用。 5. 合并两个有序链表:同样经典,考察链表操作和递归/迭代方法。 6. 二叉树的中序遍历:递归和迭代实现,特别是迭代需要使用栈,考察对遍历过程的理解。 7. 最小栈:在常数时间内获取最小值,需要辅助栈来跟踪最小值。 8. 循环队列的实现:考察队列的环形缓冲区实现,处理队空和队满的条件。 9. 堆排序:实现最大堆和堆排序过程,考察对堆结构的理解和排序算法的应用。 10. 图的最短路径(Dijkstra算法):较难,但可以考察对图结构和算法的掌握,适合高级岗位。 每个题目需要给出参考答案,并且确保代码正确,符合C语言的语法,比如指针的使用、结构体定义、动态内存分配和释放等。 在参考答案中,要详细注释,解释关键步骤,比如反转链表的三个指针移动,或者哈希表的冲突处理方式。 同时,要注意代码的健壮性,比如处理空指针,释放内存,避免内存泄漏,这在C语言中尤为重要。 最后,总结部分要指出每个题目考察的知识点,帮助用户理解这些题目的目的,比如链表题考察指针操作,二叉树题考察递归和遍历,哈希表考察数据结构设计能力等。 可能还需要检查是否有重复的考察点,确保覆盖不同的数据结构和算法,比如链表、栈、队列、树、哈希表、堆、图等,每个至少有一道题目。 现在把这些整理成结构化的题目和答案,确保清晰易懂,代码正确,注释到位,同时用中文回答,符合用户的要求。</think>以下是几道典型的C语言数据结构面试题及参考答案,涵盖链表、树、栈、队列等核心内容: --- ### **题目1:反转单链表** **要求**:用C语言实现单链表的反转(递归和迭代两种方法)。 **参考答案**: ```c // 链表节点定义 typedef struct Node { int data; struct Node* next; } Node; // 迭代法 Node* reverse_iterative(Node* head) { Node *prev = NULL, *curr = head, *next = NULL; while (curr != NULL) { next = curr->next; // 保存下一个节点 curr->next = prev; // 反转指针 prev = curr; // 前移prev curr = next; // 前移curr } return prev; // 新头节点 } // 递归法 Node* reverse_recursive(Node* head) { if (head == NULL || head->next == NULL) return head; Node* new_head = reverse_recursive(head->next); head->next->next = head; // 反转指向 head->next = NULL; // 断开原指针 return new_head; } ``` --- ### **题目2:用栈实现队列** **要求**:使用两个栈模拟队列的入队(`enqueue`)和出队(`dequeue`)操作。 **参考答案**: ```c typedef struct { int top; int data[100]; } Stack; typedef struct { Stack s1; // 主栈(入队用) Stack s2; // 辅助栈(出队用) } MyQueue; void enqueue(MyQueue* q, int val) { // 直接压入s1 q->s1.data[++q->s1.top] = val; } int dequeue(MyQueue* q) { // 若s2为空,将s1所有元素倒入s2 if (q->s2.top == -1) { while (q->s1.top != -1) { int val = q->s1.data[q->s1.top--]; q->s2.data[++q->s2.top] = val; } } // 弹出s2栈顶 return q->s2.data[q->s2.top--]; } ``` --- ### **题目3:验证二叉搜索树(BST)** **要求**:判断一棵二叉树是否为合法的二叉搜索树(左子树所有节点值 < 根节点值 < 右子树所有节点值)。 **参考答案**: ```c typedef struct TreeNode { int val; struct TreeNode* left; struct TreeNode* right; } TreeNode; // 辅助函数
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值