空中网 php 面试,空中网多线程面试题

1. 空中网面试题1

package com.kongzhongwang.interview;

import java.util.concurrent.ArrayBlockingQueue;

import java.util.concurrent.BlockingQueue;

//myeclipse强大功能:将代码直接复制到项目的src路径下可以自动相应生成包名和类名

/**

*

*    空中网面试题1:现有程序代码模拟产生16个日志对象,并且需要运行16秒才能打印完这些日志,请在程序中增加四个线程去调用

* parseLog()方法来分头打印这16个日志对象,程序只需运行4秒即可打印完这些日志对象。

* 考察新技术BlockingQueue

*/

public class ReadLog {

public static void main(String[] args) {

/*此处有一个巧合:这里ArrayBlockingQueue(1)和ArrayBlockingQueue(16)

* 达到的效果一样,并且前者产生的数据组合更整齐;目前推测是巧合,希望大牛发现因果了告知一声

*/

final BlockingQueue queue = new ArrayBlockingQueue(1);

for (int i = 0; i 

new Thread(new Runnable() {

public void run() {

while (true) {

try {

String log = queue.take();

parseLog(log);

} catch (InterruptedException e) {

e.printStackTrace();

}

}

}

}).start();

}

System.out.println("begin:" + (System.currentTimeMillis() / 1000));

/*

* 模拟处理16个日志,下面代码产生了16个日志对象;当前代码需要运行16秒才能打印完成这些日志对象;

* 修改程序代码,开四个线程让16个对象在4秒内打完

*/

for (int i = 0; i 

final String log = "" + (i + 1); // 这行代码不能改动

{

// ReadLog.parseLog(log);

try {

queue.put(log);

} catch (InterruptedException e) {

e.printStackTrace();

}

}

}

}

// parseLog内部代码不能动

public static void parseLog(String log) {

System.out.println(log + ":" + System.currentTimeMillis() / 1000);

try {

Thread.sleep(1000);

} catch (InterruptedException e) {

e.printStackTrace();

}

}

}

2. 空中网面试题2

package com.kongzhongwang.interview;

import java.util.concurrent.Semaphore;

import java.util.concurrent.SynchronousQueue;

/**

*    空中网面试题2: 现成程序中的Test类中的代码在不断地产生数据,然后交给TestDo.doSome()方法去处理;

* 这就好像是生产者在不断地产生数据,消费者在不断地消费数据。请将程序改造成有10个线程来消费生产者产生的数据,

* 这些消费者都调用TestDo.doSome()方法去处理,固每个消费者都需要1秒才能处理完,程序应该保证这些

* 消费者线程依次有序的消费数据,只有上一个消费者消费完后,下一个消费者才能消费数据,下一个消费者是谁都可以, 但要保证消费者拿到的数据是有顺序的。

*/

public class Test {

public static void main(String[] args) {

//使用semaphore信号灯相当于上一个lock锁

final Semaphore semaphore = new Semaphore(1);

//新的队列方式

final SynchronousQueue queue = new SynchronousQueue();

for(int i=0;i<10;i++){

new Thread(new Runnable() {

@Override

public void run() {

try {

semaphore.acquire();

String input = queue.take();

String output = TestDo.doSome(input);

System.out.println(Thread.currentThread().getName() + ":" + output);

semaphore.release();

} catch (InterruptedException e) {

e.printStackTrace();

}

}

}).start();

}

System.out.println("begin:" + (System.currentTimeMillis() / 1000));

for (int i = 0; i 

String input = i + ""; // 这行代码不能改动

try {

queue.put(input);

} catch (InterruptedException e) {

e.printStackTrace();

}

}

}

}

// TestDo类不能动

class TestDo {

public static String doSome(String input) {

try {

Thread.sleep(1000);

} catch (Exception e) {

e.printStackTrace();

}

String output = input + ":" + (System.currentTimeMillis() / 1000);

return output;

}

}

3.空中网面试题3

package com.kongzhongwang.interview;

import java.util.ArrayList;

import java.util.Iterator;

import java.util.concurrent.CopyOnWriteArrayList;

public class Tests extends Thread {

/**

* 空中网面试题3: 现有程序同时启动了四个线程去调用TestDo.doSome(key,value)方法;

* 由于TestsDo.doSome(key,value)方法内的代码是先暂停1秒,然后再输出以秒为单位的当前时间值,

* 所以会打印出四个相同的时间值,如下所示:4:4 1258199615 1:1 1258199615 3:3 1258199615 2:2

* 1258199615 ;请修改代码,如果有几个线程调用TestDo.doSome(key,value)方法时;

* 传递进去的key值相等(equals比较为true),则这几个线程应互斥输出结果,即当有两个线程的key都为1时,

* 它们中的一个要比其他线程晚一步输出结果,如下所示:4:4 1258199615 1:1 1258199615 3:3 1258199615 1:2

* 1258199616 ;总之每个线程中指定的key相等时;这些相等的线程应每隔1秒输出时间值(要用互斥),

* key不同,则并行执行(相互之间不互斥)

*/

private TestsDo testDo;

private String key;

private String value;

private Tests(String key, String key2, String value) {

this.testDo = TestsDo.getInstance();

/*

* 常量“1”和“1”是同一个对象,下面这行代码就是要用“1”+“”的方式产生新的对象;

* 以实现内容没有改变,仍然相等(都还为“1”),但对象却不再是同一个的效果

*/

this.key = key + key2;

/*

* a = "1"+"";

* b = "2"+"";

* a和b是同一个对象,因为编译器在执行之前就会将其优化为 a=“1”;

* 但是this.key = key + key2;这句,编译器不会给你优化,

* 因为你是属性变量,编译器不知道你将来要传入什么值

*/

this.value = value;

}

public static void main(String[] args) {

Tests a = new Tests("1", "", "1");

Tests b = new Tests("1", "", "2");

Tests c = new Tests("3", "", "3");

Tests d = new Tests("4", "", "4");

System.out.println("begin:" + (System.currentTimeMillis() / 1000));

a.start();

b.start();

c.start();

d.start();

}

public void run() {

testDo.doSome(key, value);

}

}

class TestsDo {

private TestsDo() {}

private static TestsDo _instance = new TestsDo();

public static TestsDo getInstance() {

return _instance;

}

//传统写法,没有考虑到线程并发问题

//  private ArrayList keys = new ArrayList();

private CopyOnWriteArrayList keys = new CopyOnWriteArrayList();

public void doSome(Object key,String value){

Object o = key;

if(! keys.contains(o)){

keys.add(o);

}else{

//迭代的过程中不能进行其他操作;

for(Iterator iter = keys.iterator();iter.hasNext();){

/*这里的休眠作用:为了让大家看到,使用传统的private ArrayList keys = new ArrayList();

* 会导致Exception in thread "Thread-1" java.util.ConcurrentModificationException异常

* 因为迭代的过程中不能进行其他操作;你非要在迭代的时候向其中添加数据就会导致这种异常,而且在迭代中放入休眠这种错误百发百中。

*/

try {

Thread.sleep(20);

} catch (InterruptedException e) {

e.printStackTrace();

}

Object oo = iter.next();

if(o.equals(oo)){

o = oo;

}

}

}

//这里为了区别是不同对象,所以不能直接使用synchronized(key)

synchronized(o)

//大括号内的是需要同步的代码,不能改动

{

try{

Thread.sleep(1000);

System.out.println(key+":"+value+":" + (System.currentTimeMillis() / 1000));

}catch(Exception e){

e.printStackTrace();

}

}

}

}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值