Categories
Uncategorized

Spring AOP, analyzing system (2)

Now, we will be to a proxy object of the process of the analysis.

In the Spring AOP, analyzing system ‘(a) for example, generate will object?

can see will generate six object, corresponding to, respectively:

: target object

logger: definition of tangent plane

: used to generate a proxy object in a post – processor, it is realized,type is

# 0: definition of notification

# 1: definition of notification

: pointcut expressions

Once we understand what makes these two objects and the generation of the process, then the proxy object is generated,It becomes clear.

a. the instantiation of the

Is a post – processor, and is used to bean object instantiation of some operations may be performed before and after.Here, to be precise in its method has been formed in the target object is generated by the proxy object,This method is a proxy object generated by the local, later re – analysis of this method.Now need to think about for this object. What is it?In fact it registered post processor when instantiated.The method enters

public void refresh() throws BeansException, IllegalStateException {
        synchronized (this.startupShutdownMonitor) {
            // Prepare this context for refreshing.
            prepareRefresh();

            // Tell the subclass to refresh the internal bean factory.
            ConfigurableListableBeanFactory beanFactory = obtainFreshBeanFactory();

            // Prepare the bean factory for use in this context.
            prepareBeanFactory(beanFactory);

            try {
                // Allows post-processing of the bean factory in context subclasses.
                postProcessBeanFactory(beanFactory);

                // Invoke factory processors registered as beans in the context.
                invokeBeanFactoryPostProcessors(beanFactory);

                // Register bean processors that intercept bean creation.
         

/ / into this method

registerBeanPostProcessors(beanFactory); // Initialize message source for this context. initMessageSource(); // Initialize event multicaster for this context. initApplicationEventMulticaster(); // Initialize other special beans in specific context subclasses. onRefresh(); // Check for listener beans and register them. registerListeners(); // Instantiate all remaining (non-lazy-init) singletons. finishBeanFactoryInitialization(beanFactory); // Last step: publish corresponding event. finishRefresh(); } catch (BeansException ex) { if (logger.isWarnEnabled()) { logger.warn("Exception encountered during context initialization - " + "cancelling refresh attempt: " + ex); } // Destroy already created singletons to avoid dangling resources. destroyBeans(); // Reset 'active' flag. cancelRefresh(ex); // Propagate exception to caller. throw ex; } finally { // Reset common introspection caches in Spring's core, since we // might not ever need metadata for singleton beans anymore... resetCommonCaches(); } } }

enters the method, and then can be traced to the following method

    public static void registerBeanPostProcessors(
            ConfigurableListableBeanFactory beanFactory, AbstractApplicationContext applicationContext) {
     

/ / acquired all of the post processor

  String[] postProcessorNames
= beanFactory.getBeanNamesForType(BeanPostProcessor.class, true, false); // Register BeanPostProcessorChecker that logs an info message when // a bean is created during BeanPostProcessor instantiation, i.e. when // a bean is not eligible for getting processed by all BeanPostProcessors. int beanProcessorTargetCount = beanFactory.getBeanPostProcessorCount() + 1 + postProcessorNames.length; beanFactory.addBeanPostProcessor(new BeanPostProcessorChecker(beanFactory, beanProcessorTargetCount));
//对这些后置处理器进行分类存储
// Separate between BeanPostProcessors that implement PriorityOrdered, // Ordered, and the rest. List priorityOrderedPostProcessors = new ArrayList(); List internalPostProcessors = new ArrayList(); List orderedPostProcessorNames = new ArrayList(); List nonOrderedPostProcessorNames = new ArrayList(); for (String ppName : postProcessorNames) { if (beanFactory.isTypeMatch(ppName, PriorityOrdered.class)) { BeanPostProcessor pp = beanFactory.getBean(ppName, BeanPostProcessor.class); priorityOrderedPostProcessors.add(pp); if (pp instanceof MergedBeanDefinitionPostProcessor) { internalPostProcessors.add(pp); } } else if (beanFactory.isTypeMatch(ppName, Ordered.class)) { orderedPostProcessorNames.add(ppName); } else { nonOrderedPostProcessorNames.add(ppName); } }
//以下这些就是针对不同类型的后置处理器分别进行注册实例化
// First, register the BeanPostProcessors that implement PriorityOrdered. sortPostProcessors(priorityOrderedPostProcessors, beanFactory); registerBeanPostProcessors(beanFactory, priorityOrderedPostProcessors); // Next, register the BeanPostProcessors that implement Ordered. List orderedPostProcessors = new ArrayList(); for

(String:) {instantiation in the pp

= beanFactory.getBean(ppName, BeanPostProcessor.class); orderedPostProcessors.add(pp); if (pp instanceof MergedBeanDefinitionPostProcessor) { internalPostProcessors.add(pp); } } sortPostProcessors(orderedPostProcessors, beanFactory); registerBeanPostProcessors(beanFactory, orderedPostProcessors); // Now, register all regular BeanPostProcessors. List nonOrderedPostProcessors = new ArrayList(); for (String ppName : nonOrderedPostProcessorNames) { BeanPostProcessor pp = beanFactory.getBean(ppName, BeanPostProcessor.class); nonOrderedPostProcessors.add(pp); if (pp instanceof MergedBeanDefinitionPostProcessor) { internalPostProcessors.add(pp); } } registerBeanPostProcessors(beanFactory, nonOrderedPostProcessors); // Finally, re-register all internal BeanPostProcessors. sortPostProcessors(internalPostProcessors, beanFactory); registerBeanPostProcessors(beanFactory, internalPostProcessors); // Re-register post-processor for detecting inner beans as ApplicationListeners, // moving it to the end of the processor chain (for picking up proxies etc). beanFactory.addBeanPostProcessor(new ApplicationListenerDetector(applicationContext)); }

Now the object has been generated, then for other bean is instantiated it can play a role in a post – processor due role.

2. The instantiations of

Target object instantiation process, and may also include a proxy object generated by the process, step by step through source code analysis.

entering class of the method

protected Object initializeBean(final String beanName, final Object bean, RootBeanDefinition mbd) {
        if (System.getSecurityManager() != null) {
            AccessController.doPrivileged(new PrivilegedAction() {
                @Override
                public Object run() {
                    invokeAwareMethods(beanName, bean);
                    return null;
                }
            }, getAccessControlContext());
        }
        else {
            invokeAwareMethods(beanName, bean);
        }

        Object wrappedBean = bean;
        if (mbd == null || !mbd.isSynthetic()) {

/ / the bean calls to all of the post - processor method

wrappedBean
= applyBeanPostProcessorsBeforeInitialization(wrappedBean, beanName); } try {

Call initialization methods

invokeInitMethods(beanName, wrappedBean, mbd); }
catch (Throwable ex) { throw new BeanCreationException( (mbd != null ? mbd.getResourceDescription() : null), beanName, "Invocation of init method failed", ex); } if (mbd == null || !mbd.isSynthetic()) {

/ / proxy object generated in this method is carried out in the

wrappedBean
= applyBeanPostProcessorsAfterInitialization(wrappedBean, beanName); } return wrappedBean; }

The method enters

    @Override
    public Object applyBeanPostProcessorsAfterInitialization(Object existingBean, String beanName)
            throws BeansException {

        Object result = existingBean;
        for (BeanPostProcessor beanProcessor : getBeanPostProcessors()) {

/ / acquired all of the post processor which operates on the bean and then enters the

/ / method in

result
= beanProcessor.postProcessAfterInitialization(result, beanName); if (result == null) { return result; } } return result; }

entering class of the method in

    public Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException {
        if (bean != null) {
            Object cacheKey = getCacheKey(bean.getClass(), beanName);
            if (!this.earlyProxyReferences.contains(cacheKey)) {
//进入这个方法
return wrapIfNecessary(bean, beanName, cacheKey); } } return bean; }

The method enters

    protected Object wrapIfNecessary(Object bean, String beanName, Object cacheKey) {
        if (beanName != null && this.targetSourcedBeans.contains(beanName)) {
            return bean;
        }
        if (Boolean.FALSE.equals(this.advisedBeans.get(cacheKey))) {
            return bean;
        }
        if (isInfrastructureClass(bean.getClass()) || shouldSkip(bean.getClass(), beanName)) {
            this.advisedBeans.put(cacheKey, Boolean.FALSE);
            return bean;
        }

        // Create proxy if we have advice.
    

The / / target beans, searching for the matching of the notifier

Object[] specificInterceptors = getAdvicesAndAdvisorsForBean(bean.getClass(), beanName, null); if (specificInterceptors != DO_NOT_PROXY) { this

.. put (Boolean,. TRUE); / / If notifier of array

is not empty, then the generated proxy object

            Object proxy = createProxy(
                    bean.getClass(), beanName, specificInterceptors, new SingletonTargetSource(bean));
            this.proxyTypes.put(cacheKey, proxy.getClass());
//把生成的代理对象放到容器中,此时beanName对应的对象不再是目标对象,而是代理对象。
return proxy; } this.advisedBeans.put(cacheKey, Boolean.FALSE); return bean; }

Next we go to the analysis of two methods: the target is the bean that match the query notification device and a proxy object generated by the method

1. The query notification device, the method enters

protected Object[] getAdvicesAndAdvisorsForBean(Class beanClass, String beanName, TargetSource targetSource) {

/ / entering method

List
advisors = findEligibleAdvisors(beanClass, beanName); if (advisors.isEmpty()) { return DO_NOT_PROXY; } return advisors.toArray(); }

The method enters

    protected List findEligibleAdvisors(Class beanClass, String beanName) {

// Find all of notifier

List
candidateAdvisors = findCandidateAdvisors();

/ / are then screened to a matching may be applied on the notifier

List
eligibleAdvisors = findAdvisorsThatCanApply(candidateAdvisors, beanClass, beanName); extendAdvisors(eligibleAdvisors); if (!eligibleAdvisors.isEmpty()) { eligibleAdvisors = sortAdvisors(eligibleAdvisors); } return eligibleAdvisors; }

2. the proxy object as a result of the processes, there are JDK dynamic proxies and cglib two generation mode, the default are JDK dynamic proxies

enters the method, this method is to generate the local proxy object

/**
     * Create an AOP proxy for the given bean.
     * @param beanClass the class of the bean
     * @param beanName the name of the bean
     * @param specificInterceptors the set of interceptors that is
     * specific to this bean (may be empty, but not null)
     * @param targetSource the TargetSource for the proxy,
     * already pre-configured to access the bean
     * @return the AOP proxy for the bean
     * @see #buildAdvisors
     */
    protected Object createProxy(
            Class beanClass, String beanName, Object[] specificInterceptors, TargetSource targetSource) {

        if (this.beanFactory instanceof ConfigurableListableBeanFactory) {
            AutoProxyUtils.exposeTargetClass((ConfigurableListableBeanFactory) this.beanFactory, beanName, beanClass);
        }

        ProxyFactory proxyFactory = new ProxyFactory();
        proxyFactory.copyFrom(this);

        if (!proxyFactory.isProxyTargetClass()) {
            if (shouldProxyTargetClass(beanClass, beanName)) {
                proxyFactory.setProxyTargetClass(true);
            }
            else {
                evaluateProxyInterfaces(beanClass, proxyFactory);
            }
        }
       

/ / acquired all of the notifier, the notifier and to the configuration, the target object

Advisor[] advisors
= buildAdvisors(beanName, specificInterceptors); proxyFactory.addAdvisors(advisors);

/ / When you invoke the target method, the pre - configured annunciator will work

proxyFactory.setTargetSource(targetSource); customizeProxyFactory(proxyFactory); proxyFactory.setFrozen(
this.freezeProxy); if (advisorsPreFiltered()) { proxyFactory.setPreFiltered(true); } // 此处生成代理对象,进入ProxyFactory的getProxy方法 return proxyFactory.getProxy(getProxyClassLoader()); }

enter getProxy method, due to inheritance classes, so that after entering the method,A real implementation in the class, the method is invoked in a class method,And only had one package.

    /**
     * Create a new proxy according to the settings in this factory.
     * 

Can be called repeatedly. Effect will vary if we've added * or removed interfaces. Can add and remove interceptors. *

Uses the given class loader (if necessary for proxy creation). * @param classLoader the class loader to create the proxy with * (or {@code null} for the low-level proxy facility's default) * @return the proxy object */ public Object getProxy(ClassLoader classLoader) {
// 下面的createAopProxy()方法是ProxyCreatorSupport类中的方法
return createAopProxy().getProxy(classLoader); }

Okay, next, is the key part:

() methods return the interface type,It has two implementation class, respectively (by cglib generated proxy object) and (through JDK dynamic proxies generated object),Is used to generate the proxy object, later analysis of these two different implementations.

Then, or how it is?enters the method, this method is to acquire, by this method has been used to create,While the use of a class.

    /**
     * Subclasses should call this to get a new AOP proxy. They should not
     * create an AOP proxy with {@code this} as an argument.
     */
    protected final synchronized AopProxy createAopProxy() {
        if (!this.active) {
            activate();
        }
        return getAopProxyFactory().createAopProxy(this);
    }

entering class of method is:

    @Override
    public AopProxy createAopProxy(AdvisedSupport config) throws AopConfigException {
        if (config.isOptimize() || config.isProxyTargetClass() || hasNoUserSuppliedProxyInterfaces(config)) {
            Class targetClass = config.getTargetClass();
            if (targetClass == null) {
                throw new AopConfigException("TargetSource cannot determine target class: " +
                        "Either an interface or a target is required for proxy creation.");
            }
// 如果targetClass是接口类,那么使用JDK来生成代理对象,返回JdkDynamicAopProxy类型的对象
if (targetClass.isInterface() || Proxy.isProxyClass(targetClass)) { return new JdkDynamicAopProxy(config); }
// 否则,返回ObjenesisCglibAopProxy类型的对象,它是使用cglib的方式生成代理对象的
return new ObjenesisCglibAopProxy(config); } else { return new JdkDynamicAopProxy(config); } }

Here, we already know how it was, then we are introduced and how to generate the proxy object?

JDK dynamic proxies of the proxy object is generated, the method enters getProxy

    @Override
    public Object getProxy(ClassLoader classLoader) {
        if (logger.isDebugEnabled()) {
            logger.debug("Creating JDK dynamic proxy: target source is " + this.advised.getTargetSource());
        }

/ / obtained by integrating all of the proxy interface agent

Class
[] proxiedInterfaces = AopProxyUtils.completeProxiedInterfaces(this.advised, true); findDefinedEqualsAndHashCodeMethods(proxiedInterfaces);

/ / use the JDK's Proxy Class to generate proxy objects

return Proxy.newProxyInstance(classLoader, proxiedInterfaces, this); }

cglib generated a proxy object, into the class of getProxy method:

@Override
    public Object getProxy(ClassLoader classLoader) {
        if (logger.isDebugEnabled()) {
            logger.debug("Creating CGLIB proxy: target source is " + this.advised.getTargetSource());
        }

        try {

/ / acquisition target object

Class
rootClass = this.advised.getTargetClass(); Assert.state(rootClass != null, "Target class must be available for creating a CGLIB proxy"); Class proxySuperClass = rootClass; if (ClassUtils.isCglibProxyClass(rootClass)) { proxySuperClass = rootClass.getSuperclass(); Class[] additionalInterfaces = rootClass.getInterfaces(); for (Class additionalInterface : additionalInterfaces) { this.advised.addInterface(additionalInterface); } } // Validate the class, writing log messages as necessary. validateClassIfNecessary(proxySuperClass, classLoader);
// 创建并配置Enhancer,它是cglib主要的操作类,用于代理对象的生成
// Configure CGLIB Enhancer... Enhancer enhancer = createEnhancer(); if (classLoader != null) { enhancer.setClassLoader(classLoader); if (classLoader instanceof SmartClassLoader && ((SmartClassLoader) classLoader).isClassReloadable(proxySuperClass)) { enhancer.setUseCache(false); } }

// configure object enhancer, such as interface agents, the parent class, the callback method etc.

enhancer.setSuperclass(proxySuperClass); enhancer.setInterfaces(AopProxyUtils.completeProxiedInterfaces(
this.advised)); enhancer.setNamingPolicy(SpringNamingPolicy.INSTANCE); enhancer.setStrategy(new ClassLoaderAwareUndeclaredThrowableStrategy(classLoader)); Callback[] callbacks = getCallbacks(rootClass); Class[] types = new Class[callbacks.length]; for (int x = 0; x < types.length; x++) { types[x] = callbacks[x].getClass(); } // fixedInterceptorMap only populated at this point, after getCallbacks call above enhancer.setCallbackFilter(new ProxyCallbackFilter( this.advised.getConfigurationOnlyCopy(), this.fixedInterceptorMap, this.fixedInterceptorOffset)); enhancer.setCallbackTypes(types); // 通过enhancer来生成代理对象 // Generate the proxy class and create a proxy instance. return createProxyClassAndInstance(enhancer, callbacks); } catch (CodeGenerationException ex) { throw new AopConfigException("Could not generate CGLIB subclass of " + this.advised.getTargetClass() + ": Common causes of this problem include using a final class or a non-visible class", ex); } catch (IllegalArgumentException ex) { throw new AopConfigException("Could not generate CGLIB subclass of " + this.advised.getTargetClass() + ": Common causes of this problem include using a final class or a non-visible class", ex); } catch (Throwable ex) { // TargetSource.getTarget() failed throw new AopConfigException("Unexpected AOP exception", ex); } }

Okay, now the proxy object has been generated, and the settings have been defined in the interceptor (notification), when the proxy object invokes the target method is triggered when these interceptors, in the next article, we introduced, when invoking a target method,Interceptor (notify) the idea of the whole process.

“Source Code Analysis”

Law of the People’s Republic of China, analyzing system’s three “

Categories
Uncategorized

algorithm of the sequence of changes in the algorithm to solve – –

Description: the sequence of changes in the algorithm, see http: / / www.. com / reference / algorithm /? kw = algorithm

the problem to be solved: iterator _ traits, std:: move

/*
template 
BidirectionalIterator partition (BidirectionalIterator first, BidirectionalIterator last, UnaryPredicate pred);

Partition range in two
[将一个区间一分为二]
Rearranges the elements from the range [first,last), in such a way that all the elements for which pred returns true precede all those for which it returns false. The iterator returned points to the first element of the second group.
该算法用来将一个序列分成两个部分,其中第1个部分为使得pred()返回true的元素,第2个部分为使得pred()返回false的元素,该算法返回指向第一个使得pred()返回false的元素的迭代器]
The relative ordering within each group is not necessarily the same as before the call. See stable_partition for a function with a similar behavior but with stable ordering within each group.
[该算法作用后,每一部分元素的相对排序与调用算法之前元素的相对排序不一定是一样的。如果想要保持元素的相对排序,请参看stable_partition]
The behavior of this function template (C++98) is equivalent to:
[该函数模板的行为等价于以下操作:]
template 
BidirectionalIterator partition (BidirectionalIterator first, BidirectionalIterator last, UnaryPredicate pred)
{
    while(first != last){
        while(pred(*first)){
            ++first;
            if(first == last)    return first;
        }
        do{
            --last;
            if(first == last)    return first;
        }while(!pred(*last));
        swap(*first, *last);
        ++first;
    }
    return first;
}
*/

#include 
#include 
#include 

bool isOdd(int i){
    return (i%2 == 1);
}

int main()
{
    std::vector<int> myvector;
    std::vector<int>::iterator it, bound;

    for(int i=1; i<10; i++)    myvector.push_back(i);

    bound = std::partition(myvector.begin(), myvector.end(), isOdd);

    std::cout<<"odd elements:";
    for(it = myvector.begin(); it != bound; ++it)
        std::cout<<*it<<' ';
    std::cout<<'\n';

    std::cout<<"even elements:";
    for(it = bound; it != myvector.end(); ++it)
        std::cout<<*it<<' ';
    std::cout<<'\n';

    system("pause");
    return 0;
}
/*
template 
BidirectionalIterator stable_partition (BidirectionalIterator first, BidirectionalIterator last, UnaryPredicate pred);

Partition range in two - stable ordering
Rearranges the elements in the range [first,last), in such a way that all the elements for which pred returns true precede all those for which it returns false, and, unlike function partition, the relative order of elements within each group is preserved.
[该算法用来将一个序列分成两个部分,其中第1个部分为使得pred()返回true的元素,第2个部分为使得pred()返回false的元素,不同于partition(),该函数会保留元素的相对排序]
This is generally implemented using an internal temporary buffer.
[该函数通常是使用一个内部的临时缓冲实现的]
*/

#include      // std::cout
#include     // std::stable_partition
#include        // std::vector

bool IsOdd (int i) { return (i%2)==1; }

int main () 
{
    std::vector<int> myvector;

    // set some values:
    for (int i=1; i<10; ++i) myvector.push_back(i); // 1 2 3 4 5 6 7 8 9

    std::vector<int>::iterator bound;
    bound = std::stable_partition (myvector.begin(), myvector.end(), IsOdd);

    std::cout << "odd elements:";
    for (std::vector<int>::iterator it=myvector.begin(); it!=bound; ++it)
        std::cout << ' ' << *it;
    std::cout << '\n';

    std::cout << "even elements:";
    for (std::vector<int>::iterator it=bound; it!=myvector.end(); ++it)
        std::cout << ' ' << *it;
    std::cout << '\n';

    system("pause");
    return 0;
}
/*
template 
OutputIterator copy (InputIterator first, InputIterator last, OutputIterator result);

Copy range of elements
[copy区间中的元素]
Copies the elements in the range [first,last) into the range beginning at result.
[将区间[first, last)中的元素复制到result所指向的起始位置]
The function returns an iterator to the end of the destination range (which points to the element following the last element copied).
[该函数的返回一个指向目标区间的尾部的迭代器(即指向目标区间中最后一个元素的下一位)]
The ranges shall not overlap in such a way that result points to an element in the range [first,last). For such cases, see copy_backward.
[result不应该指向区间[first, last)中的元素,即拷贝区间不允许这种形式的重叠。对于这种重叠情况,请看copy_backward]
The behavior of this function template is equivalent to:
[该函数模板的行为等价于以下操作:]
template 
OutputIterator copy (InputIterator first, InputIterator last, OutputIterator result)
{
    while(first != last){
        *first = *result;
        ++first;    ++result;
    }
    return result;
}
*/

#include 
#include 
#include 

int main () 
{
    int myints[]={10,20,30,40,50,60,70};
    std::vector<int> myvector (7);

    std::copy ( myints, myints+7, myvector.begin() );

    std::cout << "myvector contains:";
    for (std::vector<int>::iterator it = myvector.begin(); it!=myvector.end(); ++it)
        std::cout << ' ' << *it;
    std::cout << '\n';

    system("pause");
    return 0;
}
/*
template 
BidirectionalIterator2 copy_backward (BidirectionalIterator1 first, BidirectionalIterator1 last, BidirectionalIterator2 result);

Copy range of elements backward
[反向拷贝区间中的元素]
Copies the elements in the range [first,last) starting from the end into the range terminating at result.
[从后向前将区间[first, last)中的元素拷贝到以result为结尾的另一区间中]
The function returns an iterator to the first element in the destination range.
[该函数返回一个指向目标区间的第一个元素的迭代器]
The resulting range has the elements in the exact same order as [first,last). To reverse their order, see reverse_copy.
[目标区间中的元素排序与[first, last)中的完全一样,如果需要反转拷贝,请参看reverse_copy]
The function begins by copying *(last-1) into *(result-1), and then follows backward by the elements preceding these, until first is reached (and including it).
[该函数从(last-1)处开始拷贝元素到(result-1)处,然后前向拷贝,直到到达first]
The ranges shall not overlap in such a way that result (which is the past-the-end element in the destination range) points to an element in the range (first,last]. For such cases, see copy.
[result(目标区间的最后一个元素的下一位)不应该指向[first, last)中的元素,即不允许这种情况的重叠;对于这种重叠情况,请看copy]
The behavior of this function template is equivalent to:
[该函数模板的行为等价于以下操作:]
template 
BidirectionalIterator2 copy_backward (BidirectionalIterator1 first, BidirectionalIterator1 last, BidirectionalIterator2 result)
{
    while(last != first){
        *(--result) = *(--last);
    }
    return result;
}
*/

#include 
#include 
#include 

int main()
{
    std::vector<int> myvector;
    std::vector<int>::iterator it;

    for (int i=1; i<=5; i++)    
        myvector.push_back(i*10);          // myvector: 10 20 30 40 50

    myvector.resize(myvector.size()+3);

    std::copy_backward(myvector.begin(), myvector.begin()+5, myvector.end());

    std::cout << "myvector contains:";
    for (it=myvector.begin(); it!=myvector.end(); ++it)
        std::cout << ' ' << *it;
    std::cout << '\n';

    system("pause");
    return 0;
}
/*
template 
void swap (T& a, T& b);

Exchange values of two objects
[交换两个对象的值]
Exchanges the values of a and b.
[交换a和b的值]
The behavior of this function template is equivalent to:
[该函数模板的行为等价于以下操作:]
template 
void swap (T& a, T& b)
{
    T c(a);    a = b;    b = c;
}
Notice how this function involves a copy construction and two assignment operations, which may not be the most efficient way of swapping the contents of classes that store large quantities of data, since each of these operations generally operate in linear time on their size.
[该函数包含一个复制构造和两个赋值操作,如果要交换的类包含大量数据,这就不是最有效的方式,因为这些操作的时间复杂度一般是线性的]
Large data types can provide an overloaded version of this function optimizing its performance. Notably, all standard containers specialize it in such a way that only a few internal pointers are swapped instead of their entire contents, making them operate in constant time.
[大数据类型可以提供一个该函数的重载形式来优化其表现。尤其是标准容器都会特化这个模板函数,在内部实现中通过交换一些内部指针来代替交换整个内容,使得该操作的时间复杂度为一个常数]
Many components of the standard library (within std) call swap in an unqualified manner to allow custom overloads for non-fundamental types to be called instead of this generic version: Custom overloads of swap declared in the same namespace as the type for which they are provided get selected through argument-dependent lookup over this generic version.
*/

#include 
#include 
#include 

int main()
{
    int x=10, y=20;                              // x:10 y:20
    std::swap(x,y);                              // x:20 y:10

    std::vector<int> foo (4,x), bar (6,y);       // foo:4x20 bar:6x10
    std::swap(foo,bar);                          // foo:6x10 bar:4x20

    std::cout << "foo contains:";
    for (std::vector<int>::iterator it=foo.begin(); it!=foo.end(); ++it)
        std::cout << ' ' << *it;
    std::cout << '\n';

    system("pause");
    return 0;
}
/*
template 
ForwardIterator2 swap_ranges (ForwardIterator1 first1, ForwardIterator1 last1, ForwardIterator2 first2);

Exchange values of two ranges
[交换两个区间中的值]
Exchanges the values of each of the elements in the range [first1,last1) with those of their respective elements in the range beginning at first2.
[将区间[first, lasL)中的元素与以first2开始的等长范围内的元素进行交换]]
The function calls swap (unqualified) to exchange the elements.
[该函数调用swap()来进行元素的交换]
The behavior of this function template is equivalent to:
[该函数模板的行为等价于以下操作:]
template 
ForwardIterator2 swap_ranges (ForwardIterator1 first1, ForwardIterator1 last1, ForwardIterator2 first2)
{
    while(first1 != last1){
        swap(*first1, *first2);
        ++first1;    ++first2;
    }
    return first2;
}
*/

#include 
#include 
#include 

int main()
{
    std::vector<int> foo(5, 10);
    std::vector<int> bar(5, 30);
    std::vector<int>::iterator it;

    std::swap_ranges(foo.begin()+1, foo.end()-1, bar.begin());

    std::cout<<"foo contains:";
    for(it = foo.begin(); it != foo.end(); ++it)
        std::cout<<' '<<*it;
    std::cout<<'\n';

    std::cout<<"bar contains:";
    for(it = bar.begin(); it != bar.end(); ++it)
        std::cout<<' '<<*it;
    std::cout<<'\n';

    system("pause");
    return 0;
}
/*
template 
void iter_swap (ForwardIterator1 a, ForwardIterator1 b);

Exchange values of objects pointed to by two iterators
[交换两个迭代器所指向的对象的值]
Swaps the elements pointed to by a and b.
[交换迭代器a和b所指向的元素]
The function calls swap (unqualified) to exchange the elements.
[该函数调用swap()来实现元素的交换]
The behavior of this function template is equivalent to:
[该函数模板的行为等价于以下操作:]
template 
void iter_swap (ForwardIterator1 a, ForwardIterator1 b)
{
    swap(*a, *b);
}
*/

#include      // std::cout
#include     // std::iter_swap
#include        // std::vector

int main () {

    int myints[]={10,20,30,40,50 };               //   myints:  10  20  30  40  50
    std::vector<int> myvector (4,99);            // myvector:  99  99  99  99

    std::iter_swap(myints,myvector.begin());     //   myints: [99] 20  30  40  50
                                                                     // myvector: [10] 99  99  99

    std::iter_swap(myints+3,myvector.begin()+2); //   myints:  99  20  30 [99] 50
                                                                         // myvector:  10  99 [40] 99

    ostream_iterator

    std::cout << "myvector contains:";
    for (std::vector<int>::iterator it=myvector.begin(); it!=myvector.end(); ++it)
        std::cout << ' ' << *it;
    std::cout << '\n';

    system("pause");
    return 0;
}
/*
template 
OutputIterator transform (InputIterator first1, InputIterator last1, OutputIterator result, UnaryOperation op);

template 
OutputIterator transform (InputIterator1 first1, InputIterator1 last1, InputIterator2 first2, OutputIterator result, BinaryOperation binary_op);

Transform range
[转换区间]
Applies an operation sequentially to the elements of one (1) or two (2) ranges and stores the result in the range that begins at result.
[将一个操作一次应用于区间中的每个元素,并将结果保存在以result开始的区间中]
(1) unary operation
[形式一:一元操作]
Applies op to each of the elements in the range [first1,last1) and stores the value returned by each operation in the range that begins at result.
[将一元操作应用与[first1, last1)中的每个元素,并将结果保存在以result开始的区间中]
(2) binary operation
[形式二:二元操作]
Calls binary_op using each of the elements in the range [first1,last1) as first argument, and the respective argument in the range that begins at first2 as second argument. The value returned by each call is stored in the range that begins at result.
[将[ffirst, last1)中的每个元素作为二元操作的第一个参数,并将以first2开始的相应区间中的每个元素作为二元操作的第二个参数,运算结果保存在以result开始的区间中]
The behavior of this function template is equivalent to:
[该模板函数的行为等价于以下操作:]
template 
OutputIterator transform (InputIterator first1, InputIterator last1, OutputIterator result, UnaryOperation op)
{
    while(first1 != last1){
        *result = op(*first1);
        ++first1;    ++result;
    }
    return result;
}
The function allows for the destination range to be the same as one of the input ranges to make transformations in place.
[该函数允许目标区间与输入区间相同来进行转换]
*/

#include 
#include 
#include 

int op_increase(int i){
    return ++i;
}

int binaryop_add(int i, int j){
    return (i+j);
}

int main()
{
    std::vector<int> foo;
    std::vector<int> bar;

    for(int i=1; i<6; i++)    foo.push_back(i*10);     // foo: 10 20 30 40 50

    bar.resize(foo.size());

    std::transform(foo.begin(), foo.end(), bar.begin(), op_increase);    // bar: 11 21 31 41 51

    std::transform(foo.begin(), foo.end(), bar.begin(), foo.begin(), binaryop_add);     // foo: 21 41 61 81 101

    std::cout << "foo contains:";
    for (std::vector<int>::iterator it=foo.begin(); it!=foo.end(); ++it)
        std::cout << ' ' << *it;
    std::cout << '\n';

    system("pause");
    return 0;
}
/*
template 
void replace (ForwardIterator first, ForwardIterator last, const T& old_value, const T & new_value)

Replace value in range
Assigns new_value to all the elements in the range [first,last) that compare equal to old_value.
[将区间[first, last)中值为old_value的元素替换为值为new_value的元素]
The function uses operator== to compare the individual elements to old_value.
[该函数使用operator==来比较每个元素是否相等]
The behavior of this function template is equivalent to:
[该函数模板的行为等价于以下操作:]
template 
void replace (ForwardIterator first, ForwardIterator last, const T& old_value, const T& new_value)
{
    while(first != last){
        if(*first == old_value)    *first = new_value;
        ++first;
    }
}
*/

#include      // std::cout
#include     // std::replace
#include        // std::vector

int main () {
    int myints[] = { 10, 20, 30, 30, 20, 10, 10, 20 };
    std::vector<int> myvector (myints, myints+8);            // 10 20 30 30 20 10 10 20

    std::replace (myvector.begin(), myvector.end(), 20, 99); // 10 99 30 30 99 10 10 99

    std::cout << "myvector contains:";
    for (std::vector<int>::iterator it=myvector.begin(); it!=myvector.end(); ++it)
        std::cout << ' ' << *it;
    std::cout << '\n';

    system("pause");
    return 0;
}
/*
template 
void replace_if (ForwardIterator first, ForwardIterator last, UnaryPredicate pred, const T& new_value );

Replace values in range
Assigns new_value to all the elements in the range [first,last) for which pred returns true.
[将[first, last)中使得pred()返回真的元素替换为new_value]
The behavior of this function template is equivalent to:
[该函数模板的行为等价于以下操作:]
template 
void replace_if (ForwardIterator first, ForwardIterator last, UnaryPredicate pred, const T& new_value )
{
    while(first != last){
        if(pred(*first))    *first = new_value;
        ++first;
    }
}
*/

#include 
#include 
#include 

bool IsOdd (int i){
    return (i%2 == 1);
}

int main()
{
    std::vector<int> myvector;

    for(int i=1; i<10; i++)    myvector.push_back(i);

    std::replace_if(myvector.begin(), myvector.end(), IsOdd, 0);

    std::cout<<"myvector contains:";
    for(std::vector<int>::iterator it = myvector.begin(); it != myvector.end(); ++it)
        std::cout<<' '<<*it;
    std::cout<<'\n';

    system("pause");
    return 0;
}
/*
template 
OutputIterator replace_copy (InputIterator first, InputIterator last, OutputIterator result, const T& old_value, const T& new_value);

Copy range replacing value
Copies the elements in the range [first,last) to the range beginning at result, replacing the appearances of old_value by new_value.
[将[first, last)中的元素拷贝到以result开始的区间中,并替换old_value为new_value]
The function uses operator== to compare the individual elements to old_value.
[该函数使用operator==来判断元素是否为old_value]
The behavior of this function template is equivalent to:
[该函数模板的行为等价与以下操作:]
template 
OutputIterator replace_copy (InputIterator first, InputIterator last, OutputIterator result, const T& old_value, const T& new_value)
{
    while(first != last){
        *result = (*first  == old_value)?new_value:*first;
        ++first;
    }
    return result;
}
*/

#include 
#include 
#include 

int main()
{
    int myints[] = { 10, 20, 30, 30, 20, 10, 10, 20 };
    std::vector<int> myvector(8);

    std::replace_copy(myints, myints+8, myvector.begin(), 20, 99);

    std::cout<<"myvector contains:";
    for(std::vector<int>::iterator it = myvector.begin(); it != myvector.end(); ++it)
        std::cout<<' '<<*it;
    std::cout<<'\n';

    system("pause");
    return 0;
}
/*
template 
OutputIterator replace_copy_if (InputIterator first, InputIterator last, OutputIterator result, UnaryPredicate pred, const T& new_value);

Copy range replacing value
Copies the elements in the range [first,last) to the range beginning at result, replacing those for which pred returns true by new_value.
[将[first, last)中的元素拷贝到以result起始的区间中,并替换其中使得pred()返回真的元素为new_value]
The behavior of this function template is equivalent to:
[该函数模板的行为等价于以下操作:]
template 
OutputIterator replace_copy_if (InputIterator first, InputIterator last, OutputIterator result, UnaryPredicate pred, const T& new_value)
{
    while(first != last){
        *result = (pred(*first))?new_value:*first;
        ++first;    ++result;
    }
    return result;
}
*/

#include 
#include 
#include 

bool IsOdd (int i) { return ((i%2)==1); }

int main () {
    std::vector<int> foo,bar;

    // set some values:
    for (int i=1; i<10; i++) foo.push_back(i);          // 1 2 3 4 5 6 7 8 9

    bar.resize(foo.size());   // allocate space
    std::replace_copy_if (foo.begin(), foo.end(), bar.begin(), IsOdd, 0);    // 0 2 0 4 0 6 0 8 0

    std::cout << "bar contains:";
    for (std::vector<int>::iterator it=bar.begin(); it!=bar.end(); ++it)
        std::cout << ' ' << *it;
    std::cout << '\n';

    system("pause");
    return 0;
}
/*
std::fill
template 
void fill (ForwardIterator first, ForwardIterator last, const T& val);

Fill range with value
Assigns val to all the elements in the range [first,last).
[将val赋值给[first, last)之间的所有元素]
The behavior of this function template is equivalent to:
[该函数模板的行为等价于以下操作:]
template 
void fill (ForwardIterator first, ForwardIterator last, const T& val)
{
    while(first != last){
        *first = val;
        ++first;
    }
}
*/

#include 
#include 
#include 

template<class T>
class Print
{
public:
    void operator() (const T& val){
        std::cout<<' '<<val;
    }
};

int main()
{
    std::vector<int> myvector(10);
    std::fill(myvector.begin(), myvector.end(), 1);
    std::for_each(myvector.begin(), myvector.end(), Print<int>());
    std::cout<<'\n';

    system("pause");
    return 0;
}
/*
std::fill_n
template 
OutputIterator fill_n (OutputIterator first, Size n, const T& val);

Fill sequence with value
Assigns val to the first n elements of the sequence pointed by first.
[将序列中从first开始的n个元素赋值为val]
The behavior of this function template is equivalent to:
[该函数模板的行为等价于以下操作:]
template 
OutputIterator fill_n (OutputIterator first, Size n, const T& val)
{
    while(n>0){
        *first = val;
        ++first;    --n;
    }
    return first;    //since C++11
}
*/

#include 
#include 
#include 

int main()
{
    std::vector<int> myvector(8, 10);
    std::vector<int>::iterator it;

    std::fill_n(myvector.begin(), 4, 20);
    std::fill_n(myvector.begin()+4, 2, 30);

    for(it = myvector.begin(); it != myvector.end(); ++it)
        std::cout<<' '<<*it;
    std::cout<<'\n';

    system("pause");
    return 0;
}
/*
template 
void generate (ForwardIterator first, ForwardIterator last);

Generate values for range with function
Assigns the value returned by successive calls to gen to the elements in the range [first,last).
[通过连续调用gen()函数将返回值赋值给[first, last)中的元素]
The behavior of this function template is equivalent to:
[该函数模板的行为等价于以下操作:]
template 
void generate(ForwardIterator first, ForwardIterator last)
{
    while(first != last){
        *first = gen();
        ++first;
    }
}
*/

#include 
#include 
#include 
#include         //std::time
#include     //std::rand, std::srand

// function generator
int RandomNumber() {
    return rand()%100;
}

class UniqueNumber
{
private:
    int current;
public:
    UniqueNumber()    {current = 0;}
    int operator() ()    {return ++current;}
};

int main()
{
    std::vector<int> myvector(10);
    std::vector<int>::iterator it;

    std::generate(myvector.begin(), myvector.end(), RandomNumber);

    std::cout << "myvector contains:";
    for (std::vector<int>::iterator it=myvector.begin(); it!=myvector.end(); ++it)
        std::cout << ' ' << *it;
    std::cout << '\n';

    std::generate (myvector.begin(), myvector.end(), UniqueNumber());

    std::cout << "myvector contains:";
    for (std::vector<int>::iterator it=myvector.begin(); it!=myvector.end(); ++it)
        std::cout << ' ' << *it;
    std::cout << '\n';
    
    system("pause");
    return 0;
}
/*
template 
void generate_n (OutputIterator first, Size n, Generator gen);

Generate values for sequence with function
Assigns the value returned by successive calls to gen to the first n elements of the sequence pointed by first.
[通过连续调用gen()函数将返回值赋值给[first, last)中的前n个元素]
The behavior of this function template is equivalent to:
[该函数模板的行为等价于以下操作:]
template 
void generate_n ( OutputIterator first, Size n, Generator gen )
{
    while (n>0) {
        *first = gen();
        ++first; --n;
    }
}
*/

#include      // std::cout
#include     // std::generate_n

int current = 0;
int UniqueNumber () { return ++current; }

int main () 
{
    int myarray[9];

    std::generate_n (myarray, 9, UniqueNumber);

    std::cout << "myarray contains:";
    for (int i=0; i<9; ++i)
        std::cout << ' ' << myarray[i];
    std::cout << '\n';

    system("pause");
    return 0;
}
/*
template 
ForwardIterator remove (ForwardIterator first, ForwardIterator last, const T& val);

Remove value from range
[Note: This is the reference for algorithm remove. See remove for 's remove.]
[注意:这是算法中的remove()函数,而不是头文件中的remove()函数]
Transforms the range [first,last) into a range with all the elements that compare equal to val removed, and returns an iterator to the new end of that range.
[将[first, last)中值为val的元素移除,并返回一个指向新末尾的迭代器]
The function cannot alter the properties of the object containing the range of elements (i.e., it cannot alter the size of an array or a container): The removal is done by replacing the elements that compare equal to val by the next element that does not, and signaling the new size of the shortened range by returning an iterator to the element that should be considered its new past-the-end element.
[该函数不会改变对象的属性(也就是说不会改变数组或者容器的大小):移除操作是通过用下一个不等于val的元素代替等于val的元素,并且返回指向新的末尾的迭代器]
The relative order of the elements not removed is preserved, while the elements between the returned iterator and last are left in a valid but unspecified state.
[没有被移除的元素的相对位置保持不变,但从返回的迭代器到最后一个元素之间的元素处于一种有效但未指定的状态]
The function uses operator== to compare the individual elements to val.
[该函数利用operator==来比较元素]
The behavior of this function template is equivalent to:
[该函数模板的行为等价于以下操作:]
template 
ForwardIterator remove (ForwardIterator first, ForwardIterator last, const T& val)
{
    ForwardIterator result = first;
    while(first != last){
        if(!(*first == val)){
            *result = *first;
            ++result;
        }
        ++first;
    }
    return result;
}
*/

#include 
#include 
#include 

int main () {
    int myints[] = {10, 20, 20, 20, 30, 30, 20, 20, 10};
    std::vector<int> myvector(myints, myints+9);
    std::vector<int>::iterator it, result;

    result = std::remove(myvector.begin(), myvector.end(), 20);

    std::cout << "myvector contains:";
    for (it=myvector.begin(); it != result; ++it)
        std::cout << ' ' << *it;
    std::cout << '\n';

    system("pause");
    return 0;
}
/*
template 
ForwardIterator remove_if (ForwardIterator first, ForwardIterator last, UnaryPredicate pred);

Remove elements from range
Transforms the range [first,last) into a range with all the elements for which pred returns true removed, and returns an iterator to the new end of that range.
[移除[first, last)中使pred()返回真的元素,并返回新的指向末尾的迭代器]
The function cannot alter the properties of the object containing the range of elements (i.e., it cannot alter the size of an array or a container): The removal is done by replacing the elements for which pred returns true by the next element for which it does not, and signaling the new size of the shortened range by returning an iterator to the element that should be considered its new past-the-end element.
[该函数不会改变对象的属性(也就是说不会改变数组或者容器的大小):移除操作是通过用下一个使pred()返回假的元素代替使pred()返回真的元素,并且返回指向新的末尾的迭代器]
The relative order of the elements not removed is preserved, while the elements between the returned iterator and last are left in a valid but unspecified state.
[没有被移除的元素的相对位置保持不变,但从返回的迭代器到最后一个元素之间的元素处于一种有效但未指定的状态]
The behavior of this function template is equivalent to:
[该函数模板的行为等价于以下操作:]
template 
ForwardIterator remove_if (ForwardIterator first, ForwardIterator last, UnaryPredicate pred)
{
    ForwardIterator result = first;
    while(first != last){
        if(!pred(*first)){
            *result = *first;
            ++result;
        }
        ++first;
    }
    return result;
}
*/

#include 
#include 
#include 

bool IsOdd (int i) { return ((i%2)==1); }

int main () 
{
    int myints[] = {1,2,3,4,5,6,7,8,9};            // 1 2 3 4 5 6 7 8 9

    int* pbegin = myints;                         
    int* pend = myints+sizeof(myints)/sizeof(int); 

    pend = std::remove_if (pbegin, pend, IsOdd);   // 2 4 6 8 ? ? ? ? ?

    std::cout << "the range contains:";
    for (int* p=pbegin; p!=pend; ++p)
        std::cout << ' ' << *p;
    std::cout << '\n';

    system("pause");
    return 0;
}
/*
template 
OutputIterator remove_copy (InputIterator first, InputIterator last, OutputIterator result, const T& val);

Copy range removing value
Copies the elements in the range [first,last) to the range beginning at result, except those elements that compare equal to val.
[将[first, last)中不等于val的元素拷贝到以result起始的区间中]
The resulting range is shorter than [first,last) by as many elements as matches in the sequence, which are "removed".
[结果区间中的元素加上被移除元素即为原始区间中的元素]
The function uses operator== to compare the individual elements to val.
[该函数使用operator==来判断元素是否为val]
The behavior of this function template is equivalent to:
[该函数模板的行为等价于以下操作:]
template 
OutputIterator remove_copy (InputIterator first, InputIterator last, OutputIterator result, const T& val)
{
    while(first != last){
        if(!(*first == val)){
            *result = *first;
            ++result;
        }
        ++first;
    }
    return result;
}
*/

#include 
#include 
#include 

int main () 
{
    int myints[] = {10,20,30,30,20,10,10,20};               // 10 20 30 30 20 10 10 20
    std::vector<int> myvector (8);

    std::remove_copy (myints,myints+8,myvector.begin(),20); // 10 30 30 10 10 0 0 0

    std::cout << "myvector contains:";
    for (std::vector<int>::iterator it=myvector.begin(); it!=myvector.end(); ++it)
        std::cout << ' ' << *it;
    std::cout << '\n';

    system("pause");
    return 0;
}
/*
template 
OutputIterator remove_copy_if (InputIterator first, InputIterator last, OutputIterator result, UnaryPredicate pred);

Copy range removing values
Copies the elements in the range [first,last) to the range beginning at result, except those elements for which pred returns true.
[将[first, last)中使pred()返回真的元素拷贝到以result起始的区间中]
The resulting range is shorter than [first,last) by as many elements as matches, which are "removed".
[结果区间中的元素加上被移除元素即为原始区间中的元素]
The behavior of this function template is equivalent to:
[该函数模板的行为等价于以下操作:]
template 
OutputIterator remove_copy_if (InputIterator first, InputIterator last, OutputIterator result, UnaryPredicate pred)
{
    while(first != last){
        if(!(pred(*first))){
            *result = *first;
            ++result;
        }
        ++first;
    }
    return result;
}
*/

#include 
#include 
#include 

bool IsOdd (int i) { return ((i%2)==1); }

int main () 
{
    int myints[] = {1,2,3,4,5,6,7,8,9};
    std::vector<int> myvector (9);

    std::remove_copy_if (myints,myints+9,myvector.begin(),IsOdd);

    std::cout << "myvector contains:";
    for (std::vector<int>::iterator it=myvector.begin(); it!=myvector.end(); ++it)
        std::cout << ' ' << *it;
    std::cout << '\n';

    system("pause");
    return 0;
}
/*
template 
ForwardIterator unique (ForwardIterator first, ForwardIterator last);

template 
ForwardIterator unique (ForwardIterator first, ForwardIterator last, BinaryPredicate pred);

Remove consecutive duplicates in range
Removes all but the first element from every consecutive group of equivalent elements in the range [first,last).
[去掉区间[first, last)中的重复元素]
The function cannot alter the properties of the object containing the range of elements (i.e., it cannot alter the size of an array or a container): The removal is done by replacing the duplicate elements by the next element that is not a duplicate, and signaling the new size of the shortened range by returning an iterator to the element that should be considered its new past-the-end element.
[该函数不会改变对象的属性(也就是说不会改变数组或者容器的大小):移除操作是通过用下一个非重复元素代替重复元素,并且返回指向新的末尾的迭代器]
The relative order of the elements not removed is preserved, while the elements between the returned iterator and last are left in a valid but unspecified state.
[没有被移除的元素的相对位置保持不变,但从返回的迭代器到最后一个元素之间的元素处于一种有效但未指定的状态]
The function uses operator== to compare the pairs of elements (or pred, in version (2)).
[该函数利用operator==来比较元素(或者用pre)]
The behavior of this function template is equivalent to:
[该模板函数的行为等价于以下操作:]
template 
ForwarIterator unique (ForwarIterator first, ForwarIterator last)
{
    ForwarIterator result = first;
    while(++first != last){
        if(!(*result == *first))
            *(++result) = *first;
    }
    return ++result;
}
*/

#include 
#include 
#include 

bool myfunction (int i, int j){
    return (i == j);
}

int main()
{
    int myints[] = {10, 20, 20, 20, 30, 30, 20, 20, 10};
    std::vector<int> myvector(myints, myints+9);                 // 10 20 20 20 30 30 20 20 10

    // using default comparison.
    std::vector<int>::iterator it;
    it = std::unique(myvector.begin(), myvector.end());        // 10 20 30 20 10 ?  ?  ?  ?
                                                                                    //                          ^
    myvector.resize(std::distance(myvector.begin(), it));    // 10 20 30 20 10

    // using predicate comparison.
    std::unique(myvector.begin(), myvector.end(), myfunction);    // (no changes)

    std::cout<<"myvector contains:";
    for(it = myvector.begin(); it != myvector.end(); ++it)
        std::cout<<' '<<*it;
    std::cout<<'\n';

    system("pause");
    return 0;
}
/*
template 
OutputIterator unique_copy (InputIterator first, InputIterator last, OutputIterator result);

template 
OutputIterator unique_copy (InputIterator first, InputIterator last, OutputIterator result, BinaryPredicate pred);

Copy range removing duplicates
Copies the elements in the range [first,last) to the range beginning at result, except consecutive duplicates (elements that compare equal to the element preceding).
[将[first last)中的不连续重复元素拷贝到以result起始的区间中]
Only the first element from every consecutive group of equivalent elements in the range [first,last) is copied.
[对于连续重复元素,只拷贝第一个元素]
The comparison between elements is performed by either applying operator==, or the template parameter pred (for the second version) between them.
[元素的比较是通过operator==进行的或者通过模板参数pred]
The behavior of this function template is equivalent to:
[该函数模板的行为等价于以下操作:]
template 
OutputIterator unique_copy (InputIterator first, InputIterator last, OutputIterator result)
{
    if (first==last) return result;

    *result = *first;
    while (++first != last) {
        typename iterator_traits::value_type val = *first;
        if (!(*result == val))   // or: if (!pred(*result,val)) for version (2)
        *(++result)=val;
    }
    return ++result;
}
*/

#include 
#include 
#include 

bool myfunction (int i, int j) {
    return (i==j);
}

int main () {
    int myints[] = {10,20,20,20,30,30,20,20,10};
    std::vector<int> myvector (9);                            // 0  0  0  0  0  0  0  0  0

    // using default comparison:
    std::vector<int>::iterator it;
    it=std::unique_copy (myints,myints+9,myvector.begin());   // 10 20 30 20 10 0  0  0  0
    //                ^

    std::sort (myvector.begin(),it);                          // 10 10 20 20 30 0  0  0  0
    //                ^

    // using predicate comparison:
    it=std::unique_copy (myvector.begin(), it, myvector.begin(), myfunction);
    // 10 20 30 20 30 0  0  0  0
    //          ^

    myvector.resize( std::distance(myvector.begin(),it) );    // 10 20 30

    // print out content:
    std::cout << "myvector contains:";
    for (it=myvector.begin(); it!=myvector.end(); ++it)
        std::cout << ' ' << *it;
    std::cout << '\n';

    system("pause");
    return 0;
}
/*
template 
void reverse (BidirectionalIterator first, BidirectionalIterator last);

Reverse range
Reverses the order of the elements in the range [first,last).
[反序[first, last)间的元素]
The function calls iter_swap to swap the elements to their new locations.
[该函数调用iter_swap()来交换元素]
The behavior of this function template is equivalent to:
[该函数模板的行为等价于以下操作:]
template 
void reverse (BidirectionalIterator first, BidirectionalIterator last)
{
    while((first != last) && (first != --last)){
        std::iter_swap(*first, *last);
        ++first;    
    }
}
*/

#include 
#include 
#include 

int main()
{
    std::vector<int> myvector;

    for(int i=1; i<10; i++)    myvector.push_back(i);
    
    std::reverse(myvector.begin(), myvector.end());

    std::cout<<"myvector contains:";
    for(std::vector<int>::iterator it = myvector.begin(); it != myvector.end(); ++it)
        std::cout<<' '<<*it;
    std::cout<<'\n';

    system("pause");
    return 0;
}
/*
template 
OutputIterator reverse_copy (BidirectionalIterator first, BidirectionalIterator last, OutputIterator result);

Copy range reversed
Copies the elements in the range [first,last) to the range beginning at result, but in reverse order.
[将[first, last)中的元素拷贝到以result起始的区间中,并反转排序]
The behavior of this function template is equivalent to:
[该函数模板的行为等价于以下操作:]

template 
OutputIterator reverse_copy (BidirectionalIterator first, BidirectionalIterator last, OutputIterator result)
{
    while(first != last){
        --last;
        *result = *last;
        ++result;
    }
    return result;
}
*/

#include      // std::cout
#include     // std::reverse_copy
#include        // std::vector

int main () 
{
    int myints[] ={1,2,3,4,5,6,7,8,9};
    std::vector<int> myvector;

    myvector.resize(9);    // allocate space

    std::reverse_copy (myints, myints+9, myvector.begin());

    // print out content:
    std::cout << "myvector contains:";
    for (std::vector<int>::iterator it=myvector.begin(); it!=myvector.end(); ++it)
        std::cout << ' ' << *it;
    std::cout << '\n';

    system("pause");
    return 0;
}
/*
template 
void rotate (ForwardIterator first, ForwardIterator middle, ForwardIterator last);

Rotate left the elements in range
[将区间中的元素向左旋转]
Rotates the order of the elements in the range [first,last), in such a way that the element pointed by middle becomes the new first element.
[把区间[middle, last)之间的元素向左旋转,使得指向middle的元素成为新的first元素]]
The behavior of this function template (C++98) is equivalent to:
[该函数模板的行为等价于以下操作:]
template 
void rotate (ForwardIterator first, ForwardIterator middle, ForwardIterator last)
{
    ForwardIterator next = middle;
    while(first != next){
        swap(*first++, *next++);
        if(next == last)    next = middle;
        else if(first == middle)    middle = next;
    }
}
*/

#include 
#include 
#include 

int main()
{
    std::vector<int> myvector;
    std::vector<int>::iterator it;

    for(int i=1; i<10; i++)    myvector.push_back(i);    // 1 2 3 4 5 6 7 8 9

    std::rotate(myvector.begin(), myvector.begin()+3, myvector.end());    //4 5 6 7 8 9 1 2 3

    std::cout<<"After rotating, myvector contains: ";
    for(it = myvector.begin(); it != myvector.end(); ++it)
        std::cout<<*it<<' ';
    std::cout<<'\n';

    system("pause");
    return 0;
}
/*
template 
OutputIterator rotate_copy (ForwardIterator first, ForwardIterator middle, ForwardIterator last, OutputIterator result);

Copy range rotated left
Copies the elements in the range [first,last) to the range beginning at result, but rotating the order of the elements in such a way that the element pointed by middle becomes the first element in the resulting range.
[将[first, last)中的元素拷贝到以result起始的区间中,并把区间[middle, last)之间的元素向左旋转,使得指向middle的元素成为第一个元素]]
The behavior of this function template is equivalent to:
[该函数模板的行为等价于以下操作:]
template 
OutputIterator rotate_copy (ForwardIterator first, ForwardIterator middle, ForwardIterator last, OutputIterator result)
{
    result=std::copy (middle,last,result);
    return std::copy (first,middle,result);
}
*/

#include      // std::cout
#include     // std::reverse_copy
#include        // std::vector

int main () {
    int myints[] = {10,20,30,40,50,60,70};

    std::vector<int> myvector (7);

    std::rotate_copy(myints,myints+3,myints+7,myvector.begin());

    std::cout << "myvector contains:";
    for (std::vector<int>::iterator it=myvector.begin(); it!=myvector.end(); ++it)
        std::cout << ' ' << *it;
    std::cout << '\n';

    system("pause");
    return 0;
}
/*
template 
void random_shuffle (RandomAccessIterator first, RandomAccessIterator last);

template 
void random_shuffle (RandomAccessIterator first, RandomAccessIterator last, RandomNumberGenerator& gen);

Randomly rearrange elements in range
Rearranges the elements in the range [first,last) randomly.
[重新随机排列[first, last)之间的元素]
The function swaps the value of each element with that of some other randomly picked element. When provided, the function gen determines which element is picked in every case. Otherwise, the function uses some unspecified source of randomness.
[该函数将区间中的每个元素与随机选择的元素交换,如果提供了随机数生成器gen,则由函数gen来决定被选择每一次交换的元素,如果没有提供gen,则该函数使用为指定的随机源]
The behavior of this function template (2) is equivalent to:
[该函数模板的行为等价于以下操作:]
template 
void random_shuffle (RandomAccessIterator first, RandomAccessIterator last, RandomNumberGenerator& gen)
{
     iterator_traits::difference_type i, n;
     n = (last-first);
     for(i=n-1; i>0; --i){
         swap(first[i], first[gen(i+1)]);
     }
}
*/

#include 
#include 
#include 
#include 
#include 

int myrandom(int i){
    int temp = i;
    return std::rand()%i;
}

int main()
{
    std::srand((unsigned)std::time(NULL));
    std::vector<int> myvector;
    std::vector<int>::iterator it;

    for(int i=1; i<10; ++i)    myvector.push_back(i);

    // using built-in random generator.
    std::random_shuffle(myvector.begin(), myvector.end());

    for(it = myvector.begin(); it != myvector.end(); ++it)
        std::cout<<*it<<' ';
    std::cout<<'\n';

    // using myrandom.
    std::random_shuffle(myvector.begin(), myvector.end(), myrandom);

    for(it = myvector.begin(); it != myvector.end(); ++it)
        std::cout<<*it<<' ';
    std::cout<<'\n';

    system("pause");
    return 0;
}
/*
int rand (void);

Generate random number
[生成随机数]
Returns a pseudo-random integral number in the range between 0 and RAND_MAX.
[在0-RAND_MAX之间产生一个伪随机整数]
This number is generated by an algorithm that returns a sequence of apparently non-related numbers each time it is called. This algorithm uses a seed to generate the series, which should be initialized to some distinctive value using function srand.
[伪随机数是通过一个算法生成的,每次调用该算法时,该算法都会利用一个种子来产生一系列明显不相关的数,种子需要通过srand()函数来初始化为不同值]
RAND_MAX is a constant defined in .
[RAND_MAX是一个定义在头文件中的常量]
A typical way to generate trivial pseudo-random numbers in a determined range using rand is to use the modulo of the returned value by the range span and add the initial value of the range:
[利用rand()函数在一个已确定的区间中产生伪随机数一个典型做法是将返回值对区间取模并加上区间的初始值,比如:]
v1 = rand() % 100;                // v1 in the range 0 to 99
v2 = rand() % 100 + 1;            // v2 in the range 1 to 100
v3 = rand() % 30 + 1985;        // v3 in the range 1985-2014 
Notice though that this modulo operation does not generate uniformly distributed random numbers in the span (since in most cases this operation makes lower numbers slightly more likely).
[需要注意的是,这种取模操作生成的伪随机数在区间中不是均匀分布的(在大多数情况下,该操作产生值小的数比产生值大的数的概率稍微大一些)]
C++ supports a wide range of powerful tools to generate random and pseudo-random numbers (see  for more info).
[C++支持大量的强有力的工具来生成随机数和伪随机数(请参见)]

RAND_MAX
Maximum value returned by rand
[rand()函数的最大返回值]
This macro expands to an integral constant expression whose value is the maximum value returned by the rand function.
[该宏是一个整型常量表达式,表示rand()函数的最大返回值]
This value is library-dependent, but is guaranteed to be at least 32767 on any standard library implementation.
[该宏的取值由库决定,但任何库实现都必须保证其值至少为32767]

void srand (unsigned int seed);

Initialize random number generator
[初始化随机数生成器]
The pseudo-random number generator is initialized using the argument passed as seed.
[srand()函数将传递进来的参数seed作为种子,初始化伪随机数生成器]
For every different seed value used in a call to srand, the pseudo-random number generator can be expected to generate a different succession of results in the subsequent calls to rand.
[每次调用srand()函数时,如果传递进来的seed不同,则随后调用rand()时,伪随机数生成器应该生成一系列不同的结果]
Two different initializations with the same seed will generate the same succession of results in subsequent calls to rand.
[如果调用srand()函数时,传递的seed相同,则随后调用rand()时,伪随机数生成器生成的结果将是相同的]
If seed is set to 1, the generator is reinitialized to its initial value and produces the same values as before any call to rand or srand.
[如果seed是1,则生成器被重置为初始值]
In order to generate random-like numbers, srand is usually initialized to some distinctive runtime value, like the value returned by function time (declared in header ). This is distinctive enough for most trivial randomization needs.
[为了生成看起来像是随机数的数据,srand()的seed通常使用被初始化为不同的运行时间值,比如time()函数的返回值,这样能够充分保证大多数简单的随机需求]
*/

#include 
#include 
#include 

int main()
{
    std::cout<<"First number: "<100<<'\n';
    srand(time(NULL));
    std::cout<<"Random number: "<100<<'\n';
    srand(1);
    std::cout<<"Again the first number: "<100<<'\n';

    system("pause");
    return 0;
}                                                                                                           

Categories
Uncategorized

Linux non – root user installed jdk and tomcat

Reprinted from: http: // blogs.. net / wuyigong111 / article / details / 17410661, partly modified

 

Create a user, and in which the user directory and tomcat jdk installation, the installation process as follows.

First, the user group and increased

[[email protected]_test ~]# groupadd sgmm
[[email protected]_test ~]# useradd -d /home/sgmm -g sgmm -m sgmm

Second, set a password for the user

[[email protected]_test ~]# passwd sgmm

提示输入密码并确认密码,密码设置完成。

Third, deploy the jdk (switched to) the user 1, the jdk – 6u13 – linux – i586.bin. bin directory and upload the executable permissions.

[[email protected]_test ~]$ chmod 744 jdk-6u13-linux-i586.bin

2. Implement the jdk – 6u13 – linux – i586.bin. bin installed jdk

[[email protected]_test ~]$ ./jdk-6u13-linux-i586.bin

3, is performed on a one – step installation after completion of the setting user environment variables

[[email protected]_test ~]$ vi .bash_profile

Change the following contents

# .bash_profile

# Get the aliases and functions
if [ -f ~/.bashrc ]; then
        . ~/.bashrc
fi

# User specific environment and startup programs
JAVA_HOME=/home/sgmm/jdk1.6.0_13
CLASSPATH=$JAVA_HOME/lib:$JAVA_HOME/jre/lib
PATH=$PATH:$JAVA_HOME/bin:$JAVA_HOME/jre/bin
export PATH CLASSPATH JAVA_HOME

4, so that the entry into force of the environment variables

[[email protected]_test ~]$ source ~/.bash_profile

5, Verification under linux installed java jdk version not how to go about handling, see Note 1

javac -version

IV. Deployment tomcat

1、将apache-tomcat-6.0.20.tar.gz上传到服务器上

2, decompresses the file, directory apache – tomcat – 6.0. 20

[[email protected]_test ~]$ tar zxvf apache-tomcat-6.0.20.tar.gz

3, tomcat set of environment variables.

[[email protected]_test ~]$ vi .bash_profile

Add the following:

export CATALINA_BASE=/home/sgmm/apache-tomcat-6.0.20
export CATALINA_HOME=/home/sgmm/apache-tomcat-6.0.20

Final. bash _ profile file of the content as follows:

# .bash_profile

# Get the aliases and functions
if [ -f ~/.bashrc ]; then
    . ~/.bashrc
fi

# User specific environment and startup programs
JAVA_HOME=/home/sgmm/jdk1.6.0_13
CLASSPATH=$JAVA_HOME/lib:$JAVA_HOME/jre/lib 
PATH=$PATH:$JAVA_HOME/bin:$JAVA_HOME/jre/bin 
export PATH CLASSPATH JAVA_HOME
export CATALINA_BASE=/home/sgmm/apache-tomcat-6.0.20
export CATALINA_HOME=/home/sgmm/apache-tomcat-6.0.20

4, so that the entry into force of the environment variables

[[email protected]_test ~]$ source ~/.bash_profile

5, switching to decompress after the bin directory of tomcat, execute the following command to start the tomcat service

[[email protected]_test bin]$ ./startup.sh

Print out the following information, it indicates a success.

Using CATALINA_BASE:   /home/sgmm/apache-tomcat-6.0.20
Using CATALINA_HOME:   /home/sgmm/apache-tomcat-6.0.20
Using CATALINA_TMPDIR: /home/sgmm/apache-tomcat-6.0.20/temp
Using JRE_HOME:       /home/sgmm/jdk1.6.0_13

6、使用 ps -ef|grep tomcat 可以查看tomcat进程,并使用 kill -9 进程号杀掉进程

7. Close the tomcat service

[[email protected]_test bin]$ ./shutdown.sh

 

 

Note 1: Linux Install java jdk version not on how to deal with the

Reprinted from http: / / www.. net / home / space.com. php? uid = 20260 & do = blog id = 32389

Environment variables, and Java is put onto the original path of the path ahead.

先用which java查看用的是哪个JAVA,结果显示为

[[email protected] soft]# which java
/usr/bin/java

说明并不是用的刚安装的JAVA版本,那么把JAVA路径放到PATH前面试试【如果修改之后出现command not found的错误,见注2】

export JAVA_HOME=/usr/java/jdk1.6.0_35
export JAVA_BIN=/usr/java/jdk1.6.0_35/bin
export PATH=$JAVA_HOME/bin:$PATH
export CLASSPATH=.:$JAVA_HOME/lib/dt.jar:$JAVA_HOME/lib/tools.jar
export JAVA_HOME JAVA_BIN PATH CLASSPATH

使环境变量生效后再看

[[email protected] ~]# which java
/usr/java/jdk1.6.0_35/bin/java
[[email protected] ~]# java -version
java version "1.6.0_35"
Java(TM) SE Runtime Environment (build 1.6.0_35-b10)
Java HotSpot(TM) 64-Bit Server VM (build 20.10-b01, mixed mode)

 

Note 2: Linux: – bash: * **: command not found

Reference: http: / / www.. com / 2012 / 08 / Linux – 68900. htm

这应该是系统环境变量出现了问题导致的。

解决办法:

先用:echo $PATH
查看path是否含有:/usr/local/sbin:/usr/local/bin:/sbin:/bin:/usr/sbin:/usr/bin

如果没有,先用临时环境变量(重启后消失)
export PATH=$PATH:/usr/local/sbin:/usr/local/bin:/sbin:/bin:/usr/sbin:/usr/bin

which you can use those commands, and a permanent in to modify environment variables, i.e., vi. bash _ profile

Use command: source. bashrc to take effect just modify environment variables

Categories
Uncategorized

The container adapter of priority _ queue

template ,
                class Compare = less > class priority_queue;

Priority queues are a type of container, dessuch that its first element is always the greatest of the elements it cont, according to some of the strict weak ordering criterion. The priority queues is a kind of toleranceThe adapter,it will be in accordance with strict weak ordering of the elements having the highest priority to be moved to the first team in the’s’ This context is similar to “a heap, where elements can beinserted at any moment, and only the max heap element can be retrieved (the one,at the top in the priority queue. priority queue of this context is like a heap, and the element is inserted into the heap,and was able to read only the maximum stack elements (i.e. located on the top of the priority queue of the queues are Priority elements) as a container,are classes that use an encapsulated object of a specific container classas its underlying container, providing a specific set of member functions to acAccess the gxcr1 elements. Elements are from the “back”of the specific container, which is known as the top of the priority queue. A container adapterOrchestration is a class that uses a particular vessel class object as its inner container, which inner container is provided with a series of member function to read it.The rear of the container from the inherent elements of pop,from the perspective of the priority queue of top pop of The underlying container may be any of the standard container classThe templates or some other class designed container. The container shall be accessible through a random access and support following oper: a priority queue of the inner container may be a standard container class template or other specially designed container classes, but in any case, the inner container should support random – access iterators, as well as the following operations:empty () () (front) (back) and push _ back _ pop () The standardConsequently the classes of vector and deque to these requirements. By default, if no contclass is specified for a particular priority _ queue class instantiation, thE standard container used vector i.sub. s. standard container vector and deque satisfy these requirements.default of the inner container is the vector Support of random access is required to keep a heap strinternally at all times. This is done automatically by the container adapThe tor automatically by calling the algorithm functions make _ heap, the heap and push _ pop _ heap when needed. support random – access iterators require internal priority queue must keep as cool as a stack structure, the operation of the container by the adapter by means of an automatic algorithm invokes the function make _ heap,pop _ push _ namely heap heap may be auto – completed

Heap data structure is an array object, it can be seen as a complete binary tree structure.It is characteristic of the parent node’s value is greater than (less than) the two child node values (respectively referred to as the top stack and the stack top is small).It is used by management during the execution of the algorithm of information, including application scenarios, in the priority queue, etc.

/*
//construct priority_queue
priority_queue (const Compare& comp = Compare(), const Container& ctnr = Container());
priority_queue (InputIterator first, InputIterator last, const Compare& comp = Compare(), const Container& ctnr = Container());

A priority_queue keeps internally a comparing function and a container object as data, which are copies of comp and ctnr respectively.
[优先队列会将一个比较函数和一个容器对象数据,它们是各自传递到构造函数中的参数comp和ctnr]
The range version (2), on top that, inserts the elements between first and last (before the container is converted into a heap).
[第二种方式会将[first, second)之间的元素插入到优先队列中,然后转换成堆(通过make_heap排序)]

comp
Comparison object to be used to order the heap.
[comp是用于对堆进行排序的比较对象]
This may be a function pointer or function object able to perform a strict weak ordering by comparing its two arguments.
[comp可以是一个能够进行严格弱排序的函数指针或者函数对象,且有两个参数]
Compare is the third class template paramete ( by default: less).
[comp的数据类型是优先队列的第三个模板参数,默认情况下为less]

ctnr
Container object.
[ctnr是一个容器类对象]
Container is the second class template parameter (the type of the underlying container for the priority_queue; by default: vector).
[ctnr的数据类型是优先队列的第二个模板参数,即优先队列的内在容器的类型,默认情况下为vector]
*/

#include 
#include 
#include 
#include 

class mycomparison
{
    bool reverse;
public:
    mycomparison(const bool& revparam = false)
    {
        reverse = revparam;
    }
    bool operator() (const int& lhs, const int& rhs) const
    {
        if(reverse) return (lhs>rhs);
        else return (lhs<rhs);
    }
};

int main()
{
    int myints[] = {10, 60, 50, 20};

    std::priority_queue<int> first;
    std::priority_queue<int> second(myints, myints+4);

    typedef std::priority_queue<int, std::vector<int>, mycomparison> mypq_type;

    mypq_type third;

    third.push(10);
    third.push(50);
    third.push(60);
    third.push(20);

    std::cout<<"third contains:\n";
    while(!third.empty())
    {
        std::cout<' ';
        third.pop();
    }

    mypq_type fourth(myints, myints+4, mycomparison(true));

    std::cout<<"\nfourth contains:\n";
    while(!fourth.empty())
    {
        std::cout<' ';
        fourth.pop();
    }

    std::cout<<'\n';

    system("pause");
    return 0;
}
/*
bool empty() const;
size_type size() const;
void push(const value_type& val);
void pop();
const value_type& top() const;
*/

#include 
#include 

int main()
{
    std::priority_queue<int> mypq;

    mypq.push(30);
    mypq.push(100);
    mypq.push(25);
    mypq.push(40);

    std::cout<<"Popping out elements...";
    while(!mypq.empty())
    {
        std::cout<<' '<<mypq.top();
        mypq.pop();
    } 

    std::cout<<'\n';

    system("pause");
    return 0;
}
Categories
Uncategorized

Introduction to SSH public key from a remote place and

Brief Introduction to SSH

Traditional network service programs, such as FTP, POP, Telnet, who is not, not safe because they are on the network in clear text data, user account and user password, it suffers middleman attack easily attack,The attacker can impersonate the true server receives user data to the server, and then impersonate the user transmits the data to the real server.

In order to satisfy the security requirement, the IETF Network Working Group developed the Secure Shell (SSH), and that it is a creation in the application layer and transport layer security protocol,Shell is on the computer to provide a secure means of transport and the environment of use.

SSH is relatively reliable, designed for remote login sessions, and other network services that provides the security protocol.Using the SSH protocol can effectively prevent information leakage in the proces of remote management of the problem.SSH can be on all of the transmission of data to be encrypted, it is possible to prevent the DNS spoofing and IP spoofing.

This thesis will discuss the SSH is used in the encryption algorithm and establishing a secure connection of the process.

(To put the question in writing, specific surface were introduced for last ssh)

Use of the key registration is divided into three steps.

1, generate a key (public key and private key);

2, placing public keys (Public Key) to the server the ~ /. ssh / authorized _ keys file;

3, ssh client configuration used in the key.

1. 1 generates a key (public key and private key)

Open, in the menu bar, click the Tools pop – up menu, select “New User key generation (wizard)”, a pop – up “of newly – built – in user key generation wizard dialog box, in the” key type “item selection” RSA “public key encryption algorithm, key length “to select an arbitrary key length, the longer the length, the higher security, click” Next “, waiting for a key generation

you go to the next step, in the “key names” in the Key of the input file name, and I’m here as the” id _ rsa 2048 _ (2) “;Password for encryption at the input a password used to encrypt the private key, such as 12345678, and confirm the password again, click “Next”.Public key generation (key select Format – OpenSSH SSH2) format, is shown here and the public key, we can copy the public key and then save, can also be saved directly to the public key to the file,The following figure.

Click “save” button, the public key (public key) is saved to disk, file with the name of “xxxxxxx”, standby.Finally, click “finish”.

After the public key is stored, followed by a private key file.Click “Export”, is derived as a copy of this file, opened to the public key.Please take care of properly.

Click “Save” causes a pop – up box, the password is 12345678. click “OK”.

 

1. (2) is disposed between the public key (certificate server) to ~ /. ssh / authorized _ keys file

The steps above have only generated public key and private key of the process, it will be just the generated public key is placed on the server to be administered.

Used to login to the server, enter into “/ root /. ssh /” directory, using the public key to a server.

 

Then run the following command, public keys (Public Key) to “authorized _ keys file:

[[email protected] ~]# cd .ssh/
[[email protected] .ssh]# ls
authorized_keys known_hosts
[[email protected] .ssh]# rz -E
rz waiting to receive.
[[email protected] .ssh]# ls
authorized_keys known_hosts laomao.pub
[[email protected] .ssh]# cp authorized_keys authorized_keys.bak
[[email protected] .ssh]# cat laomao.pub >authorized_keys
[[email protected] .ssh]# cat authorized_keys
ssh-rsa AAAAB3NzaC1yc2EAAAABIwAAAYEAybjy7/DVWxXm4lcXFA+x0bgBMi+aQ6zIzyBfFSKJEMhAhs/MxbKHOl1c1GwzPSAKLAHoR8UZSQO7QQcYKqeb8cNWR8f9NGNBCJs+e6Fpl7BvNPKfNrixnq+gT5VIz77u2RXU74JBOuwsgaEHtCU5DQhIfvAoUe64qCBuY5J6JHJV3bBlMXnqxrJQO4+4hH0dHyVzc5wmP0ngnah/6za64hk3Nd1tdER7na701geZTR5N4OqeCep+TtPcbT4RKQ1qJ5L67ET5x3uYGEKZDK4tOL2kluePd2XHRQg1qcXl87f7HkZiLIicgLU8/rB+LyUOJzywTVHvmTWTPDS1u6RmAQSLh/4VU0vEks7bIj7xTCaKjuO6UgHvxPZL1BQWj8tY6fzerdndVM5bORkAHgZ67ZJK6X+Zui4fHTkxSQ/gvzOgBylhSL3Tyc1PRlVO8L7bl9r36x7hlACHr0BrqpenrkxdMmrR4i4RoOrYaijXoPhvg5uWH+rSeUbZDDEw7S/F[[email protected] .ssh]#
[[email protected] .ssh]# chmod 600 authorized_keys
[[email protected] .ssh]#

 

1. ssh client configuration 3 used in the key

Open, by clicking on the button will call up the New Session Properties dialog box, in the “connection” in the column,Enter your recently configured public keys (Public Key) of the IP address and port, as shown in the figure below:

In the user authentication window to input the authentication method is the “public key”.

from the secret key of the user is to chose just the generated private key file, the password input in the password and system password 123456 (may be not the same)

 

Now you can use the public key of the log in, browse to and select the secret key of the user position, and then input the password set immediately above “123456”, and click “OK”, then login.After the above configuration of the ssh keys as well, we can insert in the Publish over SSH in to use a key to the management server.Note that the server is stored on the above generated public key, Jenkins on stored therein is the generated private key file.

 

 

 

to the use of technology

In order to guarantee the security of information transmission, SSH using symmetric encryption, asymmetric encryption and hash technology, etc.

symmetric encryption

Symmetric key encryption is also referred to as symmetric cryptography, private key encryption, shared key encryption, cryptography is an encryption algorithm in the class.This type of algorithm in the encryption and decryption when using the same key, or may simply use two mutual prediction of the key.

SSH uses the symmetric key to encrypt the entire connection process in the transmission of information.Notably, the user’s own creation of public / private key pair is used only for verification, not done with the encrypted connection.Symmetric encryption allows the encryption on passwords for authentication, in order to prevent a third party.

The shared key by the key exchange algorithm, it can make both parties in full and without any pre – information over an insecure channel to create a key.The client and server are involved in this process, the process and the details thereof will be described later.

The generated key will be used to encrypt the session between server and client during transmission of data.This process will verify the client identity prior to completion.

SSH supports multiple symmetric key algorithms including AES, Blowfish, 3DES, and CAST128.The client and server may be configured using the algorithms of the list.Client list in the first server can be supported by the algorithm will be used.

for example in Ubuntu 14.04, client and server by default is configured as follows:the aes 128 – ctr ctr – aes192, aes256 – ctr, arcfour256, arcfour128, gcm – aes 128 @ openssh. com, aes256 gcm – @ openssh. com, chacha20 – poly1305 @ openssh. com, the aes 128 – cbc, blowfish – cbc, cast128 – cbc, aes192 – cbc, aes256 – cbc,.That is, if two Ubuntu 14.04 is in its default configuration, they are always using the aes 128 – ctr algorithm to an encrypted connection.

asymmetric encryption

In asymmetric encryption methods, requires a pair of keys, one private, one public key.These two keys are mathematically related.Using the public key encrypted information, only with the private key can decrypt.If we know which one, and cannot be calculated with respect to one another.Thus, if one of the pair of keys, and does not threaten another secret nature.

SSH in some parts of the asymmetric encryption is used.

In the key exchange process used in the asymmetric encryption.At this stage, the client and the server generates a temporary key pair and exchange public key to generate a shared key.

In the authentication process by using asymmetric encryption.The SSH key used to verify the client identity.The client creates a key pair, then the public key is uploaded to the remote server, is written to the file ~ /. ssh / authorized _ keys.

In creating a shared key, the client must be able to prove the identity.The server will use the file encrypted with a public key of a piece of information, and decrypts the encrypted information and sends it to the client.If the client may be able to crack this information, it is possible to prove himself an associated private key.After the client that the server will set the shell environment.

hash

Hashing is a computer science in an information processing method, by which a particular algorithm to retrieve the item and retrieving the associated with the index to generate a convenient search data structures (hash tables).It is also frequently used as an information security method, by a stream data through the hash algorithm that fingerprint data, to identify files and data have been tampered with.

SSH have been mainly used in a keyed – hash message authentication code (- hash message authentication code, HMAC), a confirmation message is not tampered.

The above – mentioned symmetric encryption negotiation process are performed using a message authentication code (MAC) algorithm.This algorithm relies on the support from the client with the algorithm selected.

In the key negotiations are complete, all of the message must carry a MAC, the communication parties for verifying the consistency of the message.The MAC value by the shared key, the message of the packet sequence and the actual message content is calculated.

In symmetrical encryption, MAC itself as the final portion of the packet is transmitted.Researchers usually recommended that the confidential data, and then calculating the MAC

SSH workflow

SSH protocol employs a client – server model to perform the authentication, and encrypt the data.

The server listens for a connection request to a designated port.It is responsible for negotiating a secure connection, connection authentication, and generates the correct shell environment.

The client is responsible for negotiating a secure connection, the server verifies the identity of a previous recording of the information to be matched to the provided authentication credentials.

SSH session is divided into two stages.The first is the agreed and established encryption to protect the future of communication.In the second stage the user is authenticated, and whether discovery should be granted access to the server.

session encryption negotiation

When the client initiates the request, the packet returned from the server to support the protocol version.If the client can match one of the protocol version, then the connection is continued.The server will provide its address to the host public key, the client can use this key to the authentication service side is legitimate.

At this time, the communication parties using a Diffie – Hellman algorithm to negotiate a session key.

The algorithm of the general process is as follows:

  1. 双方协定共享一个大素数。
  2. 双方协定一个加密算法。
  3. 双方各自生成一个素数,并保密。这个素数将作为私钥。
  4. 双方使用协定的算法,由各自的私钥和共享的素数计算得到公钥。
  5. 双方交换生成的公钥。
  6. 双方使用各自的私钥,另外一方的公钥和共享的素数,计算得到一个共享密钥。双方计算得到的共享密钥应该是一样的。
  7. 使用共享密钥加密后面的会话。

For the rest of the connection of the shared key encryption is referred to as a binary packet protocol.The process described allows equal participation of both parties generate the shared key.

The generated key is a symmetric key, which means that the key used to encrypt message can also be used for decryption.For the purpose of subsequent communications cannot be packaged in external personnel decryption of an encrypted tunnel.

In generate a session key after doing well to user authentication.

verifying user identity

According to the server in an acceptable manner, there are several different methods can be used for authentication.

The simplest method is password authentication, wherein the server requires the client to input account password of the login attempt.The password is encrypted and transmitted through negotiation.

Although the password is encrypted, but due to the complexity of the password are limited, thus typically not recommended to use this method.Compared with other authentication methods, the automatic script is relatively easy to break the normal length of the password.

The most recommended option is to use SSH key pair.SSH key pair is an asymmetric key.

The public key can only be decrypted using the private key used for encryption of data.The public key may be freely shared, because there is no public key is derived in a private key of the method.

Verification process is as follows:

  1. 客户端首先向服务端发送密钥对的ID。
  2. 服务端检查文件authorized_keys寻找该ID的公钥。
  3. 如果找到,服务端生成一个随机数,并使用公钥加密这个数。
  4. 服务端将加密后的信息发送给客户端。
  5. 如果客户端拥有对应的私钥,那么就能使用私钥解密消息,得到服务端生成的随机数。
  6. 客户端使用解密后的数和会话使用的共享密钥得到一个值,然后计算这个值的MD5散列值。
  7. 客户端将这个MD5散列值发送回服务端。
  8. 服务端用会话共享密钥和生成的随机值计算得到自己的MD5散列值。然后比较客户端传回的值和自身生成的值。如果匹配,则证明客户端拥有私钥,客户端验证通过。

As can be seen, the asymmetry allows for the key server using the public key encrypted message to the client.Then, the client can be correctly decrypted the message with the private key to prove it.

Categories
Uncategorized

SQL Server – based

One, often command

1, by using the command line to open the SQL Server service

get the administrator’s command – line tool:

net start mssqlserver open sql server services

net mssqlserver restart restart sql server services

net stop mssqlserver closes the sql server service

2, use a command log, which may also be applicable to a SQL Server computer is not operating to a SQL Server computer)

run: /

     

– The name of the server S – U login name – password P

     

1) said connection is successful, then the input SQL statement to operate.

    

Second, the basic concepts of knowledge

1, the database logon ID:

SQL Server is installed, one of the super administrator “sa” (the abbreviation of super Administrator), generally do not use this user management data,- we cannot set the password for this user is empty, the user operation, the password is empty, for connection to a database to bring potential safety hazard is caused, so that it is generally installed in resilience and has other built – in name,The sa account is disabled or deleted.

How do I create a user database in another blog post I write there.http: / / www.. com / p / / 3719408. html

 

2, the database system:

SQL Server that is contained in the system databases master, model, msdb, and tempdb.

Here reference under this article: in – depth knowledge of SQL Server database system working principle

Master Master holds placed on all of the entities SQLSERVER database, and it is part of the engine is fixed in the binder.Because if you do not use the main database, the SQL SERVER might fail to start, so you need to carefully arrange the tubes in this database.Thus, this database to perform regular backups is necessary.

This database includes powers, such as system login, configuration settings, the connected SERVER etc, as well as information for the entity of other system users and a database of general information.Main databases are stored in the extended stored procedure, it is able to access the external process, thereby giving you a little with the disk subsystem, and the system API calls, and so on characteristics.These processes generally involve the use of modern programming languages such as C ++.If unfortunately encountered by a system crash, it was necessary to restore the master database, you may be referring to MCSE / MCDBA. Col. Steven Warren on TechRepublic published articles.A version of this article have been very thorough, it explains the important database recovery required some special steps.Model Model is an entity to create new user database of the template database.You can put any stored procedures, views, users should be put in the model database, thus creating a new database, the start of the new database will contain the model you placed a database object.Tempdb As its name suggests, tempdb stores temporary objects, such as global and local temporary tables and stored procedures.(Here I I understand the system of temporary table, for example – – I’m doing a set of query, it didn’t want to create a new table,I can be by tempdb) to store the data in the database on every restart SQL SERVER – this is it’s been re – created, and wherein the object is included in the model database according to the definition of the object is created.In addition to these object, other objects, are stored in the tempdb, for example, a table of variables, from the value function table of the results, and a temporary table variables.Since the tempdb will retain SQLSERVER database entity on all of these object types, the database configuration optimization is very important.msdb database saved in the msdb database backup, SQL Agent information, DTS package, SQLSERVER task information and the like,Such as the log transfer such duplicated information.

3, and is composed of a file type

by such a data file database files. mdf /. ndf, and at least one log file (. Ldf composition

4. The server role

(1) the sysadmin: sql server execute in any of (2) the serveradmin: configure the server settings (3):Installing replication management and expand the process (4) securityadmin: create database management login and permissions, and auditing of reading (5) or a member of:manage sql server process (6) dbcreator: create and modify the database (7): manages the disk files

5. The database role

(1) of the db _ owner: database technology may be performed in all of the actions of the user (2) db _: may be added, deleted, the user of the user (3) db _:To see all the users in the database table within the data of the user (4) db _ datawriter: can add, modify, or delete all the users in the database table within the data of the user (5) db _:The database may be performed in all of the DDL operation of the user (6) db _ securityadmin: can manage security permissions in the database and related to the (7) db _:may be backup of database users (and can be released and DBCC CHECKPOINT statement, these two statements in the general before backup will be performed) (8) db _:Can’t see the task in the database data of the user (9) db _: cannot modify any data in the database of user

Third, the database integrity

1, entity integrity constraints: entity integrity requirements for each row in the table data is reflected in the different entities, cannot exist in the same data line.By indexing, unique, primary key or a column attribute.

2, the domain constraints: domain integrity refers to a given column of input, and by restricting data types, such as check constraint, the input format, the foreign key constraints, defaults, and non – null constraints and a variety of methods, may achieve the subject – matter domain integrity.

3, referential integrity constraints: at the input or deletion of a data row, referential integrity constraints is used to maintain the defined relationships between tables.Table hierarchy cannot add set in the master table foreign key constraint is not associated with the content.master table is not able to change the settings to a foreign key constraint, when the child table with matching related information, the table cannot be deleted because it was set to a foreign key column, when the child table with matching related information,Referential integrity by primary key and foreign key references between that relationship.

4, custom integrity constraints: the user – defined integrity is used to define specific rules, the rules database, stored procedures, such as any of the methods of restraint.

Four, the primary key, foreign key

1, a primary key: when certain information is not to be repeated, and this requires a column whose value is used to uniquely identify each entry in the table, the table and enforces the entity integrity of the table, such a column is defined as the primary key for the table.A table can have only one primary key, the key constraint ensures that the rows of the table is the only, although there is no primary key of the table are allowed to enter China, but in general should be set as the primary key of a table.

2, the outer key: When the sublist of a column in the table information must exist in the case of the input motion, it should create a “reference”, and to ensure that the “child” in the item “AFPM” “must be in there.”foreign key” is used to achieve this objective, it is with respect to the primary key, which is” sublist “corresponds to the” master “of the column, in the child table is referred to as the foreign key references or key, which is the value required in the main table of the corresponding primary key or unique key,External key is used to enforce referential integrity.A table can have multiple foreign keys.

3, a composite primary key: if the two rows or columns that uniquely identify each row in the table, then the primary key is also called “compound primary key”.When using a composite primary key, input data must be provided with all of the composite of the primary key of the data is the same for both will be prohibited from importing.

4. The primary key selection principles:

(1) refers to the minimum column number of the key, if can be from a single primary key and primary key combination is selected, the individual should select a primary key, because the operation than the operation of a plurality of rows of a column.Of course there are exceptions to this rule, for example, two integer – type columns of combination than a great column of type character.(2) stability refers to the column in the data of the feature, since the primary key is usually used in the table) and the link between the two, so the primary key of the data is not to be updated frequently, the ideal case, should never change.

Categories
Uncategorized

Number 1 prime

prime number, prime number, is defined except 1 and themselves. There is no other factor

From this definition, one can write the following program judges whether the number of prime numbers

bool prime(int x){//判断x是不是质数,是返回true,不是返回false 
    if(x <= 1) return false; 
    for(int i = 2; i < x; i ++){
        if(x % i == 0) return false;
    }
    return true;
}

The program of the time complexity is O (n), Is there a faster method, of course

Look at this

bool prime(int x){//判断x是不是质数,是返回true,不是返回false 
    if(x <= 1) return false; 
    for(int i = 2; i <= sqrt(x + 0.5); i ++){//0.5是防止根号的精度误差 
        if(x % i == 0) return false;
    }
    return true;
}
//另一种方法,不需要根号 
bool prime(int x){//判断x是不是质数,是返回true,不是返回false 
    if(x <= 1) return false; 
    for(int i = 2; i * i <= x; i ++){//用乘法避免根号的精度误差 
        if(x % i == 0) return false;
    }
    return true;
}
//根据题目不同,如果i*i会爆int,记得开longlong

This complexity is O (n), the speed is much faster (# 14.395)

 

 

According to different topics, you may need to pre - 1 ~ N, the number N is a prime number

If with the method, the complexity is O (n) n

#include
const int N = 100000 + 5;
bool prime[N];
bool is_prime(int x){
    if(x <= 1) return false; 
    for(int i = 2; i * i <= x; i ++){
        if(x % i == 0) return false;
    }
    return true;
}
void init(){
    for(int i = 0; i < N; i ++){
        prime[i] = is_prime(i);
    }
}
int main(){
    init();
}

If n is large, too slow (. omega.) ・・

 

A new method, sieve

 

El sieve) - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - Eratosthenes sieve method, or the so - called Erichsen sieve

 

Principle: if you find one prime number, prime number multiples of all primes not

 

example 2 is a prime number, 4, 6, 8, 10, 12... there is not a prime number

Then watch 3 is prime, then the 6, 9, 12, 15, 18, 21... there is not a prime number

Then watch the 4, 4 - 2 has been marked as composite numbers, so skip

Then with five................................................................................ like this always down screen

#include
const int N = 100000 + 5;
bool prime[N];
void init(){
    for(int i = 2; i < N; i ++) prime[i] = true;//先全部初始化为质数 
    for(int i = 2; i < N; i ++){
        if(prime[i]){//如果i是质数 
            for(int j = 2*i; j < N; j += i){//从i的两倍开始的所有倍数 
                prime[j] = false; 
            }
        }
    }
}
int main(){
    init();
}

Because some figures, such as a 6 - 2 is used both by the for - loop is again passed through the for loop 3, so the complexity is not an O (n)

This complexity through the professional examination, the complexity O () (learn too high number of children can demonstrate for yourself, of course, also possible to go to Baidu)

 

Know the principles, we tweak it again slightly faster now.

#include
const int N = 100000 + 5;
bool prime[N];
void init(){
    for(int i = 2; i < N; i ++) prime[i] = true;
    for(int i = 2; i*i < N; i ++){//判断改成i*i

 

 

... It's all going down to the final and indeed O (n)

This algorithm is called wire sieve

#include
const int N = 100000 + 5;
bool prime[N];//prime[i]表示i是不是质数 
int p[N], tot;//p[N]用来存质数 
void init(){
    for(int i = 2; i < N; i ++) prime[i] = true;//初始化为质数 
    for(int i = 2; i < N; i++){
        if(prime[i]) p[tot ++] = i;//把质数存起来 
        for(int j = 0; j < tot && i * p[j] < N; j++){
            prime[i * p[j]] = false;
            if(i % p[j] == 0) break;//保证每个合数被它最小的质因数筛去 
        }
    }    
}
int main(){
    init();
}

This method can ensure each composite number is the smallest of its prime factors are screened out

So one can only once

Its time complexity is O (n)

 

loglog actually very small, it is regarded as a linear screen doesn't matter, because you can't you want to write about than the sieve

 

 

Based on sieve principle of angstroms, where we're going to do a lot of things

Each pretreatment such as the number of prime factors all

#include
#include
using namespace std;
const int N = 100000 + 5;
vector<int > prime_factor[N];
void init(){
    for(int i = 2; i < N; i ++){
        if(prime_factor[i].size() == 0){//

If i is prime

for(int j = i; j < N; j += i){ prime_factor[j].push_back(i); } } } } int main(){ init(); }

View Code

 

Each pretreatment such as the number of all factor

#include
#include
using namespace std;
const int N = 100000 + 5;
vector<int > factor[N];
void init(){
    for(int i = 2; i < N; i ++){ 
        for(int j = i; j < N; j += i){
            factor[j].push_back(i); 
        }
    }
}
int main(){
    init();
}

View Code

 

Each pretreatment such as the number of prime factorization

#include
#include
using namespace std;
const int N = 100000 + 5;
vector<int > prime_factor[N];
void init(){
    int temp;
    for(int i = 2; i < N; i ++){
        if(prime_factor[i].size() == 0){
            for(int j = i; j < N; j += i){
                temp = j;
                while(temp % i == 0){
                    prime_factor[j].push_back(i);
                    temp /= i;
                }  
            }
        }
    }
}
int main(){
    init();
}

View Code

 

Categories
Uncategorized

object sender, e

Reference: http: // blogs.. net / kongbai308416350 / article / details / 4233786

said some of the popular, is:

There is a guy called EventHandler, he will tell the main program, there are some things that happened: This thing is who leads?Belong to a certain object types of objects, using the Source or Sender.What is this thing?E content of the content.

As to the Source and Sender, without distinction, for which you want to “use, It is same actually.

So, we in the program of the event processing function is dependent on that thing for the realization of: You just hit a button, for example, a program, there’s no way of knowing which of the following functions to handle this action?So this guy will tell EventHandler program: “button1 (sender) is clicked (e), please call the corresponding handler”.Of course this function, this function what to do, is you yourself wrote.

further in – depth level, this course is the course: your action is capture windows, windows that gesture as system message sending procedure (see message structure),program from their message queues in the continuously taken out of the message and the message loop in looking up the corresponding processing mode,Then a message structure similar to the sender of the e and Dongdong has a function of guiding the program to use the correct handler.

Ultimately, this sender and e and a set of processing mode, the message mechanism of windows is just another form of the ^ _ ^

C #. NET. sender object issues an event object System. EventArgs e data in the object

If the button is a button, that button is the sender, e is the base of the event parameters, in some case, e is not so good.In the example of Mouse event, it can be seen that includes pathing models, the mouse coordinate values, and the like, for your program to use.

specifically, the system provides the class of the event, and Sender parameters are simply transmitted, directed in the event of such a class of examples of a reference, while the EventArgs e is the type of parameter,It contains event information.

As regards the second question, I don’t understand, “I see a lot of those event codes in the code (object sender, EventArgs e),No change: sender and e, the parameters should not vary with the actual situation change?”This sentence means, for example, a button control, when the click event is triggered, the system will automatically push this button object as one type of forced conversion and then assigned to the Sender, then e.This is because all of them form the majority of cases, these simple event need not be transmitted in the special information, you can see the KeyPress event, this event included one,Contains key information.

Also need to clear a concept is similar to the form of such a method:private void Button _ Click (object sender, EventArgs e) in such a way that the method is referred to as an event – handling method,It is similar to that of C in the event – handling function, it is a run – time by a system call, therefore it will not change the parameters, like we’d write method when the method of the same name.

 

Categories
Uncategorized

application domain (Domain)

Application domains provide a flexible and secure method of isolating running applications.

Application domains are typically created by runtime hosts and operation.Sometimes, you may want your application to programmatically interact with your application domains, for example, to unload a component without having to stop your application from running.

Application domain so that the application and the application of the data are separated from each other, and help improve security.Single process may be running multiple application domains, and has a separate process in the presence of the isolation level.Running more than one application in a single process increases server scalability.

The following code example creates a new application domain, and then loads and executes a previously built assembly HelloWorld. exe, this assembly was stored in drive C.

// Create an Application Domain:
System.AppDomain newDomain = System.AppDomain.CreateDomain("NewApplicationDomain");

// Load and execute an assembly:
newDomain.ExecuteAssembly(@"c:\HelloWorld.exe");

// Unload the application domain:
System.AppDomain.Unload(newDomain);

application domain has the following characteristics:

  • You must first load the application domain, and then executes the program.

  • In one application domain errors do not affect another application running in a domain of the other code.

  • Individual applications can be stopped and code unloaded without stopping the entire process.You cannot unload individual assemblies or types, only entire application domains.