程序師世界是廣大編程愛好者互助、分享、學習的平台,程序師世界有你更精彩!
首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫知識
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
 程式師世界 >> 編程語言 >> JAVA編程 >> 關於JAVA >> JAVA面試題

JAVA面試題

編輯:關於JAVA

JAVA面試題。本站提示廣大學習愛好者:(JAVA面試題)文章只能為提供參考,不一定能成為您想要的結果。以下是JAVA面試題正文


在這裡我將收錄我面試進程中遇到的一些好玩的面試標題

第一個面試題:ABC問題,有三個線程,任務的內容辨別是打印出“A”“B”“C”,需求做的就是讓他們順序的輸入ABC  例如:ABCABCABCABC

思緒一:我覺得這個功用是需求封裝的,而且可以做到,無論多少個線程都可以順序打印出來,並且根本上不需求改任何代碼。我的思緒是首先封裝一個任務的單元為Node,次要的任務就是打印和競爭鎖並且記載參加任務的索引,然後還有一個ConcurrentHashMap貯存任務形態。假如全部任務完了之後,由最後一個任務單元刷新形態。上面是完成的代碼:

package com.hotusm.concurrent.test;

import java.util.Map;
import java.util.TreeMap;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReentrantLock;

/**
 * Created by luqibao on 2016/12/30.
 */
public class ABCSample {

    private static ReentrantLock lock=new ReentrantLock();

    private static volatile TreeMap<Integer,Node> indexs=new TreeMap<>();

    public static void main(String[] args){
        ReentrantLock lock=new ReentrantLock();
        TreeMap<Integer,Node> indexs=new TreeMap<>();
        Node node1=new Node("A",lock,indexs,0);
        Node node2=new Node("B",lock,indexs,1);
        Node node3= new Node("C",lock,indexs,2);
        indexs.put(0,node1);
        indexs.put(1,node2);
        indexs.put(2,node3);

        node1.beforeWork();
        node2.beforeWork();
        node3.beforeWork();


        try{
            TimeUnit.SECONDS.sleep(3);
        }catch (Exception e){

            e.printStackTrace();
        }

        node1.start();
        node2.start();
        node3.start();

        synchronized (ABCSample.class){

            try{
                ABCSample.class.wait();
            }catch (Exception e){
                e.printStackTrace();
            }

        }

    }

    private static class WorkQueue{

        private Node tail;
        private Node head;
    }

    private static class Node extends Thread{

        private static volatile boolean isRefresh=false;

        private volatile Map<Integer,Node> maps;
        private volatile boolean isWorked=false;
        private final int index; //索引

        private String message;
        private volatile Lock readLock;
        private boolean isLast=false;

        public Node(String message,Lock lock,Map<Integer,Node> maps,int index){
            this.message=message;
            this.readLock=lock;
            this.maps=maps;
            this.index=index;
        }

        public int getIndex() {
            return index;
        }

        public void beforeWork(){

            readLock.lock();
            try{
                if(index==maps.size()-1){
                    isLast=true;
                }else{
                    isLast=false;
                }
            }finally {
                readLock.unlock();
            }

        }
        @Override
        public void run() {
            while (true){
                readLock.lock();
                if(isRefresh){continue;}
                try{
                    if(this.index==0&&!this.isWorked){
                        System.out.print(this.message);
                        this.isWorked=true;
                    }else if(index!=0){
                        Node node= maps.get(index-1);
                        if(!node.isWorked){
                            System.out.print(node.message);
                            node.isWorked=true;
                        }else{
                            if(!this.isWorked){
                                System.out.print(this.message);
                                this.isWorked=true;
                            }else if(this.isWorked&&this.isLast){
                                refresh();
                            }
                        }
                    }
                }catch (Exception e){
                    Thread.currentThread().interrupt();
                    e.printStackTrace();
                }finally {
                    readLock.unlock();
                }

                try{
                    TimeUnit.SECONDS.sleep(1);
                }catch (Exception e){
                    e.printStackTrace();
                }

            }
        }

        private void refresh(){
            isRefresh=true;
            for(Map.Entry<Integer,Node> map:maps.entrySet()){
                map.getValue().isWorked=false;
            }
            isRefresh=false;
        }
    }
}

其實下面還有很多封裝的中央,注冊可以封裝成辦法,前置任務也是,可以用一個volatile修飾的boolean來標志,同理啟動也是一樣的,假如可以的話,最好能做到,運用的時分只需求調用一個register(msg) 和start()就可以了

思緒二:由於這是一個環形鏈接構造,所以我們可以告訴將鎖從head開端不斷往後讓其他獲取一遍,上面代碼:

package com.hotusm.concurrent.test;

import sun.misc.Unsafe;

import java.lang.reflect.Field;
import java.util.concurrent.CountDownLatch;

/**
 * Created by luqibao on 2017/1/3.
 */
public class ABCSample2 {


    public static void main(String[] args){

       WorkQueue queue= new WorkQueue();
       queue.addWork("A");
       queue.addWork("B");
       queue.addWork("C");
       queue.addWork("D");
       queue.addWork("E");

       queue.startWork();


        synchronized (ABCSample2.class){

            try{
                ABCSample2.class.wait();
            }catch (Exception e){
                e.printStackTrace();
            }

        }
    }
    private static class WorkQueue{

        private Node head;
        private Node tail;
        private int num=0;

        private static final Unsafe unsafe = getUnsafe();
        private static final long tailOffset;
        private static final long headOffset;

        static {
            try {
                // 獲取以後字段的內存地位  後來交換的中央需求運用
                headOffset = unsafe.objectFieldOffset
                        (WorkQueue.class.getDeclaredField("head"));
                tailOffset = unsafe.objectFieldOffset
                        (WorkQueue.class.getDeclaredField("tail"));
            } catch (Exception ex) { throw new Error(ex); }
        }

        private static Unsafe getUnsafe() {
            try {

                Field singleoneInstanceField = Unsafe.class.getDeclaredField("theUnsafe");
                singleoneInstanceField.setAccessible(true);
                return (Unsafe) singleoneInstanceField.get(null);

        } catch (Exception e) {
                throw new RuntimeException(e);
            }
        }

        protected void push(Node node){

            for (;;) {
                Node t = tail;
                if (t == null) {
                    if (compareAndSetHead(node))
                        num++;
                    tail = head;
                    break;
                } else {
                    if (compareAndSetTail(t, node)) {
                        num++;
                        t.next = node;
                        break;
                    }
                }
            }
        }

        /**
         *參加任務的順序就是打印的順序
         * @param message  打印的信息
         */
       public void addWork(String message){
            Node node=new Node(message);
            push(node);
        }

        /**
         * 開端停止任務
         */
        public void startWork(){
            Node.head=this.head;
            Node.tail=tail;
            Node.latch=new CountDownLatch(num);
            Node.currentWork=head;

            for (Node node=head;node!=null;node=node.next){
                node.start();
                Node.latch.countDown();
            }
        }


        public boolean compareAndSetTail(Node expect,Node newValue){
            return unsafe.compareAndSwapObject(this,tailOffset,expect,newValue);
        }
        public boolean compareAndSetHead(Node expect){
            return unsafe.compareAndSwapObject(this,headOffset,null,expect);
        }

    }


    private static class Node extends Thread{

        private static volatile Node currentWork;

        private static volatile Node head;
        private static volatile Node tail;
        private static volatile CountDownLatch latch;

        private String message;
        private Node next;


        public Node(String message) {
            this.message = message;
        }

        @Override
        public void run() {

            try {
                latch.await();
            }catch (Exception e){
                e.printStackTrace();
            }
            for(;;){
                if(currentWork==this){
                    if(!"".equals(message)){
                        System.out.print(message);
                    }
                    if(this==tail){
                        currentWork=head;
                    }else{
                        currentWork=this.next;
                    }
                }
            }

        }
    }
}

總的來說,我還是比擬喜歡前面這種的,但是還是需求優化,比方在啟動之後就不可以添加任務了,驗證任務不能反復等等。

第二個面試題:

詳細標題如下,

-         Java開發

-         功用要求:

o   網絡爬蟲,可以運用大批的3方庫,但是最好可以用自己寫的代碼

o   加分點:運用多線程,留意同步和鎖

o   將豆瓣(book.douban.com)裡的關於“互聯網,編程,算法”方面的書籍數據抓上去,並且顯示評分最高的前100本數據(要求評價人數超越2000,缺乏2000的就提取前100)

o   代碼和爬下的後果(excel文件)一並放在github裡,鏈接發給你們,再轉給我。

這個面試題是一家500強的外企的標題,由於之前不斷沒有接觸過爬蟲方面,所以覺得比擬有意思,代碼在我們的github下面:https://github.com/Housum/crawl.git。

由於事先時間比擬緊(白晝在項目),原本是想自己寫網絡和解析的,但是沒時間,所以用的都是第三方的,反而覺得除了鎖,其他的都是第三方框架的東西。面試官評價還行。

  1. 上一頁:
  2. 下一頁:
Copyright © 程式師世界 All Rights Reserved