最近面试了几家公司,发现大部分公司面试题有相似的地方。现在此记录下我还记得的一些题:
JAVA部分:
1.Java Map 按Key排序和按Value排序:
2.从一个文件中统计每个单词的次数,排序输出:
package com.test.string; import java.io.BufferedReader;
import java.io.BufferedWriter;
import java.io.FileReader;
import java.io.FileWriter;
import java.io.IOException;
import java.util.ArrayList;
import java.util.Collections;
import java.util.Comparator;
import java.util.List;
import java.util.Map;
import java.util.TreeMap;
import java.util.Map.Entry;
import java.util.regex.Matcher;
import java.util.regex.Pattern; /**
* java实现读取英文文章,统计其中每个单词出现的次数并输出
* @author halbert
*
*/
public class FileWordCount { public void count() throws IOException{
BufferedReader reader = new BufferedReader(new FileReader("D:\\test\\english.txt"));
StringBuffer buffer = new StringBuffer();
String line = null;
while( (line = reader.readLine()) != null ){
buffer.append(line);
}
reader.close();
Pattern expression = Pattern.compile("[a-zA-Z]+"); //定义正则表达式匹配单词
String string = buffer.toString();
Matcher matcher = expression.matcher(string);
Map<string integer=""> map = new TreeMap<string integer="">();
String word = "";
int n = 0;
Integer times = 0;
while(matcher.find()){ //是否匹配单词
word = matcher.group(); //得到一个单词,树映射中的键
n++;
if( map.containsKey(word) ){ //如果该键存在,则表示单词出现过
times = map.get(word); //得到单词出现的次数
map.put(word, times+1);
} else {
map.put(word, 1); //否则单词是第一次出现,直接放入map
}
}
List<Map.Entry<string integer="">> list = new ArrayList<Map.Entry<string integer="">>(map.entrySet());
Comparator<Map.Entry<string integer="">> comparator = new Comparator<Map.Entry<string integer="">>(){ @Override
public int compare(Entry<string integer=""> left, Entry<string integer=""> right) {
return (left.getValue()).compareTo(right.getValue());
} };
Collections.sort(list, comparator);
System.out.println("统计分析如下:");
System.out.println("t 文章中单词总数" + n + "个");
System.out.println("具体的信息在原文件目录的result.txt文件中");
BufferedWriter bufw = new BufferedWriter(new FileWriter("D:\\test\\result.txt"));
for(Entry<string integer=""> me : list){
bufw.write(me+"");
bufw.newLine();
}
bufw.write("english.txt中的单词总数" + n + "个");
bufw.newLine();
bufw.write("english.txt中不同单词" + map.size() + "个");
bufw.close();
} public static void main(String[] args) {
try {
FileWordCount fwc = new FileWordCount();
fwc.count();
} catch (IOException e) {
e.printStackTrace();
} } }
参考链接:java程序员的从0到1:统计某字符串在某文件中出现的次数(面试题)
3.手写arraylist:
参考链接:java面试题答疑(手写arraylist、进制转换、多线程、动态代理)
4.手写一把可重入锁:
public class MyLock implements Lock { private boolean isLocked = false; //定义一个变量,标记锁是否被使用 private Thread runningThread = null; //第一次线程进来的时候,正在运行的线程为null private int count = 0; //计数器 @Override
public synchronized void lock() {
Thread currentThread = Thread.currentThread();
//不断的重复判断,isLocked是否被使用,如果已经被占用,则让新进来想尝试获取锁的线程等待,直到被正在运行的线程唤醒
//除了判断当前锁是否被占用之外,还要判断正在占用该锁的是不是本线程自己
while(isLocked && currentThread != runningThread) { //如果锁已经被占用,而占用者又是自己,则不进入while循环
try {
wait();
}catch (InterruptedException e) {
e.printStackTrace();
}
}
//进入该代码块有三种情况:
// 1.第一个线程进来,此时isLocked变量的值为false,线程没有进入while循环体里面
// 2.线程进入那个循环体里面,调用了wait()方法并经历了等待阶段,现在已经被另一个线程唤醒,
// 3.线程不是第一次进来,但是新进来的线程就是正在运行的线程,则直接来到这个代码块
// 唤醒它的线程将那个变量isLocked设置为true,该线程才跳出了while循环体 //跳出while循环体,本线程做的第一件事就是赶紧占用线程,并告诉其他线程说:嘿,哥们,我占用了,你必须等待,计数器+1,并设置runningThread的值
isLocked = true; //将isLocked变量设置为true,表示本线程已经占用
runningThread = currentThread; //给正在运行的线程变量赋值
count++; //计数器自增
} @Override
public void lockInterruptibly() throws InterruptedException { } @Override
public boolean tryLock() {
return false;
} @Override
public boolean tryLock(long time, TimeUnit unit) throws InterruptedException {
return false;
} @Override
public synchronized void unlock() {
//线程释放锁,释放锁的过程分为三步
//1. 判断发出释放锁的请求是否是当前线程
//2. 判断计数器是否归零,也就是说,判断本线程自己进来了多少次,是不是全释放锁了
//3. 还原标志变量
if(runningThread == Thread.currentThread()) {
count--;//计数器自减
if(count == 0) { //判断是否归零
isLocked = false; //将锁的状态标志为未占用
runningThread = null; //既然已经真正释放了锁,正在运行的线程则为null
notifyAll(); //通知所有等待的线程,谁抢到我不管
}
}
} @Override
public Condition newCondition() {
return null;
}
}
---------------------
作者:SpringChang
来源:CSDN
原文:https://blog.csdn.net/zhang5476499/article/details/83794711
版权声明:本文为博主原创文章,转载请附上博文链接!
参考链接:Java并发编程:自己动手写一把可重入锁
5.说几个JAVA中的单例模式,然后你最喜欢用哪个?为什么?
饿汉式和懒汉式。
//第一种形式: 饿汉式单例类
//饿汉式单例类.在类初始化时,已经自行实例化
public class Singleton {
private Singleton(){}
private static Singleton instance = new Singleton();
public static Singleton getInstance() {
return instance;
}
}
//第二种形式:懒汉式单例类
public class Singleton {
private Singleton(){}
private static Singleton instance = null;
public static synchronized Singleton getInstance() {
if (instance==null)instance=new Singleton();
return instance;
} }
第一种形式要更加安全些
instance = new Singleton();
static属于类的资源,类资源在jvm加载类的时候就加载好了,instance一直引用这new Singleton(),所以永远都不会释放一直存在与内存中直到程序结束运行;
第2种的话如果两个线程同一时刻去访问getInstance的时候就可能创建两个实例,所以不安全;
解决办法(加上同步锁)。
参考链接:快速理解Java中的五种单例模式
6.说说你对Java中的栈内存和堆内存的看法:
参考链接:JAVA面试、进阶必备——堆内存与栈内存
7.http在传输时是无状态的,你是如何解决的:
可以使用Cookie来解决无状态的问题,Cookie就相当于一个通行证,第一次访问的时候给客户端发送一个Cookie,当客户端再次来的时候,拿着Cookie(通行证),那么服务器就知道这个是”老用户“。
参考链接:Java面试之http知识点(必问) HTTP面试题都在这里
8.设计一个秒杀系统
参考链接:如何设计一个秒杀系统 秒杀系统设计(JAVA)
9.设计一个大数据高并发系统
秒杀系统和高并发系统均有视频,百度云链接:
链接: https://pan.baidu.com/s/1ooQaputdmsoHm9qT-PyXRw 提取码: 686e
.NET部分:
其实C#和Java中大部分语法类似,故就算只想走Java部分题也有参考价值。
1.面向对象的三个特性,请简述。
封装:将对象中的方法,属性隐藏起来。外届程序调用对象的方法,只能通过对象提供给外部的接口来调用。这样可以可以让人忽略代码的具体细节实现,使代码更易维护。同时因为不能直接调用、修改对象内部的私有属性,在一定程度上保证了系统安全性。
继承:主要用于代码复用,将多次使用的公共代码提取出来,以达到提高编码效率目的。
多态:所谓的多态是指在继承体系中,所有派生类都从基类继承接口,但由于每个派生类都是独立的实体,因此在接收同一消息的时候,可能会生成不同的响应。多态的作用作为隐藏代码实现细节,使得代码能够模块化;扩展代码模块,实现接口重用。
2.用.net做B/S结构的系统,您是用几层结构来开发,每一层之间的关系以及为什么要这样分层?
三层。从下至上分别为:数据访问层、业务逻辑层(又或成为领域层)、表示层;
数据访问层:有时候也称为是持久层,其功能主要是负责数据库的增删查改操作;
业务逻辑层:是整个系统的核心,它与这个系统的业务(领域)有关
表示层:是系统的UI部分,负责使用者与整个系统的交互。
优点: 分工明确,条理清晰,易于调试,而且具有可扩展性。
缺点: 增加成本。
3.列举ASP.NET 页面之间传递值的几种方式。
有页面传值、存储对象传值、ajax、类、model、表单等。但是一般来说,常用的较简单有QueryString,Session,Cookies,Application,Server.Transfer。
QueryString 传递一个或多个安全性要求不高或是结构简单的数值。但是对于传递数组或对象的话,就不能用这个方法了
session(viewstate) 简单,但易丢失 作用于用户个人,过量的存储会导致服务器内存资源的耗尽。
application 对象的作用范围是整个全局,也就是说对所有用户都有效。其常用的方法用Lock和UnLock
cookie 简单,但可能不支持,可能被伪造 Cookie是存放在客户端的,而session是存放在服务器端的。而且Cookie的使用要配合ASP.NET内置对象Request来使用 input ttype="hidden" 简单,可能被伪造 url参数简单,显示于地址栏,长度有限
Server.Transfer 把流程从当前页面引导到另一个页面中,新的页面使用前一个页面的应答流 数据库稳定,安全,但性能相对弱
参考链接:ASP.NET页面之间传递值的几种方式
4.事件和委托的区别
事件是委托的封装,可以理解为一种特殊的委托。
事件里面其实就两个方法(即add_event()和remove_event())和一个私有的委托变量,这两个方法里面分别是对这个私有的委托变量进行的合并和移除,当调用事件的+=时其实是调用的事件里面的add_event()方法,同样-=调用的是remove_event()方法。
事件只能够从对象外部增加新的响应方法和删除已知的响应方法,而不能主动去触发事件和获取其他注册的响应方法等信息。如果使用公有的delegate则不能做这些限制,也就是说事件对委托做了限制,使委托使用起来更加方便。也有人说事件是对委托的阉割,大概也是这个意思。
5.C#中的接口和类有什么异同
异:
不能直接实例化接口。
接口不包含方法的实现。
接口、类和结构可从多个接口继承。但是C# 只支持单继承:类只能从一个基类继承实现。
类定义可在不同的源文件之间进行拆分。
同:
接口、类和结构可从多个接口继承。
接口类似于抽象基类:继承接口的任何非抽象类型都必须实现接口的所有成员。
接口可以包含事件、索引器、方法和属性。
一个类可以实现多个接口。
6.SQL注入是什么意思以及防止SQL注入:
参考链接:sql注入是什么意思以及防止sql注入?
SQL:
1. 取出表A中第31到第40记录:
1、假设ID是连续的:
select top 10 * from A where ID not in (select top 30 ID from A)
或
select * from A where ID between 31 and 40
2、假设ID是不连续的:
select top 40 * from A except select top 30 * from A
或
select top 10 * from A where ID > (select max(ID) from A where ID in (select top 30 ID from A))
或
select top 10 * from A where ID not in (select top 30 ID from A)
2.
原表:
courseid coursename score
-------------------------------------
1 java 70
2 oracle 90
3 xml 40
4 jsp 30
5 servlet 80
-------------------------------------
为了便于阅读,查询此表后的结果显式如下(及格分数为60):
courseid coursename score mark
---------------------------------------------------
1 java 70 pass
2 oracle 90 pass
3 xml 40 fail
4 jsp 30 fail
5 servlet 80 pass
---------------------------------------------------
写出此查询语句
---------------------
select courseid, coursename ,score ,decode(sign(score-60),-1,'fail','pass') as mark from course
sql题练习链接:https://blog.csdn.net/qq_30946681/article/details/80233652