====== 某公司笔试题 ====== 2018-04-12 9:00去某公司面试,记录4道笔试题 ===== linux查看系统编码 ===== 命令: locale 输出: LANG="zh_CN.UTF-8" LC_COLLATE="zh_CN.UTF-8" LC_CTYPE="zh_CN.UTF-8" LC_MESSAGES="zh_CN.UTF-8" LC_MONETARY="zh_CN.UTF-8" LC_NUMERIC="zh_CN.UTF-8" LC_TIME="zh_CN.UTF-8" LC_ALL= ===== 什么是闭包 ===== 闭包,指的是一个拥有许多变量和绑定了这些变量的环境的表达式(通常是一个函数),因而这些变量也是该表达式的一部分。 通俗的讲:就是函数a的内部函数b,被函数a外部的一个变量引用的时候,就创建了一个闭包。 function a(){ var i=0; function b(){ alert(++i); } return b; } var c = a(); c(); ===== 原生js实现ajax ===== 访问demo:http://www.recorddrip.com/testajax.html ===== 并发编程 ===== 实现逻辑:n个线程并发,按顺序打印1,2,3...,n,n+1,n+2,...,2n,2n+1,2n+2... ==== 解法1 ==== 使用ReentrantLock condition await signalAll搞定 === PrintObject.java === package com.gxx.record.gtja; import java.util.ArrayList; import java.util.List; import java.util.concurrent.locks.Condition; import java.util.concurrent.locks.Lock; import java.util.concurrent.locks.ReentrantLock; /** * 打印对象 * 逻辑:多线程按顺序打印1,2,3...,n,n+1,n+2,...,2n,2n+1,2n+2... * @author Gxx */ public class PrintObject { /** * 锁 */ private Lock lock = new ReentrantLock(); /** * 条件 */ private List conditionList = new ArrayList(); /** * 打印索引,从1,2,3...n,1,2,3... */ private int index = 1; /** * 线程数 */ private int n; /** * 轮次 */ private int k = 0; /** * 构造方法 * @param num */ public PrintObject(int num) { for(int i=0;i n) { index = 1; } Thread.sleep(100); conditionList.get(index - 1).signal();//唤醒 } catch(Exception e) { e.printStackTrace(); } finally { lock.unlock();//释放锁 } } } === MyThread.java === package com.gxx.record.gtja; /** * 线程 * @author Gxx */ public class MyThread extends Thread { /** * 索引 */ int i; /** * 打印对象 */ PrintObject printObject; /** * 构造方法 * @param i 索引 * @param printObject 打印对象 */ public MyThread(int i, PrintObject printObject) { this.i = i; this.printObject = printObject; } @Override public void run() { while(true) { printObject.print(i); } } } === Main.java === package com.gxx.record.gtja; import java.io.BufferedReader; import java.io.InputStreamReader; /** * 入口 * @author Gxx */ public class Main { /** * 入口 * @param param */ public static void main(String[] param) throws Exception { /** * 录入数字 */ System.out.println("请录入数字:"); BufferedReader bufferedReader = new BufferedReader( new InputStreamReader(System.in)); int num = Integer.parseInt(bufferedReader.readLine()); /** * 构建打印对象 */ PrintObject printObject = new PrintObject(num); System.out.println("打印结果:"); /** * 创建并启动线程 */ for(int i=0;i 输出结果: 请录入数字: 5 打印结果: 1,2,3,4,5,1,2,3,4,5,1,2,3,4,5,1,2,3,4,5,1,2,3,4,5,1,2,3,4,5, ==== 解法2 ==== 使用wait notifyAll搞定 === LockObject.java === package com.gxx.test; /** * 锁对象 */ public class LockObject { //计数 int count; } === MyThread.java === package com.gxx.test; /** * 线程 */ public class MyThread extends Thread { int index;//索引 LockObject lockObject;//锁对象 int threadCount;//线程总数 /** * 构造方法 * @param index * @param lockObject * @param threadCount */ public MyThread(int index, LockObject lockObject, int threadCount) { this.index = index; this.lockObject = lockObject; this.threadCount = threadCount; } @Override public void run() { /** * 锁,只有一个线程进入 */ synchronized (lockObject) { while (true) { try { if (lockObject.count % threadCount == index) { System.out.println((lockObject.count+1) + ","); Thread.sleep(100); lockObject.count ++; /** * 唤起wait的线程 */ lockObject.notifyAll(); } else { /** * 释放锁 */ lockObject.wait(); } } catch (Exception e) { e.printStackTrace(); } } } } } === PrintThreadTest.java === package com.gxx.test; /** * 多线程打印测试 */ public class PrintThreadTest { /** * main方法 * @param args * @throws Exception */ public static void main(String[] args) throws Exception { /** * 锁对象 */ LockObject lockObject = new LockObject(); /** * 线程总数 */ int threadCount = 5; for(int i=0;i === 输出 === 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, ...