服务端开发Java面试复盘篇1
上周投了一些简历,约了8-9家面试,其中完成了3家的第一轮面试,由于面试的是Java 的实习生,感觉问的题目都比较基础,不过有些问题回答的不是很好,在这里对回答的不太好的题目做一下总结和复盘。
目录
一、后端开发Java面试复盘
1.1、23种设计模式
1.2、数据库(MySQL)的索引失效情况
1.3、线程池的使用
1.4、ConcurrentHashMap的使用及底层原理
1.5、Spring的传递依赖问题
1.6、MySQL事务的四种隔离级别
一、后端开发Java面试复盘
1.1、23种设计模式
设计模式:就是代码设计经验的总结。使用设计模式可以提高代码的可靠性和可重用性。
设计模式共有23中,整体分为3大类,如下:
创建型模式,共五种:工厂方法模式、抽象工厂模式、单例模式、建造者模式、原型模式
结构型模式,共七种:适配器模式、装饰器模式、代理模式、外观模式、桥接模式、组合模式、享元模式
行为型模式,共十一种:策略模式、模板方法模式、观察者模式、迭代子模式、责任链模式、命令模式、备忘录模式、状态模式、访问者模式、中介者模式、解释器模式
设计模型有6大原则,具体如下:
1)开放封闭原则:尽量通过扩展软件实体应对需求的改变,而不是修改原有代码
2)里氏代换原则:使用的基类可以在任何地方使用继承的字类,完美的替换基类
3)依赖倒转原则:即面向接口编程,依赖抽象而不依赖具体
4)接口隔离原则:使用多个隔离的接口替代单个接口,降低耦合
5)迪米特法则:一个类尽量减少对其他类的依赖
6)单一职责:一个方法尽量只负责一件事
单例模式,分为饿汉模式和懒汉模式,都是每个类中只创建一个实例,并提供全局访问点来访问这个实例。饿汉模型是线程安全的,懒汉模式线程不安全,需要使用双重检测锁保证线程安全,具体的Java代码实现如下:
/*** 单例模式:确保每个类只有一个实例,并提供全局访问点来访问这个实例*/
//饿汉模式:线程安全
class Singleton1 {private static Singleton1 instance = new Singleton1() ;public Singleton1 getInstance(){return instance ;}
}//懒汉模式:线程不安全,需要通过双重检查锁定机制控制
class Singleton2{private static Singleton2 instance2 = null ;public Singleton2 getInstance2(){if(instance2 == null){instance2 = new Singleton2() ;}return instance2 ;}
}
//使用双重检查锁的方式保重线程安全
class Singleton3{//使用双重检查进行初始化的实例必须使volatile关键字修饰private volatile static Singleton3 instance3 = null ;public Singleton3 getInstance3(){if(instance3 == null){synchronized (Singleton3.class){if(instance3 == null){instance3 = new Singleton3();}}}return instance3 ;}
}
public class Main {public static void main(String[] args) {Singleton1 singleton1 = new Singleton1() ;Singleton1 singleton2 = new Singleton1() ;Singleton2 singleton21 = new Singleton2() ;Singleton2 singleton22 = new Singleton2() ;Singleton1 instance1 = singleton1.getInstance();Singleton1 instance2 = singleton2.getInstance();Singleton2 instance21 = singleton21.getInstance2();Singleton2 instance22 = singleton22.getInstance2();System.out.println(instance1 == instance2);System.out.println(instance21 == instance22);}
}
下面在了解一下工厂模式和代理模式。
工厂模式是一种创建对象的最佳方式,在创建对象时不对客户端暴露创建逻辑,通过使用一个共同的接口来指向新创建的对象,实现创建者和调用者的分离,工厂模式分为简单工厂,工厂方法和抽象工厂。我们熟知的Spring的IOC容器使用工厂模式创建Bean,只需要交给Bean进行管理即可,这样我们在业务层调接口层的方法时候就不需要再new了,可以直接注入。
1)简单工厂模式:也称为静态工厂方法,可以根据参数的不同返回不同类的实例,简单工厂模式专门定义一个类来负责创建其它类的实例,被创建的实例通常都有共同的父类。
首先创建工厂:
public interface Car {public void run() ;
}
定义工厂中的两个产品:
public class Car1 implements Car {@Overridepublic void run() {System.out.println("我是小汽车");}
}
public class Bus implements Car {@Overridepublic void run() {System.out.println("我是大卡车");}
}
创建核心工厂类,决定调用工厂中的哪一种方法,具体如下:
/*** 创建工厂类,在工厂类中决定调用哪一种产品*/
public class CarFactory {public static Car createCar(String name){if("小汽车".equals(name)){return new Car1() ;}if("大卡车".equals(name)){return new Bus() ;}return null ;}}
演示创建共创对象,并调用工厂中的产品,具体如下:
/*** 演示简单工厂*/
public class Factory1 {public static void main(String[] args) {//通过工厂类创建工厂对象Car car = CarFactory.createCar("小汽车");Car car1 = CarFactory.createCar("大卡车");//调用工厂方法car.run();car1.run();}
}
- 优点:简单工厂模式能够根据外界给定的信息,决定究竟应该创建哪个具体类的对象。明确区分了各自的职责和权力,有利于整个软件体系结构的优化。
- 缺点:很明显工厂类集中了所有实例的创建逻辑,容易违反GRASPR的高内聚的责任分配原则。
2)工厂方法模式:也称多态性工厂模式,核心的工厂类不在负责所有产品实例的创建,而是将具体的创建交给具体的子类去做,该核心类成为一个抽象工厂角色,仅仅给出具体工厂字类必须实现的接口,而不涉及具体哪一个产品被实例化。
首先是创建工厂和工厂的两个产品,具体如下:
public interface Car {public void run() ;
}public class Car1 implements Car {@Overridepublic void run() {System.out.println("我是小汽车");}
}public class Bus implements Car {@Overridepublic void run() {System.out.println("我是大卡车");}
}
然后创建工厂方法调用接口,并创建工厂实例。
/*** 创建创建工厂方法调用接口,所有工厂产品需要实现该接口,并重写接口方法*/
public interface Factorys {Car createFactory() ;
}public class CarF implements Factorys {@Overridepublic Car createFactory() {return new Car1() ;}
}public class BusF implements Factorys {@Overridepublic Car createFactory() {return new Bus() ;}
}
最后演示工厂方法的实现。
public class Factory2 {public static void main(String[] args) {Car car = new CarF().createFactory();Car car1 = new BusF().createFactory();car.run() ;car1.run() ;}
}
3)抽象工厂模式:即工厂的工厂 ,抽象工厂可以创建具体工厂,由具体工厂来生产具体产品。
首先创建第一个子工厂及其实现类,如下:
/*** 创建第一个工厂接口及其实现类*/
public interface A {void run() ;
}
class CarA implements A{@Overridepublic void run() {System.out.println("奔驰");}
}
class CarB implements A{@Overridepublic void run() {System.out.println("宝马");}
}
创建第2个子工厂及其实现类,具体如下:
public interface B {void run() ;
}
class Animal1 implements B{@Overridepublic void run() {System.out.println("狗");}
}
class Animal implements B{@Overridepublic void run() {System.out.println("猫");}
}
创建一个总工厂及其实现类,由总工厂的实现类决定调用哪个工厂的哪个实例。
/*** 总工厂,包含创建工厂工厂的接口*/
public interface TotalFactory {A createA() ;B createB() ;
}/*** 总工厂的实现类,决定创建哪个工厂的哪个实例*/
class TotalFactoryImpl implements TotalFactory{@Overridepublic A createA() {return new CarA() ;}@Overridepublic B createB() {return new Animal1();}
}
最后演示抽象工厂模式,如下:
public class Test {public static void main(String[] args) {A a = new TotalFactoryImpl().createA();B b = new TotalFactoryImpl().createB();a.run();b.run() ;}
}
下面我们看一下代理模式,我们正常在Spring会接触到代理模式。我们先了解一下什么是代理。
- 通过代理控制对象的访问,可以在这个对象调用方法之前、调用方法之后去处理/添加新的功能。(也就是AOP的实现)
- 代理在原有代码乃至原业务流程都不修改的情况下,直接在业务流程中切入新代码,增加新功能,这也和Spring的(面向切面编程)很相似
我们常见的代理模式分为3种,即静态代理,JDK动态代理和CGLIB动态代理。
静态代理:简单代理模式,是动态代理的理论基础。常见使用在代理模式。
JDK 代理 : 基于接口的动态代理技术·:利用拦截器(必须实现invocationHandler)加上反射机制生成一个代理接口的匿名类,在调用具体方法前调用InvokeHandler来处理,从而实现方法增强。
CGLIB代理:基于父类的动态代理技术:动态生成一个要代理的子类,子类重写要代理的类的所有不是final的方法。在子类中采用方法拦截技术拦截所有的父类方法的调用,顺势织入横切逻辑,对方法进行增强。
1)静态代理
我们首先看如下一个接口类,如何在不改变接口类的基础上,在接口方法中开启和关闭事务,我们可以使用静态代理的方式。
public interface UserDao {void save() ;
}class UserDaoImpl implements UserDao{@Overridepublic void save() {System.out.println("添加数据");}
}
public class Test2 {public static void main(String[] args) {UserDaoImpl userDao = new UserDaoImpl();userDao.save();}
}
下面是静态代理实现的代码,如下:
public class UserDaoProxy extends UserDaoImpl {public UserDaoImpl userDao ;public UserDaoProxy(UserDaoImpl userDao){this.userDao = userDao ;}@Overridepublic void save() {System.out.println("开启事务");super.save();System.out.println("关闭事务");}
}
public class Test2 {public static void main(String[] args) {UserDaoImpl userDao = new UserDaoImpl();UserDaoProxy userDaoProxy = new UserDaoProxy(userDao);userDaoProxy.save();}
}
2)下面看一下JDK动态代理,它是基于接口的动态代理技术,用拦截器(必须实现invocationHandler)加上反射机制生成一个代理接口的匿名类,在调用具体方法前调用InvokeHandler来处理,从而实现方法增强。
首先编写可以重复使用的代理类,如下,可以重复使用,不像静态代理那样每次都要重复编写带泪类,具体如下:
import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;public class InvocationHandlerImpl implements InvocationHandler {//通过构造方法传入目标对象public Object target ;InvocationHandlerImpl(Object target){this.target = target ;}/*** 动态代理实际运行的代理方法,以反射的方式创建对象* @param proxy* @param method* @param args* @return* @throws Throwable*/@Overridepublic Object invoke(Object proxy, Method method, Object[] args) throws Throwable {System.out.println("开始");Object invoke = method.invoke(target, args);System.out.println("结束");return invoke ;}
}
public class Test2 {public static void main(String[] args) {//已构造方法的方式传入被代理的对象UserDaoImpl userDaoImpl = new UserDaoImpl() ;InvocationHandlerImpl invocationHandler = new InvocationHandlerImpl(userDaoImpl);//类加载器ClassLoader classLoader = userDaoImpl.getClass().getClassLoader();Class<?>[] interfaces = userDaoImpl.getClass().getInterfaces();UserDao proxyInstance = (UserDao)Proxy.newProxyInstance(classLoader, interfaces, invocationHandler);proxyInstance.save();}
}
3)最后我们看一下CGLIB动态代理,基于父类的动态代理技术:动态生成一个要代理的子类,子类重写要代理的类的所有不是final的方法。在子类中采用方法拦截技术拦截所有的父类方法的调用,顺势织入横切逻辑,对方法进行增强。
简单地说就是实现MethodInterceptor接口并重写intercept()方法实现动态代理。
1.2、数据库(MySQL)的索引失效情况
1)查询条件有or关键字(必须所有查询条件都有索引)
2)模糊查询like以%开头
3)索引列上的条件where部分涉及计算或者函数
4)复合索引缺少左列字段
5)数据库认为全表扫描比索引更高效
1.3、线程池的使用
创建线程常见的几种方法包括继承Thread类并重写run()方法,实现Runnable()接口或实现Collable()等。一般来说,我们使用传统的方法每次创建和销毁线程的开销都比较大,故我们可以使用线程池的方式,减小开销。
使用线程池主要有如下的优势:
1)提高效率,创建好一定数量的线程放在池中,等需要使用的时候就从池中拿一个,这要比需要的时候创建一个线程对象要快的多。
2)减少了创建和销毁线程的次数,每个工作线程都可以被重复利用,可执行多个任务。
3)提升系统响应速度,假如创建线程用的时间为T1,执行任务用的时间为T2,销毁线程用的时间为T3,那么使用线程池就免去了T1和T3的时间。
Executors类(并发包)提供了4种创建线程池方法,这些方法最终都是通过配置ThreadPoolExecutor的不同参数,来达到不同的线程管理效果。

推荐通过 new ThreadPoolExecutor() 的写法创建线程池,这样写线程数量更灵活,开发中多数用这个类创建线程。
该类包含如下核心参数:核心线程数,最大线程数,闲置超时时间,超时时间的单位,线程池中的任务队列,线程工厂,拒绝策略。

最后一个参数为拒绝策略,一半包含四种拒绝策略,如下:
1. AbortPolicy
当任务添加到线程池中被拒绝时,直接丢弃任务,并抛出RejectedExecutionException异常。
2. DiscardPolicy
当任务添加到线程池中被拒绝时,丢弃被拒绝的任务,不抛异常。
3. DiscardOldestPolicy
当任务添加到线程池中被拒绝时,丢弃任务队列中最旧的未处理任务,然后将被拒绝的任务添加到等待队列中。
4. CallerRunsPolicy
被拒绝任务的处理程序,直接在execute方法的调用线程中运行被拒绝的任务。
总结:就是被拒绝的任务,直接在主线程中运行,不再进入线程池。
下面看一个demo,创建线程池,并设置最大线程数目为2,设置拒绝策略为CallerRunsPolicy。
import java.util.concurrent.LinkedBlockingDeque;
import java.util.concurrent.ThreadPoolExecutor;
import java.util.concurrent.TimeUnit;public class Test {public static void main(String[] args) {// 创建单线程-线程池,任务依次执行ThreadPoolExecutor threadPoolExecutor = new ThreadPoolExecutor(2, 2,60, TimeUnit.SECONDS,new LinkedBlockingDeque<>(2),new ThreadPoolExecutor.CallerRunsPolicy());for (int i = 0; i < 10; i++) {//创建任务Runnable runnable = new Runnable() {@Overridepublic void run() {try {Thread.sleep(20);} catch (InterruptedException e) {e.printStackTrace();}System.out.println(Thread.currentThread().getName());}};// 将任务交给线程池管理threadPoolExecutor.execute(runnable);}}
}
1.4、ConcurrentHashMap的使用及底层原理
Map包括HashMap和HashTable。
HashMap性能高,但不是线程安全:
HashMap的性能比较高,但是HashMap不是线程安全的,在并发环境下,可能会形成环状链表导致get操作时,cpu空转,所以,在并发环境中使用HashMap是非常危险的。
HashTable是线程安全的,但性能差:
HashTable和HashMap的实现原理几乎一样,差别:HashTable不允许key和value为null。
HashTable是线程安全的,但是HashTable线程安全的策略实现代价却比较大,get/put所有相关操作都是synchronized的,这相当于给整个哈希表加了一把大锁,多线程访问时候,只要有一个线程访问或操作该对象,那其他线程只能阻塞,这就导致性能比较低。
ConcurrentHashMap是线程安全的且性能高:
JDK1.7版本: 容器中有多把锁,每一把锁锁一段数据,这样在多线程访问时不同段的数据时,就不会存在锁竞争了,这样便可以有效地提高并发效率。
JDK1.8版本:做了2点修改,取消segments字段,直接采用transient volatile HashEntry<K,V>[] table保存数据,采用table数组元素作为锁,从而实现了对每一行数据进行加锁,并发控制使用Synchronized和CAS来操作将原先table数组+单向链表的数据结构,变更为table数组+单向链表+红黑树的结构。
1.5、Spring的传递依赖问题
maven环境存在的依赖冲突问题,可以在pom文件中使用<exlusions>标签排除依赖,主动断开依赖的资源,被排除的资源无需指定版本。
在Spring中解决循环依赖问题,可以使用三级缓存,三级缓存如下:

1.6、MySQL事务的四种隔离级别
MySQL支持四种事务隔离级别,默认的事务隔离级别为repeatable read,Oracle数据库默认的隔离级别是read committed。
四种隔离级别分别为读未提交,读已提交,可重复读, 序列化/串行化。其中,读未提交是最低的隔离级别,序列化隔离级别最高。
1.读未提交(read uncommitted):没有提交就读取到了。
2.读已提交(read committed):已经提交的才能读取。
3.可重复读(repeatable read):事务结束之前。永远读取不到真实数据,提交了也读取不到,读取的永远都是最初的数据,即假象。
4.序列化(serializable):表示事务排队,不能并发,每次读取的都是最真实的数据。
同时运行多个事务,当这些事务访问数据库中相同的数据时,如果没有采取必要的隔离机制,就会导致各种并发问题。
1-脏读:对于两个事务T1和T2,T1读取了已经被T2更新但还没有提交的字段,之后,若T2回滚,则T1读取的数据就是临时且无效的。
2-不可重复读:对于两个事务T1和T2,T1读取了该字段,但是T2更新了该字段,T1再次读取这个字段,值就不同了。
3-幻读:对于两个事务T1和T2,T1从表中读取了一些字段,T2在表中插入了一些新的行,T1再次读取该表发现多几行。
read uncommitted:可以出现脏读,幻读,不可重复读。
read committed:避免脏读,出现幻读和不可重复读。
repeatable read:避免脏读和不可重复读,出现幻读。
serializable:避免脏读,幻读,不可重复读。
相关文章:
服务端开发Java面试复盘篇1
上周投了一些简历,约了8-9家面试,其中完成了3家的第一轮面试,由于面试的是Java 的实习生,感觉问的题目都比较基础,不过有些问题回答的不是很好,在这里对回答的不太好的题目做一下总结和复盘。 目录 一、后…...
Android框架WiFi架构
同学,别退出呀,我可是全网最牛逼的 WIFI/BT/GPS/NFC分析博主,我写了上百篇文章,请点击下面了解本专栏,进入本博主主页看看再走呗,一定不会让你后悔的,记得一定要去看主页置顶文章哦。 一、wpa_supplicant:wpa_supplicant本身开源项目源码,被谷歌收购之后加入Android移…...
rt-thread 移植调试记录
rt-thread 移植调试记录 记录rt-thread移植的过程。这里移植仅仅是利用rt-thread源码目录已经移植好的文件,组建自己的工程,不需要自己编写汇编完成底层移植。 1. 搭建基础工程 这里使用的是正点原子的潘多拉开发板,MCU为stm32l475。需要先…...
红外线额温枪与红外线温度传感器的原理分析
额温枪主要针对测量人体额温基准而设计,使用也非常简单方便。测体温可以达到一秒即可准确测量。并且不需要接触人体,隔着空气即可一键测温。非常适合家庭、学校、企业等场所。 但是由于其精度原因(一般为 0.2 ℃,也有更低的&#…...
2023牛客寒假算法集训营4
目录A. [清楚姐姐学信息论](https://ac.nowcoder.com/acm/contest/46812/A)(数学)B. [清楚姐姐学构造](https://ac.nowcoder.com/acm/contest/46812/B)(数学 构造)C. [清楚姐姐学01背包(Easy Version)](https://ac.nowcoder.com/…...
vue组合式API及生命周期钩子函数
一、组合式API 什么是组合式API? vue3中支持vue2的选项式、支持新的编程模式–函数式编程(没有this指针)做了一个兼容,可以在一个组件中使用函数式编程和OOP编程(选项式) setup()函数 可以使用setup属性…...
Python|每日一练|数组|回溯|二分查找|排序和顺序统计量|.update方法 |单选记录:组合总和|寻找峰值|编程通过键盘输入每一位运动员
1、组合总和(数组、回溯) 给定一个无重复元素的数组 candidates 和一个目标数 target ,找出 candidates 中所有可以使数字和为 target 的组合。 candidates 中的数字可以无限制重复被选取。 说明: 所有数字(包括 t…...
minio下载文件速度很慢的原因分析与说明
文章目录1.实战背景2.问题描述3.问题分析4.问题解决1.实战背景 最近在做一个项目,需要用到minio来搭建文件系统,先简单说一下我在项目中设置的上传文件流程: 前端将分块文件逐一传给后端,后端再存储到 linux服务器的minio 当中。…...
基于comsol软件弯曲单模光纤模拟仿真
在本节中,主要基于实验室实际光纤单模圆柱光纤进行模拟,与comsol案例库文件在分析过程和建模有些差异: 模拟主要通过以下三个步骤进行:模型的几何构建、物理场的添加研究、结构处理分析来进行。 下面是第一步骤:几何…...
如何开启多个独立Chrome浏览器
一、简介 作为测试或者开发人员,有些情况下会用到 Chrome 浏览器,但有时是同一个 Chrome 浏览器无法为我们提供隔离开的不同环境。这样 我们就需要清理 cache 、切换账号等,降低了我们的工作效率。今天的主题是如何开启多个独立的 Chrome 浏…...
erp5开源制造业erp主要业务会计分录处理
erp5开源制造业erp主要业务会计分录处理 采购业务的会计分录 收到发票时 借:材料采购 (1201) 应交税费-应交增值税(进项税)(21710101) 贷:应付账款 (2121) 付款时 借:应付账款 (2121) 贷:银行存款 (1002) 入…...
技能树基础——17四平方和(拉格朗日定理,嵌套循环)
题目:四平方和定理,又称为拉格朗日定理:每个正整数都可以表示为至多4个正整数的平方和。如果把0包括进去,就正好可以表示为4个数的平方和。比如:5 0^ 2 0^ 2 1^ 2 2^27 1^ 2 1^ 2 1^ 2 2^2 (^符号表…...
JPA、EJB、事物管理---相关内容整理
目录 ■前言 ■实现原理:容器管理事务 ■代码实现简单描述: 1.JPA ■定义 ■1.1.配置文件 ■1.2.OSS jar ■1.3.一些OPA的类(举例) ■1.4. jpa 框架在实体类(Entity)中添加非数据库字段的属性--…...
C语言学习笔记(一):了解C语言
什么是C语言 C语言是一种高级编程语言,最早由丹尼斯里奇在1972年开发。它是一种通用编程语言,提供了高级编程语言的方便和易用性,同时又有较低级别的编程语言的灵活性和效率。C语言在许多操作系统、编译器和应用程序开发中广泛使用ÿ…...
回头看——《智能家居项目小结》
openAI兴起,于是拿着之前小组合作的项目(承认优化较差),交给AI试着帮忙优化下1.功能函数(TCP_SER_INIT)优化源代码:int TCP_SER_INIT(int *tcpsocket, const char *ip, const char *…...
社交登陆OAuth2.0
QQ、微博、github 等网站的用户量非常大,别的网站为了 简化自我网站的登陆与注册逻辑,引入社交登陆功能; 步骤: 1)、用户点击 QQ 按钮 2)、引导跳转到 QQ 授权页 3)、用户主动点击授权ÿ…...
C++005-C++选择与分支2
文章目录C005-C选择与分支2条件语句C实现else if 语句题目描述 根据成绩输出成绩等级ABCDEif嵌套语句题目描述 输出三个数中的最大值题目描述 模拟游戏登录switch语句三元运算符题目描述 输出三个数中的最大值-基于3元运算符题目描述 根据1-7输出星期1-星期日案例练习题目描述 …...
IPFS 简介及概述
文章目录 IPFS 简介IPFS 包含的协议内容及其理解IPFS 和 BitTorrent 区别IPFS 简介 星际文件系统(InterPlanetary File System). IPFS 是一个分布式的网络文件系统, 点到点超媒体协议. 可以让我们的互联网速度更快, 更加安全, 并且更加开放. IPFS协议的目标是取代传统的互联网…...
初学者必读:讲解 VC 下如何正确的创建、管理及发布项目
Visual C 的项目文件组成,以及如何正确的创建及管理项目。 本内容是初学者必须要掌握的。不能正确的管理项目,就不能进一步写有规模的程序。 一、项目下各种常见文件类型的功能 1. 代码文件 扩展名为 .cpp、.c、.h 等。 通常情况下,项目…...
剑指offer(中等)
目录 二维数组中的查找 重建二叉树 矩阵中的路径 剪绳子 剪绳子② 数值的整数次方 表示数值的字符串 树的子结构 栈的压入、弹出序列 从上到下打印二叉树① 从上到下打印二叉树③ 二叉搜索树的后序遍历序列 二叉树中和为某一值的路径 复杂链表的复制 二叉搜索树与…...
设计模式和设计原则回顾
设计模式和设计原则回顾 23种设计模式是设计原则的完美体现,设计原则设计原则是设计模式的理论基石, 设计模式 在经典的设计模式分类中(如《设计模式:可复用面向对象软件的基础》一书中),总共有23种设计模式,分为三大类: 一、创建型模式(5种) 1. 单例模式(Sing…...
TDengine 快速体验(Docker 镜像方式)
简介 TDengine 可以通过安装包、Docker 镜像 及云服务快速体验 TDengine 的功能,本节首先介绍如何通过 Docker 快速体验 TDengine,然后介绍如何在 Docker 环境下体验 TDengine 的写入和查询功能。如果你不熟悉 Docker,请使用 安装包的方式快…...
.Net框架,除了EF还有很多很多......
文章目录 1. 引言2. Dapper2.1 概述与设计原理2.2 核心功能与代码示例基本查询多映射查询存储过程调用 2.3 性能优化原理2.4 适用场景 3. NHibernate3.1 概述与架构设计3.2 映射配置示例Fluent映射XML映射 3.3 查询示例HQL查询Criteria APILINQ提供程序 3.4 高级特性3.5 适用场…...
Nginx server_name 配置说明
Nginx 是一个高性能的反向代理和负载均衡服务器,其核心配置之一是 server 块中的 server_name 指令。server_name 决定了 Nginx 如何根据客户端请求的 Host 头匹配对应的虚拟主机(Virtual Host)。 1. 简介 Nginx 使用 server_name 指令来确定…...
Rust 异步编程
Rust 异步编程 引言 Rust 是一种系统编程语言,以其高性能、安全性以及零成本抽象而著称。在多核处理器成为主流的今天,异步编程成为了一种提高应用性能、优化资源利用的有效手段。本文将深入探讨 Rust 异步编程的核心概念、常用库以及最佳实践。 异步编程基础 什么是异步…...
ios苹果系统,js 滑动屏幕、锚定无效
现象:window.addEventListener监听touch无效,划不动屏幕,但是代码逻辑都有执行到。 scrollIntoView也无效。 原因:这是因为 iOS 的触摸事件处理机制和 touch-action: none 的设置有关。ios有太多得交互动作,从而会影响…...
OPenCV CUDA模块图像处理-----对图像执行 均值漂移滤波(Mean Shift Filtering)函数meanShiftFiltering()
操作系统:ubuntu22.04 OpenCV版本:OpenCV4.9 IDE:Visual Studio Code 编程语言:C11 算法描述 在 GPU 上对图像执行 均值漂移滤波(Mean Shift Filtering),用于图像分割或平滑处理。 该函数将输入图像中的…...
android13 app的触摸问题定位分析流程
一、知识点 一般来说,触摸问题都是app层面出问题,我们可以在ViewRootImpl.java添加log的方式定位;如果是touchableRegion的计算问题,就会相对比较麻烦了,需要通过adb shell dumpsys input > input.log指令,且通过打印堆栈的方式,逐步定位问题,并找到修改方案。 问题…...
协议转换利器,profinet转ethercat网关的两大派系,各有千秋
随着工业以太网的发展,其高效、便捷、协议开放、易于冗余等诸多优点,被越来越多的工业现场所采用。西门子SIMATIC S7-1200/1500系列PLC集成有Profinet接口,具有实时性、开放性,使用TCP/IP和IT标准,符合基于工业以太网的…...
【Veristand】Veristand环境安装教程-Linux RT / Windows
首先声明,此教程是针对Simulink编译模型并导入Veristand中编写的,同时需要注意的是老用户编译可能用的是Veristand Model Framework,那个是历史版本,且NI不会再维护,新版本编译支持为VeriStand Model Generation Suppo…...
