java实习面试题整理
栈是为函数中基本类型的变量和对象的引用变量分配内存,是由系统自动分配,获得的空间比较小,但是速度会比 较快,储存空间是连续的。
堆是为函数创建的对象分配内存,通常是使用new关键字来实现的,是人为申请开辟,获得的空间比较大,但是速 度会比较,储存空间是不连续的。
1)对于==,比较的是值是否相等
如果作用于基本数据类型的变量,则直接比较其存储的 “值”是否相等;
如果作用于引用类型的变量,则比较的是所指向的对象的地址
2)对于equals方法,注意:equals方法不能作用于基本数据类型的变量,equals继承Object类,比较的是是否是 同一个对象,如果没有对equals方法进行重写,则比较的是引用类型的变量所指向的对象的地址;
例如String、Date等类对equals方法进行了重写的话,比较的是所指向的对象的内容。
throw:就是自己处理一个异常,通常使用try…catch代码块捕获处理异常
throws:不对异常做任何处理而是将异常往上传,谁调用我我就抛给谁
cookie不是很安全,它的数据是存放在客户的浏览器上,单个cookie保存的数据不能超过4K。
session比较安全,它会在一定时间内保存在服务器上,但是当访问增多,会比较占用服务器的性能,所以考虑到减 轻服务器性能方面,应当使用cookie。
1)final用于声明属性方法和类,分别表示属性不可变,方法不可覆盖,类不可继承。
修饰变量:该属性一定要有初始值,要么在定义时马上初始化,要么在构造器中初始化。
该变量指向基本类型后该引用为常量,不能修改。
指向对象后,对象的引用不可变,但是对象的内容可变。
修饰方法:该方法无法被子类重写,但是可以被继承。
修饰类:该类无法被继承。比如java.lang.String类就是final类。
2)finally是异常处理语句结构的一部分,表示总是执行,一定会执行。如果try里有一个return语句,会在return前执行finally中的代码。
3)finalize是Object类的方法,执行gc时会调用此方法,可以覆盖此方法提供垃圾收集时其他资源的回收,比如关闭文件等。
两个对象存在继承关系,子类重写父类的方法,然后父类的引用指向子类的对象,可以调用父类中的所有成员,不能调用子类中特有成员。
概念:接口是抽象类的特殊化,是抽象方法与常量的集合,不能被实例化,但可以作为接口变量进行声明(实例化为一个具体子类),一个类可以同时实现多个接口,接口可以弥补抽象类不能多继承的缺陷。接口不允许被接口实现,但允许被接口继承。
特性:接口中的属性是常量,默认有且只能是public static final。接口中的方法默认有且只能是public abstract.
内部类的概念:内部类就是写在类或者方法中的类,他只为这个外部类所用。
内部类的优点:防止类重名,实现多继承。
内部类只能间接通过访问外部类的方法来实例化内部类。
内部类可以隐藏你不想让别人知道的操作,实现代码的封装性。
内部类可以直接使用外部类的私有和保护属性,方便实用。
内部类可以减少开发类的数量。
Static
可以用来修饰代码块,成员变量和成员方法,被 static 修饰的成员属于类,而不属于这个类的某个对象,被类中所有对象共享,可以建议通过类名调用,这些静态变量是存放在 Java 内存区域的方法区里。还有一种特殊用法是用static修饰内部类,普通类是不允许声明为静态的,只有内部类才可以,被static修饰的内部类可以直接作为一个普通类来使用,而不需实例一个外部类
This
This指的是当前对象本身,哪个对象调用,this就代表哪个对象。可以用来访问本类的属性,方法,构造器,也可以用来区分局部变量和全局变量,访问构造器的话只能在构造器中使用而且必须放在第一个语句。
Super
super代表父类的引用,用于访问父类的属性、方法、构造器,访问构造器的话只能也只能放在构造器的第一句,主要用于子类和父类的属性和方法同名的情况下想直接调用父类的属性方法。
1.首先,他们的底层数据结构不同,ArrayList底层是基于数组实现的,LinkedList底层是基于链表实现的
2.由于底层数据结构不同,他们所适用的场景也不同,Arraylist更适合随机查找,LinkedList更适合删除和添加
3.另外Arraylist和LinkedList都实现了List接口,但是LinkedList还额外实现了Deque接口,所以LinkedList还可以 当做队列来使用
内存泄漏:是指程序在申请内存后,无法释放已申请的内存空间,一次内存泄漏不会有大的影响,但内存泄漏堆积后的后果就是内存溢出。
内存溢出:指程序申请内存时,没有足够的内存供申请者使用,比如说给了你一块存储int类型数据的存储空间,但是你却存储long类型的数据,那么结果就是内存不够用这个时候就会报内存溢出的错误。
如何防止内存溢出: 1修改JVM参数,直接增加内存2检查错误日志,查找OOM前是否有异常或错误3对代码进行走查和分析,找出会发生内存溢出的位置4使用内存查看工具,动态查看内存使用情况。(改参,检查OOM前,走查分析找溢出,内存查看工具看内存情况)
如何防止内存泄漏:1可以使用软引用或弱引用,当内存空间不足时释放这些引用所指向的对象2一定要让程序各个分支完整地执行到程序结束,然后看看某个对象是否被引用过,若没有引用过,则说明发生了内存泄漏。(软弱引用不足释放,分支执行到结束看某对象是否被引用过若没有则属于内存泄漏)
字节流在操作字符时,可能会有中文导致的乱码,如果要都转化为字符都话是比较耗时的,所以就有了字符流。
但是字符流比较适用操作文本文件,操作二进制文件的话文件很容易损坏,二进制文件(视频,音频,pdf等待)适合用字节流来操作。
强引用:就是指在程序中普遍存在的,Java永远不会回收这些对象,内存不足时抛出OutOfMemory错误也不会被回收。
软引用:当内存空间不足的时候,gc会回收软引用指向的对象。
弱引用:弱引用遇到GC就回收,为了解决某些地方的内存泄漏。
虚引用:在任何时候都可能被回收。
数组:
数组存储的数据在地址空间上是连续的,方便数据的查找,所以查找快,增删慢,插入值会整体移动,效率低.
链表:
链表存储数据在内存空间上不是连续的。其中每个节点包含两部分,一个是存储数据元素的“数据域”,另一个是存储下一个节点地址的“指针域”。插入一个数值节点,只需将插入节点,连接到链表中即可,删除效率也可以,但是查询某个具体的值,需要从头节点开始遍历,效率很低。
二叉树
由一个根节点和两棵互不相交的左子树和右子树的组成,而且每个节点最多有两个子节点,它是用一组连续的存储单元来存放二叉树的节点元素,既有链表的好处,也有数组的好处。所以它适合处理大批量的动态的数据
哈希表
1、哈希表底层数据结构是数组,哈希表不能存储基本数据类型(因为基本数据类型不能调用其hashcode()方法和equals()方法),存储的元素具有唯一性。
2、哈希表存储元素的过程是先判断要存储的元素与已有元素的hashcode是不是相同,如果不相同则会直接存储,如果相同就会继续调用equals方法判断,如果equals方法返回的是true则不能存储否则可以存储。
List:
有索引。有序可重复。ArrayList与Vector底层是数组,查询快增删慢。LinkedList底层是双向链表,查询慢增删快。ArrayList,LinkedList都是线程不安全,Vector线程安全。
Set:
无索引。无序不重复,Set实质上使用的是Map的Key存储,如果要将自定义的类存储到Set中,需要重写equals和hashCode方法。
HashSet底层是通过Hashmap来实现的,HashSet是无序不重复的,且不能排序,集合元素可以是null,但只能放入一个null
LinkedHashSet底层是链表+哈希表,查询慢增删快,它是根据元素的hashCode值来决定元素的存储位置,但是它同时使用链表维护元素的顺序所以遍历的时候会按照添加时的顺序来访问。
TreeSet底层是红黑树,一般用于排序,可以使用compareTo进行排序方法来比较元素之间大小关系,然后将元素按照升序排列。
Map
Map:Key无序不重复,Value可重复。
HashMap底层是数组+链表,它根据键的HashCode值存储数据,根据键可以直接获取它的值,访问速度很快。所以在Map 中插入、删除和定位元素比较适合用hashMap。
LinkedHashMap底层是链表+哈希表,它是HashMap的一个子类,如果需要读取的顺序和插入的相同,可以用LinkedHashMap来实现。
TreeMap底层是红黑树,与TreeSet类似,取出来的是排序后的键值对。但如果是要按自然顺序或自定义顺序遍历键,那么TreeMap会更好。
主要是为了减少equals比较的次数,两个对象进行比较的时候会先进行HashCode比较,不满足则不必进行equals比较了,提高了程序的效率。还有就是为了保证是同一个对象,如果重写了equals方法,而没有重写hashcode方法,会出现hashcode相等的对象,equals不相等的情况。
Error表示靠程序本身难以处理的一种异常,比如内存溢出。
Exception表示程序可以预见到的能处理的异常,可以捕获且可能恢复。
把基本数据类型转换为引用数据类型
装箱比如int变Integer,如果某个地方的参数需要填入Integer,你传int给它,它自动会生成一个Integer传过去。反之,Integer变int,就是自动拆箱。
Int转成Integer的好处
转成integer可以调用处理int型的数据方法,例如parint将string转成int类型,而且这些封装类都实现了serilizable接口,可以在网络之间进行数据传输。
如果我们需要持久化 Java 对象比如将 Java 对象保存在文件中,或者在网络传输 Java 对象,这些场景都需要用到序列化。
如果有些变量不想进行序列化,可以transient 关键字修饰。
垃圾回收可以有效的防止内存泄漏,Java会有一个固定的周期去清理和回收堆中已经死亡的或者长时间没有使用的对象
1)运行速度方面:String > StringBuffer > StringBuilder。
2)因为String是不可变对象,每次拼接都会创建一个对象,非常消耗内存空间,所以String的处理速度比StringBuilder和StringBuffer慢得多,StringBuilder和StringBuffer只需要创建一个StringBuilder和StringBuffer对象,然后用append方法拼接,无论拼接多少次都只有一个对象。
3)StringBuffer与StringBuilder的区别:StringBuffer是线程安全的,StringBuilder是线程不安全的。
4)使用场景:
String适用于操作少量数据;
StringBuffer适用于多线程操作大量数据;
StringBuilder适用于单线程操作大量数据。
服务器创建session出来后,会把session的id号,以cookie的形式回写给客户机,这样,只要客户机的浏览器不 关,再去访问服务器时,都会带着session的id号去,服务器发现客户机浏览器带session id过来了,就会使用内存 与之对应的session为之服务
Statement用于执行静态sql语句,在执行时,必须指定一个事先准备好的sql语句。
PrepareStatement是预编译的sql语句对象,sql语句被预编译并保存在对象中,在执行时可以为“?”动态设置参数值。
除此之外使用Statement 的话有可能会引起sql注入,就是用户输入的参数里面有可能包含了一些sql关键词比如 “or,where”等,有可能会改变sql语句的逻辑,但是preparestatement 通过占位符的形式,传入的参数会被“”包裹起 来从而避免了sql注入。
反射机制就是在运行状态中能动态获取当前的类的所有信息,很多框架,Jdbc,Spring IOC就是使用反射机制实现的,反射机制实质上就是不需要实例化对象(不需要new出来),将你的类进行初始化,对于私有属性也能通过反射机制进行赋值,核心就是当前类的.class文件
可以用来写框架和一些工具类,提高程序的可扩展性
将默认公共的无参构造器私有化,反射机制因为找不到无参构造器,无法进行初始化,所以运行时候会报错。
(1)可以用来写框架,比如常用的ORM(对象关系映射:Object Relational Mapping)的框架:MyBatis
(2)可以用来写工具类,比如常用的jdbc连接驱动
(3)可以实现Spring IOC控制反转
(4)可以获取当前类的所有方法,并为其所有的私有属性进行初始化
线程池是一种多线程处理形式,处理过程中将任务提交到线程池,任务的执行交由线程池来管理,线程使用完毕不会销毁,而是会先存储在线程池内。
降低资源损耗,提高响应速度因为线程创建需要时间,如果每个请求都创建一个线程去处理,那服务器的资源很快就会被耗尽,使用线程池可以减少创建和销毁线程的次数,每个工作线程都可以被重复利用,可执行多个任务。
1、newSingleThreadExecutor
创建一个单线程化的线程池,它只会用唯一的工作线程来执行任务,保证所有任务按照指定顺序执行。
2、newFixedThreadPool
创建一个定长线程池,可控制线程最大并发数,超出的线程会在队列中等待。
3、newCachedThreadPool
创建一个可缓存线程池,当任务数量减少会回收空闲线程,当任务数增加时,线程池会创建新线程来处理任务
4、newScheduledThreadPool
创建一个定长线程池,支持定时及周期性任务执行。
乐观锁(多读)
每次去取数据的时候总认为不会有其他线程对数据进行修改,因此不会上锁,但是在更新时会判断其他线程在这之前有没有对数据进行修改,一般是在数据表中加上一个数据版本号version字段,表示数据被修改的次数,当数据被修改时,version值会加一。当线程A要更新数据值时,在读取数据的同时也会读取version值,在提交更新时,若刚才读取到的version值为当前数据库中的version值相等时才更新。通常适用于读取操作比较频繁的场景。
update table。
set x=x+1, version=version+1
where id=#{id} and version=#{version};
悲观锁:(多写)
每次取数据时都总会认为会有其他线程对数据进行修改,所以都会加锁,当其他线程想要访问数据时,都会被阻塞在那里,可以通过数据库来实现,都是在操作之前加锁,MySQL中可以在查询语句后通过for update加上排他锁(写锁)或者lock in share mode加上共享锁(读锁),通常用于写入操作比较频繁的场景
什么是CAS
CAS是乐观锁的一种实现方式,CAS算法有三个操作数,内存值V,预期值A,要修改的值B,当且仅当内存值V与预期值A相等时,将内存值V修改为B,否则什么也不做。
CAS中的ABA问题
但是CAS可能存在ABA的问题,就是一个线程把数据A变成了B,然后又重新变成了A,此时另一个线程读取该数据的时候,发现A没有变化,就误认为是原来的那个A,但是此时A的一些属性或状态已经发生过变化。
ABA问题如何解决
CAS实现会使用版本号。AtomicStampedReference内部维护了对象值和版本号,在创建AtomicStampedReference对象时,需要传入初始值和初始版本号,当AtomicStampedReference设置对象值时,对象值以及状态戳都必须满足期望值,写入才会成功。
事务就是将一组sql放到一个批次中去执行,这些sql必须一起成功,如果其中有一个失败了就会出现事务回滚,什么都没有发生过的状态。
事务的四个特性:
原子性:要么都成功,要么都失败
一致性:事务前后数据完整性必须保持一致
隔离性:事务之间互不干扰
持久性:事务一旦提交成功后,对数据库的改变是永久性的
根据事务的隔离性可能会产生的问题:
脏读:一个事务读取到另一个事务未提交的数据
不可重复读:一个事务两条相同的查询语句,查询出来的结果不一样(事务执行一半数据被另一条事务修改了)
幻读:是指在一个事务内读取到别的事务插入的数据
事务有四种隔离级别:
事务默认隔离级别是可重复读,可序列化级别的事务操作某个表的时候会导致这个表会被锁住,其他事务无法访问,只有提交了这个事务才会释放锁
1.like查询是以%开头,会导致索引失效
2.在索引列上使用mysql的内置函数,索引失效
3.对索引列运算(如,+、-、*、/),索引失效
4.索引字段上使用(!= 或者 < >,not in)时,可能会导致索引失效
5.索引字段上使用is null, is not null,可能导致索引失效
SpringBoot是一个集成了许多第三方框架的框架,它本质上就是Spring,是Spring的拓展,它取消了Spring那种XML繁琐的配置方式,改用注解的配置方式,用来提高程序开发的效率,核心是ioc(控制反转)和aop(面向切面编程)。
先解析xml配置或注解配置的类,得到一个BeanDefinition,通过这个BeanDefinition反射创建Bean对象并进行属性填充,然后回调实现了Aware接口的方法,比BeanNameAware。之后会去调用BeanPostProcessor的初始化前方法,调用init初始化方法,调用BeanPostProcessor的初始化后方法,然后将创建的Bean对象放入一个Map中,这时候就可以正常业务使用bean了。Spring容器关闭时调用DisposableBean的destory()方法。
Ioc是以一种控制反转的设计思想,传统的方式假如有 a 和 b 两个对象,a 依赖于 b 那么 a 就必须先把b New出来才能使用,控制权都在自己手上 ,而注入 IOC 之后就 a对象 与b像 之间失去了直接联系,当a 对象 运行到需要b 对象 的时候,IOC 容器会主动创建一个 b对象 注入到 a对象 需要的地方。Ioc意味着将你设计好的对象交给容器控制,而不是传统的在你的对象内部直接控制。它负责对象的创建和维护,将实例化的过程交给spring去完成,对象 a 获得依赖对象 b 的过程,由主动行为变为了被动行为,可以降低使用资源双方的依赖程度
①概念:面向切面编程完善了Spring的依赖注入(DI),还是对面向对象编程(OOP)的补充。可以在不修改代码 的情况下,增加新的功能。AOP有日志记录、安全控制、事务处理等功能。
②AOP四个组成部分:
连接点:用来插入的方法。
切点:被插入的方法。
通知:被插入方法的内容。
切面:切点+通知。
③AOP Advice(AOP通知)分为前置通知、后置通知、异常通知、环绕通知。
Spring中常用注解:
@Bean 把自己写的类注入到容器里
@Configuration 给配置文件加的注解
@Controller @Service @Repository @Component 都是把类注入到容器里 但是有分层
@Transactional 一般是在业务逻辑层加的 让该类有事务的功能特性
@Resource 从容器里面取资源
@RequestMapping 要执行的方法或者路径
@ResponseBody 可以在方法上加 让该方法返回数据而不是页面
springMVC是模型视图控制器,它的本质是servlet,主要接收前台传递的参数到后台,并且将执行完的数据返回到前台
SpringMVC的工程结构一般来说分为三层,Modle层(数据访问层)、Cotroller层(处理用户发送 的请求)、View 层(页面显示层),其中Modle层分为两层:dao层、service层,MVC架构分层 的主要作用是解耦
spring中的Dispacherservlet会拦截满足规矩的请求,截取URL中最后一串代码到配置中寻找是否有满足的映射,如果有的话会寻找映射对应的类,并且执行类的代码,将代码中需要传送跳转的请求封装到modelandview中并且返回,将modelandview中视图的url进行前缀或后缀的装配后进行页面和数据的渲染后将页面返回给用户看
1.本质是servlet,但是相比servlet少很多代码,有利于系统的维护和扩展
2.是Spring框架的一部分,可以方便的利用Spring所提供的其他功能。
是一个基于xm文件的持久层框架,它内部封装了JDBC,所以开发的时候不需要再去加载驱动,创建和释放连接只需要关注SQL语句如何去编写,可以通过标签把SQL中的动态参数进行映射生成最终的SQL语句,然后把结果映射转为Java对象返回。
mybatis把所有sq语句都封装起来,让sql语句和代码分开来管理,方便去维护和拓展
,而且它提供了映射标签,支持对象和数据库的字段的关系映射,也可以使用where if 等标签来编写动态的sql。
一级缓存默认是开启的,只在一次SqlSession(会话)中有效,也就是拿到链接到关闭连接这个区间。在这个会话里面,如果有两条相同的sql语句的话,第二条sql语句会去缓存里面取数据,而不是去数据库里面取数据,除非这两条相同的sql语句中间有增删改或者手动清除缓存的操作,缓存才会失效
二级缓存也叫全局缓存,一级缓存怍用域太低了,所以逛生了二级缓存,它是基于namespace级别的缓存。一个名称空间。对应一个二级缓存。只要开启了二级缓存,在同一个Mapper下就有效所有的数据都会先放在一级缓存中;只有当会话提交,或者关闭的时候,才会提交到二级缓冲中!二级缓存默认是关闭的,如果要启用的话就在mapper.xml 里面加个就可以了
${ }是直接将参数参与编译,这样的话有可能会引起sql注入,比如传过来的参数里面带有where , or 等关键字有可能会改变这条sql语句的逻辑
#{ }是将参数通过 ?站位符预编译的形式,会给传过来的参数加上 ‘ ’ ,可以防止sql注入,通常都是使用这种方式
1.当参数不需要字符串包裹起来的时候
2.当sql中表名是从参数中取的情况 (动态拼接表名的时候)
3.order by排序语句中,因为order by 后边必须跟字段名,这个字段名不能带引号,如果带引号会被识别会字符串,而不是字段
一对一:assosiation标签
比如一个学生对应一个班级,需要在班级的实体类里面写入班级的对象属性,然后在resultMap标签下和result的同级目录下的assosiation标签里配置班级的属性信息。
一对多:collection标签
比如一个班级对应多个学生…
多对多:collection标签
比如一个大学生属于不同的班级,班级里又有不同的学生
答mybatis优点+而且它内部封装了JDBC,开发时只需要关注SQL语句,不需再花费精力手动去加载驱动,创建和释放连接。
Redis是一个高性能的key-value存储数据库,它是免费和开源,是当下最热门的 NoSQL技术之一,也被称之为结构化数据库。
与Memcached相比,Redis不仅仅支持K/V类型的数据,同时还提供list,set,hash等数据结构的存储,另外Redis支持数据备份与持久化,保证数据不易丢失。所以选择Redis作为数据缓存系统。(纯kv存储,数据量非常大,并发量非常大的业务,使用mcmemcache更合适)
因为redis是将所有的数据全部放在内存中操作的,肯定比直接操作磁盘快,使用多线程的话CPU上下文会切换会比较耗时,所以说使用单线程去操作效率就是最高的
redis有rdb和aof两种持久化的方式
rdb
rdb是一种快照的方式进行保存,的在指定的时间间隔内将内存中的数据集快照写入磁盘,恢复的时候只需要把rdb文件放在redis启动目录就可以了,redis会把将快照文件直接读到内存里,可以在配置文件里面配置快照触发的规则。它比较适合适合大规模的数据恢复,但是每一次触发都需要一定的时间间隔,如果Redis意外宕机了,这个最后一次修改的数据就没有了。
aof
以日志的形式来记录每个写操作,将Redis执行过的所有指令记录下来, redis每一次重启都会把这些命令执行一遍存到缓存中,每一次修改都同步,文件的完整会更加好,但是如果恢复的时候数量如果比较大,修复的速度会比rdb方式慢,所以持久化是rdb方式。
主从复制是指将一台主机服务器的数据 ,复制到从机服务器,主机只负责写的操作,而从机只负责读的操作,主机更新的数据会同步更新给从机。因为大部分情况下都是进行读的操作的,主从复制就是用来减轻服务器的压力。
哨兵模式是redis主从模式高可用的版本。
在主从模式下,如果主机宕机了,需要手动将从节点晋升为主节点,并且还要切换客户端的连接数据源,这样就无法达到高可用,而通过哨兵模式就可以解决这一问题。哨兵启动之后会开始监控redis主机和从机是否正常运行,当主机不能正常工作时候,哨兵模式会将随机一个从机变为主机。
缓存穿透
用户想要查询一个数据,发现redis数据库没有这个数据,于是就会向向持久层数据库查询,发现也没有,当用户很多的时候,这些请求都直接向持久层数据库查询,这会给持久层数据库造成很大的压力,这时候就相当于出现了缓存穿透。
解决方式:
缓存击穿
某一个热点 key,在缓存过期的一瞬间,同时有大量的请求过来,因为这个key缓存过期了,所以请求最终都会走到数据库,让数据库瞬间压力过大
解决方案:
缓存雪崩
大量的热点 key 设置了相同的过期时间,导在缓存在同一时刻全部失效,让数据库瞬间压力过大,引起缓存雪崩,还有一个更严重的缓存雪崩就是Redis宕机了,那所有的缓存都失效了。
解决方案:
对于普通的缓存雪崩
对于redis宕机这种情况:
redis中的事务是没有隔离级别的概念,所有的命令在事务队列中并没有直接被执行,只有发起执行命令的时候才会执行!
事务的两种异常
Redis中的监视
Watch监视,能实现一个乐观锁的功能,watch监视一个key后,会有一个类似version的功能,事务执行的时候,会进行对比version,观察这个key对应的value是否发生改变,如果改变,则事务不会执行
我真的很习惯使用Ruby编写以下代码:my_hash={}my_hash['test']=1Java中对应的数据结构是什么? 最佳答案 HashMapmap=newHashMap();map.put("test",1);我假设? 关于java-等价于Java中的RubyHash,我们在StackOverflow上找到一个类似的问题: https://stackoverflow.com/questions/22737685/
我正在尝试使用boilerpipe来自JRuby。我看过guide从JRuby调用Java,并成功地将它与另一个Java包一起使用,但无法弄清楚为什么同样的东西不能用于boilerpipe。我正在尝试基本上从JRuby中执行与此Java等效的操作:URLurl=newURL("http://www.example.com/some-location/index.html");Stringtext=ArticleExtractor.INSTANCE.getText(url);在JRuby中试过这个:require'java'url=java.net.URL.new("http://www
我只想对我一直在思考的这个问题有其他意见,例如我有classuser_controller和classuserclassUserattr_accessor:name,:usernameendclassUserController//dosomethingaboutanythingaboutusersend问题是我的User类中是否应该有逻辑user=User.newuser.do_something(user1)oritshouldbeuser_controller=UserController.newuser_controller.do_something(user1,user2)我
什么是ruby的rack或python的Java的wsgi?还有一个路由库。 最佳答案 来自Python标准PEP333:Bycontrast,althoughJavahasjustasmanywebapplicationframeworksavailable,Java's"servlet"APImakesitpossibleforapplicationswrittenwithanyJavawebapplicationframeworktoruninanywebserverthatsupportstheservletAPI.ht
这篇文章是继上一篇文章“Observability:从零开始创建Java微服务并监控它(一)”的续篇。在上一篇文章中,我们讲述了如何创建一个Javaweb应用,并使用Filebeat来收集应用所生成的日志。在今天的文章中,我来详述如何收集应用的指标,使用APM来监控应用并监督web服务的在线情况。源码可以在地址 https://github.com/liu-xiao-guo/java_observability 进行下载。摄入指标指标被视为可以随时更改的时间点值。当前请求的数量可以改变任何毫秒。你可能有1000个请求的峰值,然后一切都回到一个请求。这也意味着这些指标可能不准确,你还想提取最小/
HashMap中为什么引入红黑树,而不是AVL树呢1.概述开始学习这个知识点之前我们需要知道,在JDK1.8以及之前,针对HashMap有什么不同。JDK1.7的时候,HashMap的底层实现是数组+链表JDK1.8的时候,HashMap的底层实现是数组+链表+红黑树我们要思考一个问题,为什么要从链表转为红黑树呢。首先先让我们了解下链表有什么不好???2.链表上述的截图其实就是链表的结构,我们来看下链表的增删改查的时间复杂度增:因为链表不是线性结构,所以每次添加的时候,只需要移动一个节点,所以可以理解为复杂度是N(1)删:算法时间复杂度跟增保持一致查:既然是非线性结构,所以查询某一个节点的时候
遍历文件夹我们通常是使用递归进行操作,这种方式比较简单,也比较容易理解。本文为大家介绍另一种不使用递归的方式,由于没有使用递归,只用到了循环和集合,所以效率更高一些!一、使用递归遍历文件夹整体思路1、使用File封装初始目录,2、打印这个目录3、获取这个目录下所有的子文件和子目录的数组。4、遍历这个数组,取出每个File对象4-1、如果File是否是一个文件,打印4-2、否则就是一个目录,递归调用代码实现publicclassSearchFile{publicstaticvoidmain(String[]args){//初始目录Filedir=newFile("d:/Dev");Datebeg
目录第1题连续问题分析:解法:第2题分组问题分析:解法:第3题间隔连续问题分析:解法:第4题打折日期交叉问题分析:解法:第5题同时在线问题分析:解法:第1题连续问题如下数据为蚂蚁森林中用户领取的减少碳排放量iddtlowcarbon10012021-12-1212310022021-12-124510012021-12-134310012021-12-134510012021-12-132310022021-12-144510012021-12-1423010022021-12-154510012021-12-1523.......找出连续3天及以上减少碳排放量在100以上的用户分析:遇到这类
我基本上来自Java背景并且努力理解Ruby中的模运算。(5%3)(-5%3)(5%-3)(-5%-3)Java中的上述操作产生,2个-22个-2但在Ruby中,相同的表达式会产生21个-1-2.Ruby在逻辑上有多擅长这个?模块操作在Ruby中是如何实现的?如果将同一个操作定义为一个web服务,两个服务如何匹配逻辑。 最佳答案 在Java中,模运算的结果与被除数的符号相同。在Ruby中,它与除数的符号相同。remainder()在Ruby中与被除数的符号相同。您可能还想引用modulooperation.
Java的Collections.unmodifiableList和Collections.unmodifiableMap在Ruby标准API中是否有等价物? 最佳答案 使用freeze应用程序接口(interface):Preventsfurthermodificationstoobj.ARuntimeErrorwillberaisedifmodificationisattempted.Thereisnowaytounfreezeafrozenobject.SeealsoObject#frozen?.Thismethodretur