目录
1. @EnableAsync开启异步化支持
2. ProxyAsyncConfiguration异步代理配置类
3. AsyncAnnotationBeanPostProcessor
3.1 BeanFactoryAware实现逻辑
3.1.1 异步注解增强/拦截器AnnotationAsyncExecutionInterceptor的原理
3.1.2 切点AnnotationMatchingPointcut的执行逻辑
3.2 BeanPostProcessor后处理器实现逻辑
在项目开发中,基于业务逻辑合理性以及程序执行性能等方面的考虑,程序执行异步化是一个很好地选择;当然,异步化的方式有很多种,包括自定义线程池、Guava开源组件AsyncEventBus、以及spring内部支持的@Async注解方式等等,这里,我们主要分析下spring对异步化的支持@EnableAsync&@Async的源码实现;
1. @EnableAsync开启异步化支持
通过@EnableAsync的注解名称很容易得知,这又是一个enable*的实现模式,类似于介绍aop时@EnableAspectJAutoProxy开启aspectj切面的支持,介绍spring声明式事务时@EnableTransactionManager开启声明式事务支持一样;下面首先看一下@EnableAsync的源码:
@Target(ElementType.TYPE)
@Retention(RetentionPolicy.RUNTIME)
@Documented
@Import(AsyncConfigurationSelector.class)
public @interface EnableAsync {
/**
* Indicate the 'async' annotation type to be detected at either class
* or method level.
* By default, both Spring's @{@link Async} annotation and the EJB 3.1
* {@code @javax.ejb.Asynchronous} annotation will be detected.
*
This attribute exists so that developers can provide their own
* custom annotation type to indicate that a method (or all methods of
* a given class) should be invoked asynchronously.
*/
Class annotation() default Annotation.class;
/**
* Indicate whether subclass-based (CGLIB) proxies are to be created as opposed
* to standard Java interface-based proxies.
*
Applicable only if the {@link #mode} is set to {@link AdviceMode#PROXY} .
*
The default is {@code false}.
*
Note that setting this attribute to {@code true} will affect all
* Spring-managed beans requiring proxying, not just those marked with {@code @Async}.
* For example, other beans marked with Spring's {@code @Transactional} annotation
* will be upgraded to subclass proxying at the same time. This approach has no
* negative impact in practice unless one is explicitly expecting one type of proxy
* vs. another — for example, in tests.
*/
boolean proxyTargetClass() default false;
/**
* Indicate how async advice should be applied.
*
The default is {@link AdviceMode#PROXY}.
* Please note that proxy mode allows for interception of calls through the proxy
* only. Local calls within the same class cannot get intercepted that way; an
* {@link Async} annotation on such a method within a local call will be ignored
* since Spring's interceptor does not even kick in for such a runtime scenario.
* For a more advanced mode of interception, consider switching this to
* {@link AdviceMode#ASPECTJ}.
*/
AdviceMode mode() default AdviceMode.PROXY;
/**
* Indicate the order in which the {@link AsyncAnnotationBeanPostProcessor}
* should be applied.
*
The default is {@link Ordered#LOWEST_PRECEDENCE} in order to run
* after all other post-processors, so that it can add an advisor to
* existing proxies rather than double-proxy.
*/
int order() default Ordered.LOWEST_PRECEDENCE;
}
上面的几个属性通过注释都能很好地理解,多个字段的含义和我么在分析声明式事务时基本是一致的,我们主要看一下Import注解导入的AsyncConfigurationSelector的原理;
AsyncConfigurationSelector继承结构如下,可以看出它是一个ImportSelector,用来导入其它的配置类
AsyncConfigurationSelector的实现源码如下,可以看出根据不同的代理模式adviceMode,这里导入了不同的配置类,PROXY代理时,导入了ProxyAsyncConfiguration类,下面主要对该类进行分析;
/**
* Selects which implementation of {@link AbstractAsyncConfiguration} should be used based
* on the value of {@link EnableAsync#mode} on the importing {@code @Configuration} class.
*
* @author Chris Beams
* @since 3.1
* @see EnableAsync
* @see ProxyAsyncConfiguration
*/
public class AsyncConfigurationSelector extends AdviceModeImportSelector {
private static final String ASYNC_EXECUTION_ASPECT_CONFIGURATION_CLASS_NAME =
"org.springframework.scheduling.aspectj.AspectJAsyncConfiguration";
/**
* {@inheritDoc}
* @return {@link ProxyAsyncConfiguration} or {@code AspectJAsyncConfiguration} for
* {@code PROXY} and {@code ASPECTJ} values of {@link EnableAsync#mode()}, respectively
*/
@Override
public String[] selectImports(AdviceMode adviceMode) {
switch (adviceMode) {
case PROXY:
return new String[] { ProxyAsyncConfiguration.class.getName() };
case ASPECTJ:
return new String[] { ASYNC_EXECUTION_ASPECT_CONFIGURATION_CLASS_NAME };
default:
return null;
}
}
}
2. ProxyAsyncConfiguration异步代理配置类
ProxyAsyncConfiguration配置类的继承结构以及源码如下,可以看出父类AbstractAsyncConfiguration也是一个配置类;
/**
* {@code @Configuration} class that registers the Spring infrastructure beans necessary
* to enable proxy-based asynchronous method execution.
*
* @author Chris Beams
* @author Stephane Nicoll
* @since 3.1
* @see EnableAsync
* @see AsyncConfigurationSelector
*/
@Configuration
@Role(BeanDefinition.ROLE_INFRASTRUCTURE)
public class ProxyAsyncConfiguration extends AbstractAsyncConfiguration {
@Bean(name = TaskManagementConfigUtils.ASYNC_ANNOTATION_PROCESSOR_BEAN_NAME)
@Role(BeanDefinition.ROLE_INFRASTRUCTURE)
public AsyncAnnotationBeanPostProcessor asyncAdvisor() {
Assert.notNull(this.enableAsync, "@EnableAsync annotation metadata was not injected");
AsyncAnnotationBeanPostProcessor bpp = new AsyncAnnotationBeanPostProcessor();
Class customAsyncAnnotation = this.enableAsync.getClass("annotation");
if (customAsyncAnnotation != AnnotationUtils.getDefaultValue(EnableAsync.class, "annotation")) {
bpp.setAsyncAnnotationType(customAsyncAnnotation);
}
if (this.executor != null) {
bpp.setExecutor(this.executor);
}
if (this.exceptionHandler != null) {
bpp.setExceptionHandler(this.exceptionHandler);
}
bpp.setProxyTargetClass(this.enableAsync.getBoolean("proxyTargetClass"));
bpp.setOrder(this.enableAsync.getNumber("order"));
return bpp;
}
}
ProxyAsyncConfiguration的源码比较简单,通过在父类AbstractAsyncConfiguration中解析到的enableAsync注解,构造了AsyncAnnotationBeanPostProcessor,并进行了bean化,后面再进一步展开分析;
enableAsync注解是在父类AbstractAsyncConfiguration初始化的,下面看一下该注解的初始化过程:
/**
* Abstract base {@code Configuration} class providing common structure for enabling
* Spring's asynchronous method execution capability.
*
* @author Chris Beams
* @author Stephane Nicoll
* @since 3.1
* @see EnableAsync
*/
@Configuration
public abstract class AbstractAsyncConfiguration implements ImportAware {
protected AnnotationAttributes enableAsync;
protected Executor executor;
protected AsyncUncaughtExceptionHandler exceptionHandler;
@Override
public void setImportMetadata(AnnotationMetadata importMetadata) {
this.enableAsync = AnnotationAttributes.fromMap(
importMetadata.getAnnotationAttributes(EnableAsync.class.getName(), false));
if (this.enableAsync == null) {
throw new IllegalArgumentException(
"@EnableAsync is not present on importing class " + importMetadata.getClassName());
}
}
/**
* Collect any {@link AsyncConfigurer} beans through autowiring.
*/
@Autowired(required = false)
void setConfigurers(Collection configurers) {
if (CollectionUtils.isEmpty(configurers)) {
return;
}
if (configurers.size() > 1) {
throw new IllegalStateException("Only one AsyncConfigurer may exist");
}
AsyncConfigurer configurer = configurers.iterator().next();
this.executor = configurer.getAsyncExecutor();
this.exceptionHandler = configurer.getAsyncUncaughtExceptionHandler();
}
}
由上,可以看出,
该配置类通过实现ImportAware接口,在接口方法setImportMetadata中完成了enableAsync的解析;
方法setConfigurers通过自动注入的方式获取容器中AsyncConfigurer的实现类,分别获取了执行器和异常处理器;
AbstractAsyncConfiguration中构造完成的成员变量都在ProxyAsyncConfiguration中,用于完成AsyncAnnotationBeanPostProcessor的创建,下面单独分析下AsyncAnnotationBeanPostProcessor的实现原理;
3. AsyncAnnotationBeanPostProcessor
首先看一下AsyncAnnotationBeanPostProcessor整体的实现结构:
由继承结构可以看出,AsyncAnnotationBeanPostProcessor是一个Bean后处理器,同时实现了BeanFactoryAware接口,下面分别分析下这两个接口的实现逻辑;
3.1 BeanFactoryAware实现逻辑
BeanFactoryAware接口是由AbstractBeanFactoryAwareAdvisingPostProcessor直接实现的,同时AsyncAnnotationBeanPostProcessor对该接口方法进行了覆盖,首先看下这两个方法的具体实现:
//AsyncAnnotationBeanPostProcessor实现如下:
@Override
public void setBeanFactory(BeanFactory beanFactory) {
super.setBeanFactory(beanFactory);
AsyncAnnotationAdvisor advisor = new AsyncAnnotationAdvisor(this.executor, this.exceptionHandler);
if (this.asyncAnnotationType != null) {
advisor.setAsyncAnnotationType(this.asyncAnnotationType);
}
advisor.setBeanFactory(beanFactory);
this.advisor = advisor;
}
//AbstractBeanFactoryAwareAdvisingPostProcessor实现如下:
@Override
public void setBeanFactory(BeanFactory beanFactory) {
this.beanFactory = (beanFactory instanceof ConfigurableListableBeanFactory ?
(ConfigurableListableBeanFactory) beanFactory : null);
}
在AsyncAnnotationBeanPostProcessor的实现中,这里实例化了一个异步注解切面AsyncAnnotationAdvisor,最后赋值到了成员变量advisor上面,后面在bean后处理器中会应用该切面;
在实例化异步切面AsyncAnnotationAdvisor时,主要完成了切点和增强的构造,如下:
/**
* Create a new {@code AsyncAnnotationAdvisor} for the given task executor.
* @param executor the task executor to use for asynchronous methods
* (can be {@code null} to trigger default executor resolution)
* @param exceptionHandler the {@link AsyncUncaughtExceptionHandler} to use to
* handle unexpected exception thrown by asynchronous method executions
* @see AnnotationAsyncExecutionInterceptor#getDefaultExecutor(BeanFactory)
*/
@SuppressWarnings("unchecked")
public AsyncAnnotationAdvisor(Executor executor, AsyncUncaughtExceptionHandler exceptionHandler) {
Set> asyncAnnotationTypes = new LinkedHashSet>(2);
asyncAnnotationTypes.add(Async.class);
try {
asyncAnnotationTypes.add((Class)
ClassUtils.forName("javax.ejb.Asynchronous", AsyncAnnotationAdvisor.class.getClassLoader()));
}
catch (ClassNotFoundException ex) {
// If EJB 3.1 API not present, simply ignore.
}
if (exceptionHandler != null) {
this.exceptionHandler = exceptionHandler;
}
else {
this.exceptionHandler = new SimpleAsyncUncaughtExceptionHandler();
}
this.advice = buildAdvice(executor, this.exceptionHandler);
this.pointcut = buildPointcut(asyncAnnotationTypes);
}
为了更深入的理解切面的实现逻辑,这里再分别对切点和增强进行展开说明
3.1.1 异步注解增强/拦截器AnnotationAsyncExecutionInterceptor的原理
AnnotationAsyncExecutionInterceptor是在buildAdvice方法中完成构造的,如下:
protected Advice buildAdvice(Executor executor, AsyncUncaughtExceptionHandler exceptionHandler) {
return new AnnotationAsyncExecutionInterceptor(executor, exceptionHandler);
}
其具体继承类图如下:
由此可见,AnnotationAsyncExecutionInterceptor是一个方法拦截器,其中接口MethodInterceptor的接口方式是在AsyncExecutionInterceptor中实现的,完成拦截逻辑的处理,如下:
/**
* Intercept the given method invocation, submit the actual calling of the method to
* the correct task executor and return immediately to the caller.
* @param invocation the method to intercept and make asynchronous
* @return {@link Future} if the original method returns {@code Future}; {@code null}
* otherwise.
*/
@Override
public Object invoke(final MethodInvocation invocation) throws Throwable {
Class targetClass = (invocation.getThis() != null ? AopUtils.getTargetClass(invocation.getThis()) : null);
Method specificMethod = ClassUtils.getMostSpecificMethod(invocation.getMethod(), targetClass);
final Method userDeclaredMethod = BridgeMethodResolver.findBridgedMethod(specificMethod);
AsyncTaskExecutor executor = determineAsyncExecutor(userDeclaredMethod);
if (executor == null) {
throw new IllegalStateException(
"No executor specified and no default executor set on AsyncExecutionInterceptor either");
}
Callable task = new Callable() {
@Override
public Object call() throws Exception {
try {
Object result = invocation.proceed();
if (result instanceof Future) {
return ((Future) result).get();
}
}
catch (ExecutionException ex) {
handleError(ex.getCause(), userDeclaredMethod, invocation.getArguments());
}
catch (Throwable ex) {
handleError(ex, userDeclaredMethod, invocation.getArguments());
}
return null;
}
};
return doSubmit(task, executor, invocation.getMethod().getReturnType());
}
其中determineAsyncExecutor方法完成异步执行器executor的初始化,具体过程如下:
在解析异步执行器时,首先是根据@Async注解的value属性查找对应的标识符以及类型为Executor的自定义异步执行器,
当没有找到时,获取defaultExecutor,也及在AbstractAsyncConfiguration中通过自动注入AsyncConfigurer实现类指定的执行器;
当没有AsyncConfigurer实现类指定执行器时,会继续尝试获取bean容器中TaskExecutor类型的自定义任务执行器,以及beanName为taskExecutor,类型为Executor的执行器;
当上述几种方式都获取不到时,默认会new一个SimpleAsyncTaskExecutor,每次执行被注解方法时,单独创建一个Thread来执行
这部分的实现源码如下:
/**
* Determine the specific executor to use when executing the given method.
* Should preferably return an {@link AsyncListenableTaskExecutor} implementation.
* @return the executor to use (or {@code null}, but just if no default executor is available)
*/
protected AsyncTaskExecutor determineAsyncExecutor(Method method) {
AsyncTaskExecutor executor = this.executors.get(method);
if (executor == null) {
Executor targetExecutor;
String qualifier = getExecutorQualifier(method);
if (StringUtils.hasLength(qualifier)) {
targetExecutor = findQualifiedExecutor(this.beanFactory, qualifier);
}
else {
targetExecutor = this.defaultExecutor;
if (targetExecutor == null) {
synchronized (this.executors) {
if (this.defaultExecutor == null) {
this.defaultExecutor = getDefaultExecutor(this.beanFactory);
}
targetExecutor = this.defaultExecutor;
}
}
}
if (targetExecutor == null) {
return null;
}
executor = (targetExecutor instanceof AsyncListenableTaskExecutor ?
(AsyncListenableTaskExecutor) targetExecutor : new TaskExecutorAdapter(targetExecutor));
this.executors.put(method, executor);
}
return executor;
}
/**
* This implementation searches for a unique {@link org.springframework.core.task.TaskExecutor}
* bean in the context, or for an {@link Executor} bean named "taskExecutor" otherwise.
* If neither of the two is resolvable (e.g. if no {@code BeanFactory} was configured at all),
* this implementation falls back to a newly created {@link SimpleAsyncTaskExecutor} instance
* for local use if no default could be found.
* @see #DEFAULT_TASK_EXECUTOR_BEAN_NAME
*/
@Override
protected Executor getDefaultExecutor(BeanFactory beanFactory) {
Executor defaultExecutor = super.getDefaultExecutor(beanFactory);
return (defaultExecutor != null ? defaultExecutor : new SimpleAsyncTaskExecutor());
}
/**
* Retrieve or build a default executor for this advice instance.
* An executor returned from here will be cached for further use.
*
The default implementation searches for a unique {@link TaskExecutor} bean
* in the context, or for an {@link Executor} bean named "taskExecutor" otherwise.
* If neither of the two is resolvable, this implementation will return {@code null}.
* @param beanFactory the BeanFactory to use for a default executor lookup
* @return the default executor, or {@code null} if none available
* @since 4.2.6
* @see #findQualifiedExecutor(BeanFactory, String)
* @see #DEFAULT_TASK_EXECUTOR_BEAN_NAME
*/
protected Executor getDefaultExecutor(BeanFactory beanFactory) {
if (beanFactory != null) {
try {
// Search for TaskExecutor bean... not plain Executor since that would
// match with ScheduledExecutorService as well, which is unusable for
// our purposes here. TaskExecutor is more clearly designed for it.
return beanFactory.getBean(TaskExecutor.class);
}
catch (NoUniqueBeanDefinitionException ex) {
logger.debug("Could not find unique TaskExecutor bean", ex);
try {
return beanFactory.getBean(DEFAULT_TASK_EXECUTOR_BEAN_NAME, Executor.class);
}
catch (NoSuchBeanDefinitionException ex2) {
if (logger.isInfoEnabled()) {
logger.info("More than one TaskExecutor bean found within the context, and none is named " +
"'taskExecutor'. Mark one of them as primary or name it 'taskExecutor' (possibly " +
"as an alias) in order to use it for async processing: " + ex.getBeanNamesFound());
}
}
}
catch (NoSuchBeanDefinitionException ex) {
logger.debug("Could not find default TaskExecutor bean", ex);
try {
return beanFactory.getBean(DEFAULT_TASK_EXECUTOR_BEAN_NAME, Executor.class);
}
catch (NoSuchBeanDefinitionException ex2) {
logger.info("No task executor bean found for async processing: " +
"no bean of type TaskExecutor and no bean named 'taskExecutor' either");
}
// Giving up -> either using local default executor or none at all...
}
}
return null;
}
最后,拦截方法中doSubmit提交任务到选取的异步执行器executor中进行执行:
/**
* Delegate for actually executing the given task with the chosen executor.
* @param task the task to execute
* @param executor the chosen executor
* @param returnType the declared return type (potentially a {@link Future} variant)
* @return the execution result (potentially a corresponding {@link Future} handle)
*/
protected Object doSubmit(Callable task, AsyncTaskExecutor executor, Class returnType) {
if (completableFuturePresent) {
Future result = CompletableFutureDelegate.processCompletableFuture(returnType, task, executor);
if (result != null) {
return result;
}
}
if (ListenableFuture.class.isAssignableFrom(returnType)) {
return ((AsyncListenableTaskExecutor) executor).submitListenable(task);
}
else if (Future.class.isAssignableFrom(returnType)) {
return executor.submit(task);
}
else {
executor.submit(task);
return null;
}
}
3.1.2 切点AnnotationMatchingPointcut的执行逻辑
在buildPointCut方法中完成了切点的构造,如下:
/**
* Calculate a pointcut for the given async annotation types, if any.
* @param asyncAnnotationTypes the async annotation types to introspect
* @return the applicable Pointcut object, or {@code null} if none
*/
protected Pointcut buildPointcut(Set> asyncAnnotationTypes) {
ComposablePointcut result = null;
for (Class asyncAnnotationType : asyncAnnotationTypes) {
Pointcut cpc = new AnnotationMatchingPointcut(asyncAnnotationType, true);
Pointcut mpc = AnnotationMatchingPointcut.forMethodAnnotation(asyncAnnotationType);
if (result == null) {
result = new ComposablePointcut(cpc);
}
else {
result.union(cpc);
}
result = result.union(mpc);
}
return result;
}
这里为所以异步注解(@Async和自定义注解)定义了一个组合切点,完成切点的匹配:
在class上标注异步注解,或者在方法上标注异步注解;
3.2 BeanPostProcessor后处理器实现逻辑
bean后处理的接口实现是在抽象父类AbstractAdvisingBeanPostProcessor中完成的,如下:
@Override
public Object postProcessBeforeInitialization(Object bean, String beanName) {
return bean;
}
@Override
public Object postProcessAfterInitialization(Object bean, String beanName) {
if (bean instanceof AopInfrastructureBean) {
// Ignore AOP infrastructure such as scoped proxies.
return bean;
}
if (bean instanceof Advised) {
Advised advised = (Advised) bean;
if (!advised.isFrozen() && isEligible(AopUtils.getTargetClass(bean))) {
// Add our local Advisor to the existing proxy's Advisor chain...
if (this.beforeExistingAdvisors) {
advised.addAdvisor(0, this.advisor);
}
else {
advised.addAdvisor(this.advisor);
}
return bean;
}
}
if (isEligible(bean, beanName)) {
ProxyFactory proxyFactory = prepareProxyFactory(bean, beanName);
if (!proxyFactory.isProxyTargetClass()) {
evaluateProxyInterfaces(bean.getClass(), proxyFactory);
}
proxyFactory.addAdvisor(this.advisor);
customizeProxyFactory(proxyFactory);
return proxyFactory.getProxy(getProxyClassLoader());
}
// No async proxy needed.
return bean;
}
其中isEligible方法用来判定当前bean是否和当前异步注解切点匹配,如下:
/**
* Check whether the given class is eligible for advising with this
* post-processor's {@link Advisor}.
*
Implements caching of {@code canApply} results per bean target class.
* @param targetClass the class to check against
* @see AopUtils#canApply(Advisor, Class)
*/
protected boolean isEligible(Class targetClass) {
Boolean eligible = this.eligibleBeans.get(targetClass);
if (eligible != null) {
return eligible;
}
eligible = AopUtils.canApply(this.advisor, targetClass);
this.eligibleBeans.put(targetClass, eligible);
return eligible;
}
满足匹配条件时,调用代理工厂ProxyFactory,创建bean的动态代理,JDK动态代理或者CGLIB动态代理,具体代理执行的逻辑和我们在前面Spring源码:Aop源码分析中是完全一致的;
最后,异步注解的方法声明的类完成了动态代理过程,在执行增强逻辑,即拦截器方法的时候,将异步注解方法包装为一个task,放到异步执行器中进行调度执行;
————————————————
出处:https://blog.csdn.net/supzhili/article/details/99169875
你可能感兴趣的:(Spring boot @EnableAsync与@Async源码分析)
本地运行 DeepSeek-R1 的成本究竟多高?
前端javascript
ReactHook深入浅出CSS技巧与案例详解vue2与vue3技巧合集VueUse源码解读本地运行DeepSeek-R1的成本究竟多高?DeepSeek让人们对大规模生成式模型的追求更进一步,甚至有人想在本地跑下规模高达671B参数的版本。但要在家里开这种“巨无霸”,可不是闹着玩的:光是推理就对硬件提出了非常高的要求。这篇文章将大致拆解一下,如果真想在个人电脑上运行DeepSeek-R1,可能需
构建 Next.js 应用时的安全保障与风险防范措施
前端javascript
ReactHook深入浅出CSS技巧与案例详解vue2与vue3技巧合集VueUse源码解读在Web应用开发过程中,确保应用的安全性至关重要,这不仅能保护用户数据,还能防止应用本身遭受各种安全攻击。Next.js作为一款备受欢迎的React框架,内置了许多安全功能和推荐做法,但开发者仍需清楚地了解潜在的安全隐患,并采取合适的防范策略。一、Next.js安全问题概述尽管Next.js为构建安全应用提
PHIDATA智能体AGENT构建框架
何为标准
python
介绍Phidata是一个用于构建多模式代理和工作流的框架。利用记忆、知识、工具和推理构建代理。建立可以协同工作解决问题的代理团队。使用美观的AgentUI与您的代理和工作流程进行交互。安装pipinstallphidatapipinstallduckduckgo-search最基本的使用自主调用工具示例。使用duckduckgo搜索内容,需要自己定义.env文件可能需要科学上网,因为这个工具使用的
语音识别使用SenseVoiceSmall模型实现源码
丢了个猪
python 语音识别 深度学习 机器学习 语言模型
SenseVoiceSenseVoice是具有音频理解能力的音频基础模型,包括语音识别(ASR)、语种识别(LID)、语音情感识别(SER)和声学事件分类(AEC)或声学事件检测(AED)。本项目提供SenseVoice模型的介绍以及在多个任务测试集上的benchmark,以及体验模型所需的环境安装的与推理方式。pip安装pipinstallmodelscopepipinstallfunasrpi
python异步编程实例_python 异步编程
weixin_39585070
python异步编程实例
Python3.5协程究竟是个啥Yushneng·Mar10th,2016作者是Python语言的核心开发人员,这篇文章也是我分享的,但是在翻译之前并没有看得太仔细。作者在这篇文章里先是是从Python异步编程的发展历史一直介绍到Python3.5中async/await新特性的提出,又从底层的实现的差异一直延伸到完整的代码实例,来说明旧的生成器作为协程的“权宜之计”与新语法的差别。真正做到了深入
流形拓扑学:Chern数与Euler示性数
AI天才研究院
DeepSeek R1 & 大数据AI人工智能大模型 AI大模型企业级应用开发实战 AI大模型应用入门实战与进阶 计算科学 神经计算 深度学习 神经网络 大数据 人工智能 大型语言模型 AI AGI LLM Java Python 架构设计 Agent RPA
流形拓扑学:Chern数与Euler示性数1.背景介绍流形拓扑学是数学中一个重要的分支,研究流形的拓扑性质。流形是局部类似于欧几里得空间的空间,广泛应用于物理学、计算机科学和工程学等领域。Chern数和Euler示性数是流形拓扑学中的两个重要不变量,它们在描述流形的几何和拓扑性质方面起着关键作用。Chern数是由中国数学家陈省身提出的,主要用于描述复流形的特征类。Euler示性数则是一个更为古老的
深入解析 Flutter 高级路由管理:使用 go_router 和 auto_route 实现复杂路由与拦截
陈皮话梅糖@
flutter 路由 路由拦截
深入解析Flutter高级路由管理:使用go_router和auto_route实现复杂路由与拦截在Flutter中,随着应用规模的增长,路由管理变得越来越复杂。简单的Navigator和命名路由可能难以满足需求,比如嵌套路由、动态路由参数、路由守卫(如登录验证)等。为了解决这些问题,Flutter社区提供了强大的第三方路由库,如go_router和auto_route。本篇博客将深入探讨如何使用
R语言中的函数32:seq_along()
zoujiahui_2018
# R语言中的函数 r语言 开发语言
介绍seq_along函数在R语言中用于生成一个整数序列,其长度与给定对象的长度相同。这个函数特别有用,当你想要创建一个索引序列来遍历一个向量或列表时。用法seq_along(x)参数x:任何R对象(如向量、列表等)。返回值:返回一个从1到x的长度的整数序列。示例#创建一个向量vec<-c("a","b","c")#使用seq_along生成索引indices<-seq_along(vec)pri
acwing搜索与图论(二)spfa
一缕叶
算法 图论 算法
#include#include#include#includeusingnamespacestd;typedefpairPII;constintN=10010;intn,m;inth[N],e[N],ne[N],w[N],idx;intdist[N];boolst[N];voidadd(inta,intb,intc){e[idx]=b,ne[idx]=h[a],w[idx]=c,h[a]=idx
python实现将RGB相机与事件相机的照片信息进行融合以进行目标检测
go5463158465
python 算法 python 数码相机 目标检测
要将RGB相机与事件相机的照片信息进行融合以进行目标检测,我们可以按以下步骤进行:整体思路数据读取:分别读取RGB图像和事件相机数据。数据预处理:对RGB图像和事件数据进行必要的预处理,如调整尺寸、归一化等。数据融合:将预处理后的RGB图像和事件数据进行融合。目标检测:使用融合后的数据进行目标检测。代码实现importcv2importnumpyasnpimporttorchfromtorchvi
编程语言的深度剖析:从语法到性能优化
大梦百万秋
性能优化
引言随着软件开发的不断进化,编程语言的选择对项目的成功与否具有关键影响。今天的开发者面临着丰富多样的编程语言选择:每一种语言都有独特的优势、特性和适用场景。然而,语言的设计理念、运行机制和优化技巧背后的技术细节却常常被忽视。本文将深入剖析一些现代编程语言的技术性细节,重点关注语法设计、运行时效率、内存管理和性能优化策略。1.语法与设计理念1.1静态类型vs动态类型编程语言通常根据类型系统分为静态类
四元数:连接四维时空与三维旋转的数学桥梁
aichitang2024
算法 数学知识点讲解 四元数 线性代数
四元数:连接四维时空与三维旋转的数学桥梁引言1843年,威廉·哈密顿在都柏林布鲁姆桥的顿悟,不仅诞生了四元数理论,更开创了高维数在三维空间应用的新纪元。本文将揭示四元数如何架起四维数学空间与三维物理世界的桥梁。一、四元数基础架构1.代数定义四元数是形如的超复数:q=w+xi+yj+zk其中:w为实部(Scalar)(x,y,z)为虚部(Vector)i²=j²=k²=ijk=-12.基本运算规则运
闵氏几何详解
aichitang2024
算法 数学知识点讲解 几何学 闵可夫斯基几何
闵氏几何详解闵氏几何(Minkowskigeometry)最初由数学家赫尔曼·闵可夫斯基(HermannMinkowski)提出,是现代几何学和理论物理的重要分支。它既与爱因斯坦的狭义相对论密切相关,也在更普遍的度量空间研究中占有显赫地位。本文将对闵氏几何的基础概念、结构、在物理中的用途以及与其他几何的对比等方面进行详细介绍。一、历史背景与概念渊源提出背景19世纪末到20世纪初,数学家们在研究欧几
鸿蒙5.0实战案例:关于图像撕裂、掉帧等异常现象的原理以及优化方案
敢嗣先锋
鸿蒙开发 HarmonyOS 移动开发 harmonyos 鸿蒙开发 openharmony 移动开发 ArkUI 性能优化
往期推文全新看点(文中附带全新鸿蒙5.0全栈学习笔录)✏️鸿蒙(HarmonyOS)北向开发知识点记录~✏️鸿蒙(OpenHarmony)南向开发保姆级知识点汇总~✏️鸿蒙应用开发与鸿蒙系统开发哪个更有前景?✏️嵌入式开发适不适合做鸿蒙南向开发?看完这篇你就了解了~✏️对于大前端开发来说,转鸿蒙开发究竟是福还是祸?✏️鸿蒙岗位需求突增!移动端、PC端、IoT到底该怎么选?✏️记录一场鸿蒙开发岗位面
DeepSeek的实用方法DeepSeek+kimi生成PPT
C_V_Better
AI人工智能 人工智能 ppt ai
在人工智能领域,DeepSeek和KimiAI作为强大的语言模型,为开发者和普通用户提供了丰富的功能。本文将详细介绍DeepSeek的实用方法,以及如何结合KimiAI生成PPT,帮助您快速上手并发挥其强大能力。一、DeepSeek的使用方法(一)注册与登录访问官网:打开浏览器,输入DeepSeek官网。注册账号:点击“注册”按钮,填写邮箱地址、设置密码,并完成邮箱验证。登录:注册成功后,使用注册
【一文读懂】JS与Java的区别
Bl_a_ck
JS进阶 javascript java 开发语言
相同点这两个语言除了注释长得差不多之外就没什么相同点了不同点设计初衷:JS从开发到上线就经历了10天的时间,最初的目的是实现网页端的动态交互效果,由于设计时间太短,语言的一些细节考虑得不够严谨,导致后来很长一段时间,Javascript写出来的程序混乱不堪。所以现在有了TS来代替JSJava设计用于编写跨平台的、运行在虚拟机上的应用程序设计理念:Java是典型的面相对象的语言,具有面向对象的三大特
上位机知识篇---sbit、bit、sfr
Ronin-Lotus
上位机操作篇 程序代码篇 嵌入式硬件篇 单片机 嵌入式硬件 c sbit bit sfr 蓝桥杯
文章目录前言1.sbit的使用语法特点作用范围存储位置用途示例代码2.bit的使用语法特点作用范围存储位置用途示例代码3.sbit与bit的区别4.综合示例5.注意事项sbit的适用范围:bit的存储限制编译器支持6.总结sbitbit7.sfr的使用1.sfr的语法2.sfr的作用访问硬件资源提高代码可读性简化代码:3.8051单片机中常见的SFR4.sfr的使用示例示例1:控制GPIO端口示例
资本资产定价模型(CAPM, Capital Asset Pricing Model)通俗解析
阿正的梦工坊
Finance 金融
现代资产定价理论:CAPM模型通俗解析在金融领域,如何定价一个资产(如股票、债券等)是一个至关重要的问题。而资本资产定价模型(CAPM,CapitalAssetPricingModel)就是现代资产定价理论中的一块基石。它帮助我们理解不同资产的风险与回报之间的关系,以及如何在投资组合中分配资金以获得最优的回报。今天,我们来一起通俗易懂地探讨一下CAPM模型的原理、公式、以及它的实际应用。CAPM模
DeepSeek专利:分布式系统的“去重神器”,如何让数据传输效率飙升?
CodePatentMaster
php 网络 安全
“DeepSeek的这项专利(CN111064587A),通过创新的冗余数据消除机制,让分布式系统的数据传输效率提升50%,网络延迟降低30%!”一、技术分析:DeepSeek专利的核心价值1.技术背景:解决分布式系统中的冗余数据与网络拥塞问题在分布式系统中,数据通过广播式传输时,往往会经过多个路径转发,导致大量冗余数据的产生。这些冗余数据不仅占用存储空间,还会增加网络传输负担,导致网络拥塞和延迟
Web开发中的可专利性分析:透过一个案例学习
CodePatentMaster
前端 学习
Web开发工程师在创新过程中经常面临是否能申请专利并获得专利权的问题。本文通过一个详细的Web开发领域案例来阐释可专利性的分析过程。案例分析假设您是一名Web开发工程师,您开发了一种名为“动态响应式前端框架”(DynamicResponsiveFrontendFramework,DRFF)的新型前端框架。与传统前端框架相比,DRFF通过引入一种基于AI的组件化设计方法和实时数据流处理机制,显著提高
[从零开始的 Vue3 系列]:第四章——Vue3 中常用组件通信全解析
花信少年plus
从零开始的vue3 系列 vue.js javascript 前端
前言本系列将从零开始,系统性地介绍Vue3的常用API,逐步深入每个核心概念与功能模块。通过详尽的讲解与实战演示,帮助大家掌握Vue3的基础与进阶知识,最终具备独立搭建完整Vue3项目的能力。vue3中的组件通信Vue3提供了多种方式来进行组件之间的通信。根据场景的不同,开发者可以选择最合适的方式进行数据的传递与事件的处理。1.通过Props传递数据(父->子)父组件:importChildCom
SpringBoot 新手入门(实操)
李恩11
spring boot 后端 java
SpringBoot是一个开源框架,旨在简化基于Spring的Java应用程序的开发。它通过提供一系列默认配置和约定大于配置的理念,让开发者可以更快速地创建和部署应用。以下是一个SpringBoot新手入门的实操指南,帮助你从零开始创建一个简单的SpringBoot应用程序。环境准备安装JDK:SpringBoot需要JavaDevelopmentKit(JDK)8或更高版本。你可以从Oracle
结构体与位段
bbppooi
c语言学习 c语言 数据结构
结构体类型的声明结构是⼀些值的集合,这些值称为成员变量。结构的每个成员可以是不同类型的变量结构的声明structtag{member-list;}variable-list;例子structbook{chartitle[MAXTITL];//字符串类型的titilecharauthor[MAXAUTL];//字符串类型的authorfloatvalue;//浮点型的value};关于其声明的位置,
常用的高性能计算工具有哪些
这题有点难度
人工智能 学习
在当今数字化时代,高性能计算(HPC)已成为推动科学、工程、技术以及商业创新的核心力量。无论是模拟宇宙的起源、设计新型航空器,还是训练复杂的人工智能模型,HPC都扮演着不可或缺的角色。本文将深入探讨高性能计算的定义、其背后的强大工具,以及它们如何助力各领域的突破性发展。一、高性能计算:定义与意义高性能计算(HPC)是一种利用超级计算机或大规模集群来处理复杂计算任务的技术。它通过并行计算和优化算法,
《Spring实战》读书笔记-第3章 高级装配
2401_89790580
spring oracle 数据库
Spring表达式语言在上一章中,我们看到了一些最为核心的bean装配技术。你可能会发现上一章学到的知识有很大的用处。但是,bean装配所涉及的领域并不仅仅局限于上一章所学习到的内容。Spring提供了多种技巧,借助它们可以实现更为高级的bean装配功能。在本章中,我们将会深入介绍一些这样的高级技术。本章中所介绍的技术也许你不会天天都用到,但这并不意味着它们的价值会因此而降低。3.1环境与prof
C语言分支语句
2401_88435596
c语言 开发语言 笔记 改行学it
C语言中分支语句主要有以下几种:一.ifinta=1;if(2==a)printf("hehe\n);ifelseif(1==a)printf("hehe\n");elseprintf("haha\n");ifelsefielseif(a=18&&a<60)printf("青壮年");elseprintf("老年");注意:当有多个if时,else与离它最近的if配对二.switchcase---
Django 5实用指南(二)项目结构与管理
网络风云
python django 后端
2.1Django5项目结构概述当你创建一个新的Django项目时,Django会自动生成一个默认的项目结构。这个结构是根据Django的最佳实践来设计的,以便开发者能够清晰地管理和维护项目中的各种组件。理解并管理好这些文件和目录结构是Django开发的基础。假设你使用django-adminstartprojectmyproject命令创建了一个新项目,下面是一个典型的Django5项目的文件结
Spring Boot 中自动装配机制的原理
李恩11
java spring boot 开发语言
SpringBoot的自动装配机制是其核心特性之一,它简化了Spring应用的配置,让开发者能够快速构建应用。以下是对其原理的详细总结:1.核心概念自动装配(Auto-configuration):SpringBoot根据应用依赖和配置,自动配置SpringBean的过程。条件化配置(ConditionalConfiguration):根据特定条件决定是否启用某个配置类或Bean。SpringBo
JAX-WS与JAX-RS比较分析及与SpringMVC集成实现
零度anngle
SpringMVC Restful spring mvc JAX-RS JAX-WS
1、导言过去几年,REST逐渐成为影响Web框架、Web协议与Web应用设计的重要概念。如果你还不了解REST,那这个简短的介绍将有助你快速掌握REST,此外还可以点击这里了解关于REST的更多信息。现在有越来越多的公司希望能以简单而又贴合Web架构本身的方式公开WebAPI,因此REST变得越来越重要也就不足为奇了。使用Ajax进行通信的富浏览器端也在朝这个目标不断迈进。这个架构原则提升了万维网
xml:schema详解
yippeelyl
Android java
XMLSchema详解博客分类:XMLXML数据结构正则表达式Struts什么是Schema?在计算机软件中,Schema这个词在不同的应用中有不同的含义,可以翻译为:架构、结构、规则、模式等。在XML中,Schema指的是定义和描述XML文档的规则,翻译为模式。XMLSchema与DTD的比较我们看例4-3所示的XML文档。例4-3employee.xml张三26zhangsan@sunxin.
apache 安装linux windows
墙头上一根草
apache inux windows
linux安装Apache 有两种方式一种是手动安装通过二进制的文件进行安装,另外一种就是通过yum 安装,此中安装方式,需要物理机联网。以下分别介绍两种的安装方式
通过二进制文件安装Apache需要的软件有apr,apr-util,pcre
1,安装 apr 下载地址:htt
fill_parent、wrap_content和match_parent的区别
Cb123456
match_parent fill_parent
fill_parent、wrap_content和match_parent的区别:
1)fill_parent
设置一个构件的布局为fill_parent将强制性地使构件扩展,以填充布局单元内尽可能多的空间。这跟Windows控件的dockstyle属性大体一致。设置一个顶部布局或控件为fill_parent将强制性让它布满整个屏幕。
2) wrap_conte
网页自适应设计
天子之骄
html css 响应式设计 页面自适应
网页自适应设计
网页对浏览器窗口的自适应支持变得越来越重要了。自适应响应设计更是异常火爆。再加上移动端的崛起,更是如日中天。以前为了适应不同屏幕分布率和浏览器窗口的扩大和缩小,需要设计几套css样式,用js脚本判断窗口大小,选择加载。结构臃肿,加载负担较大。现笔者经过一定时间的学习,有所心得,故分享于此,加强交流,共同进步。同时希望对大家有所
[sql server] 分组取最大最小常用sql
一炮送你回车库
SQL Server
--分组取最大最小常用sql--测试环境if OBJECT_ID('tb') is not null drop table tb;gocreate table tb( col1 int, col2 int, Fcount int)insert into tbselect 11,20,1 union allselect 11,22,1 union allselect 1
ImageIO写图片输出到硬盘
3213213333332132
java image
package awt;
import java.awt.Color;
import java.awt.Font;
import java.awt.Graphics;
import java.awt.image.BufferedImage;
import java.io.File;
import java.io.IOException;
import javax.imagei
自己的String动态数组
宝剑锋梅花香
java 动态数组 数组
数组还是好说,学过一两门编程语言的就知道,需要注意的是数组声明时需要把大小给它定下来,比如声明一个字符串类型的数组:String str[]=new String[10]; 但是问题就来了,每次都是大小确定的数组,我需要数组大小不固定随时变化怎么办呢? 动态数组就这样应运而生,龙哥给我们讲的是自己用代码写动态数组,并非用的ArrayList 看看字符
pinyin4j工具类
darkranger
.net
pinyin4j工具类Java工具类 2010-04-24 00:47:00 阅读69 评论0 字号:大中小
引入pinyin4j-2.5.0.jar包:
pinyin4j是一个功能强悍的汉语拼音工具包,主要是从汉语获取各种格式和需求的拼音,功能强悍,下面看看如何使用pinyin4j。
本人以前用AscII编码提取工具,效果不理想,现在用pinyin4j简单实现了一个。功能还不是很完美,
StarUML学习笔记----基本概念
aijuans
UML建模
介绍StarUML的基本概念,这些都是有效运用StarUML?所需要的。包括对模型、视图、图、项目、单元、方法、框架、模型块及其差异以及UML轮廓。
模型、视与图(Model, View and Diagram)
&
Activiti最终总结
avords
Activiti id 工作流
1、流程定义ID:ProcessDefinitionId,当定义一个流程就会产生。
2、流程实例ID:ProcessInstanceId,当开始一个具体的流程时就会产生,也就是不同的流程实例ID可能有相同的流程定义ID。
3、TaskId,每一个userTask都会有一个Id这个是存在于流程实例上的。
4、TaskDefinitionKey和(ActivityImpl activityId
从省市区多重级联想到的,react和jquery的差别
bee1314
jquery UI react
在我们的前端项目里经常会用到级联的select,比如省市区这样。通常这种级联大多是动态的。比如先加载了省,点击省加载市,点击市加载区。然后数据通常ajax返回。如果没有数据则说明到了叶子节点。 针对这种场景,如果我们使用jquery来实现,要考虑很多的问题,数据部分,以及大量的dom操作。比如这个页面上显示了某个区,这时候我切换省,要把市重新初始化数据,然后区域的部分要从页面
Eclipse快捷键大全
bijian1013
java eclipse 快捷键
Ctrl+1 快速修复(最经典的快捷键,就不用多说了)Ctrl+D: 删除当前行 Ctrl+Alt+↓ 复制当前行到下一行(复制增加)Ctrl+Alt+↑ 复制当前行到上一行(复制增加)Alt+↓ 当前行和下面一行交互位置(特别实用,可以省去先剪切,再粘贴了)Alt+↑ 当前行和上面一行交互位置(同上)Alt+← 前一个编辑的页面Alt+→ 下一个编辑的页面(当然是针对上面那条来说了)Alt+En
js 笔记 函数
征客丶
JavaScript
一、函数的使用
1.1、定义函数变量
var vName = funcation(params){
}
1.2、函数的调用
函数变量的调用: vName(params);
函数定义时自发调用:(function(params){})(params);
1.3、函数中变量赋值
var a = 'a';
var ff
【Scala四】分析Spark源代码总结的Scala语法二
bit1129
scala
1. Some操作
在下面的代码中,使用了Some操作:if (self.partitioner == Some(partitioner)),那么Some(partitioner)表示什么含义?首先partitioner是方法combineByKey传入的变量,
Some的文档说明:
/** Class `Some[A]` represents existin
java 匿名内部类
BlueSkator
java匿名内部类
组合优先于继承
Java的匿名类,就是提供了一个快捷方便的手段,令继承关系可以方便地变成组合关系
继承只有一个时候才能用,当你要求子类的实例可以替代父类实例的位置时才可以用继承。
在Java中内部类主要分为成员内部类、局部内部类、匿名内部类、静态内部类。
内部类不是很好理解,但说白了其实也就是一个类中还包含着另外一个类如同一个人是由大脑、肢体、器官等身体结果组成,而内部类相
盗版win装在MAC有害发热,苹果的东西不值得买,win应该不用
ljy325
游戏 apple windows XP OS
Mac mini 型号: MC270CH-A RMB:5,688
Apple 对windows的产品支持不好,有以下问题:
1.装完了xp,发现机身很热虽然没有运行任何程序!貌似显卡跑游戏发热一样,按照那样的发热量,那部机子损耗很大,使用寿命受到严重的影响!
2.反观安装了Mac os的展示机,发热量很小,运行了1天温度也没有那么高
&nbs
读《研磨设计模式》-代码笔记-生成器模式-Builder
bylijinnan
java 设计模式
声明: 本文只为方便我个人查阅和理解,详细的分析以及源代码请移步 原作者的博客http://chjavach.iteye.com/
/**
* 生成器模式的意图在于将一个复杂的构建与其表示相分离,使得同样的构建过程可以创建不同的表示(GoF)
* 个人理解:
* 构建一个复杂的对象,对于创建者(Builder)来说,一是要有数据来源(rawData),二是要返回构
JIRA与SVN插件安装
chenyu19891124
SVN jira
JIRA安装好后提交代码并要显示在JIRA上,这得需要用SVN的插件才能看见开发人员提交的代码。
1.下载svn与jira插件安装包,解压后在安装包(atlassian-jira-subversion-plugin-0.10.1)
2.解压出来的包里下的lib文件夹下的jar拷贝到(C:\Program Files\Atlassian\JIRA 4.3.4\atlassian-jira\WEB
常用数学思想方法
comsci
工作
对于搞工程和技术的朋友来讲,在工作中常常遇到一些实际问题,而采用常规的思维方式无法很好的解决这些问题,那么这个时候我们就需要用数学语言和数学工具,而使用数学工具的前提却是用数学思想的方法来描述问题。。下面转帖几种常用的数学思想方法,仅供学习和参考
函数思想
把某一数学问题用函数表示出来,并且利用函数探究这个问题的一般规律。这是最基本、最常用的数学方法
pl/sql集合类型
daizj
oracle 集合 type pl/sql
--集合类型
/*
单行单列的数据,使用标量变量
单行多列数据,使用记录
单列多行数据,使用集合(。。。)
*集合:类似于数组也就是。pl/sql集合类型包括索引表(pl/sql table)、嵌套表(Nested Table)、变长数组(VARRAY)等
*/
/*
--集合方法
&n
[Ofbiz]ofbiz初用
dinguangx
电商 ofbiz
从github下载最新的ofbiz(截止2015-7-13),从源码进行ofbiz的试用
1. 加载测试库
ofbiz内置derby,通过下面的命令初始化测试库
./ant load-demo (与load-seed有一些区别)
2. 启动内置tomcat
./ant start
或
./startofbiz.sh
或
java -jar ofbiz.jar
&
结构体中最后一个元素是长度为0的数组
dcj3sjt126com
c gcc
在Linux源代码中,有很多的结构体最后都定义了一个元素个数为0个的数组,如/usr/include/linux/if_pppox.h中有这样一个结构体: struct pppoe_tag { __u16 tag_type; __u16 tag_len; &n
Linux cp 实现强行覆盖
dcj3sjt126com
linux
发现在Fedora 10 /ubutun 里面用cp -fr src dest,即使加了-f也是不能强行覆盖的,这时怎么回事的呢?一两个文件还好说,就输几个yes吧,但是要是n多文件怎么办,那还不输死人呢?下面提供三种解决办法。 方法一
我们输入alias命令,看看系统给cp起了一个什么别名。
[root@localhost ~]# aliasalias cp=’cp -i’a
Memcached(一)、HelloWorld
frank1234
memcached
一、简介
高性能的架构离不开缓存,分布式缓存中的佼佼者当属memcached,它通过客户端将不同的key hash到不同的memcached服务器中,而获取的时候也到相同的服务器中获取,由于不需要做集群同步,也就省去了集群间同步的开销和延迟,所以它相对于ehcache等缓存来说能更好的支持分布式应用,具有更强的横向伸缩能力。
二、客户端
选择一个memcached客户端,我这里用的是memc
Search in Rotated Sorted Array II
hcx2013
search
Follow up for "Search in Rotated Sorted Array":What if duplicates are allowed?
Would this affect the run-time complexity? How and why?
Write a function to determine if a given ta
Spring4新特性——更好的Java泛型操作API
jinnianshilongnian
spring4 generic type
Spring4新特性——泛型限定式依赖注入
Spring4新特性——核心容器的其他改进
Spring4新特性——Web开发的增强
Spring4新特性——集成Bean Validation 1.1(JSR-349)到SpringMVC
Spring4新特性——Groovy Bean定义DSL
Spring4新特性——更好的Java泛型操作API
Spring4新
CentOS安装JDK
liuxingguome
centos
1、行卸载原来的:
[root@localhost opt]# rpm -qa | grep java
tzdata-java-2014g-1.el6.noarch
java-1.7.0-openjdk-1.7.0.65-2.5.1.2.el6_5.x86_64
java-1.6.0-openjdk-1.6.0.0-11.1.13.4.el6.x86_64
[root@localhost
二分搜索专题2-在有序二维数组中搜索一个元素
OpenMind
二维数组 算法 二分搜索
1,设二维数组p的每行每列都按照下标递增的顺序递增。
用数学语言描述如下:p满足
(1),对任意的x1,x2,y,如果x1<x2,则p(x1,y)<p(x2,y);
(2),对任意的x,y1,y2, 如果y1<y2,则p(x,y1)<p(x,y2);
2,问题:
给定满足1的数组p和一个整数k,求是否存在x0,y0使得p(x0,y0)=k?
3,算法分析:
(
java 随机数 Math与Random
SaraWon
java Math Random
今天需要在程序中产生随机数,知道有两种方法可以使用,但是使用Math和Random的区别还不是特别清楚,看到一篇文章是关于的,觉得写的还挺不错的,原文地址是
http://www.oschina.net/question/157182_45274?sort=default&p=1#answers
产生1到10之间的随机数的两种实现方式:
//Math
Math.roun
oracle创建表空间
tugn
oracle
create temporary tablespace TXSJ_TEMP
tempfile 'E:\Oracle\oradata\TXSJ_TEMP.dbf'
size 32m
autoextend on
next 32m maxsize 2048m
extent m
使用Java8实现自己的个性化搜索引擎
yangshangchuan
java superword 搜索引擎 java8 全文检索
需要对249本软件著作实现句子级别全文检索,这些著作均为PDF文件,不使用现有的框架如lucene,自己实现的方法如下:
1、从PDF文件中提取文本,这里的重点是如何最大可能地还原文本。提取之后的文本,一个句子一行保存为文本文件。
2、将所有文本文件合并为一个单一的文本文件,这样,每一个句子就有一个唯一行号。
3、对每一行文本进行分词,建立倒排表,倒排表的格式为:词=包含该词的总行数N=行号