zoukankan      html  css  js  c++  java
  • 如何避免变量在多线程中冲突

    字符串去重的再研究

     
    1、前言
          今天参加了 某公司的在线笔试,其实题目很简单,一道是关于数组去重,另外一道就是字符串替换的问题。这些问题都是网上很常见的问题,但是答的并不是很理想,如果打分的话只能得到70分,面试官也说我的编程水平中等,这样的评价我是完全认同的。现在就回过头来用多种办法求解这两道题吧。
    2、数组去重
    方法1:使用hash的方法解决该问题
    <span style="font-size: 14px;"><strong>2.1.1 初次写出的代码</strong>
    Array.prototype.unique = function(){
      var arr = this, obj = {}, result ,i, len = arr.length;
      for(i=0 ; i<len; i++){
           if(!obj[arr[i]]){
               obj[arr[i]] = true;
          result.push(arr[i]);
           }
        }
        return result;
    }
    </span>

     这是我第一次写的代码,咋一看没什么问题,但是请看下面这个例子

    <span style="font-size: 14px;">var a = ['a','b','a','c',3,5,8,3,'8']
    a.unique()  //  ['a','b','c',3,5,8]
    </span>

    但是我们期望的结果是什么呢?自然是['a','b','c',3,5,8,'8'],至于什么原因大家都明白。下面是当时我写的很2的方法: 

    <span style="font-size: 14px;"><strong>2.1.2 第一次修bug</strong>
    Array.prototype.unique=  function(){
         var arr = this, obj1 = {}, obj2 = {}, result = [], i , len = arr.length;
         for(i=0; i< len; i++){
             if(typeof arr[i] === 'number'){
                  if(!obj1[arr[i]]){
               obj1[arr[1]] = true;
                     result.push(arr[i]);
                  }
              }else{
                  if(!obj2[arr[i]]){
                      obj2[arr[i]] = true;
                      result.push(arr[i]);
                  }
              }
           }
           return  result;
    }
    var a = ['a','b','a','c',3,5,8,3,'8']
    var b = a.unique(); //['a','b','c',3,5,8,'8']
    </span>

    IQ太低,上面的代码太土,太2,现在想想看还有没有其他办法。

    <span style="font-size: 14px;"><strong>2.1.3 第二次修bug</strong>
    Array.prototype.unique=  function(){
        var arr = this, obj = {}, result = [], i , len = arr.length;
        for(i=0; i< len; i++){
         if(<span style="color: #ff6600;">obj[arr[i]] !== arr[i]</span> ){
              <span style="color: #ff6600;">obj[arr[i]] = arr[i]</span>;
              result.push(arr[i]);
         }
        }
        return result;
    }
    var a = ['a','b','a','c',3,5,8,3,'8'];
    var b = a.unique();  // ['a','b','c',3,5,8,'8']
    </span>

    接下来问题来了,假如存在这样的数组 var a = ['a','b','a','c',3,5,8,3,'8',8];你妈这又出现问题了,结果为['a','b','c',3,5,8,'8',8],那就都存起来:

    <span style="font-size: 14px;"><strong>2.1.4 第三次修bug</strong>
    if(!Array.prototype.indexOf){
        Array.prototype.indexOf = function(ele,index){
            var arr = this, len = arr.length, index = index >= 0 ? index : index + len ,i;
            for(i=index; i < len; i++){
                if(arr[i] === ele){
                  return i;
                }
            }
            return -1;
        }
    }
     
    Array.prototype.unique=  function(){
        var arr = this, obj = {}, result = [], i , len = arr.length;
        for(i=0; i< len; i++){
            obj[arr[i]] = obj[arr[i]] || [];
            if(obj[arr[i]].indexOf(arr[i]) === -1 ){
                  <span style="color: #ff6600;"> obj[arr[i]].push(arr[i])</span>;
                   result.push(arr[i]);
            }
        }
        return result;
    }
    var a =  ['a','b','a','c',3,5,8,3,'8',8];
    var b = a.unique(); // ['a','b','c',3,5,8,'8'] 到目前为止应该不会出现bug了
    </span>
    方法2:使用indexOf方法或者lastIndexOf方法
         这个方法需要考虑到低版本的浏览器是不知道indexOf属性的,所以使用前非常有必要写下兼容性的代码:
    <span style="font-size: 14px;">if(!Array.prototype.indexOf){
        Array.prototype.indexOf = function(ele,index){
            var arr = this, len = arr.length, index = index >= 0 ? index : index + len ,i;
            for(i=index; i < len; i++){
                if(arr[i] === ele){
                  return i;
                }
            }
            return -1;
        }
    }
    Array.prototype.unique=  function(){
        var arr = this, obj = {}, result = [], i , len = arr.length , n;
        for(i=0; i< len; i++){
            n = <span style="color: #ff6600;">arr.indexOf(arr[i],i+1)</span>;
            if( n !== -1){
                <span style="color: #ff6600;">arr.splice(n,1)</span>;
            }
        }
        return arr;
    }
    var a =  ['a','b','a','c',3,5,8,3,'8',8];
    var b = a.unique();  //['a','b','c',3,5,8,'8']</span>
    现在想出来的也就这两种方法了。 

    【多线程】在暴力破解中的应用问题---如何避免变量在多线程中冲突(都是调用同一个值)【请各位指点一下!】 - CSDN论坛 - CSDN.NET http://bbs.csdn.net/topics/390603941

    TianYi3G2013 - 博客园 http://www.cnblogs.com/TianYi3G2013/

    两边同时发,看看哪个社区的更热心~~~~

    为方便各位帮忙调试,特附上源码:

    Thread.zip_免费高速下载|百度云 网盘-分享无限制 http://pan.baidu.com/s/1zKA4Y

    复制代码
      1 using System;
      2 using System.Collections.Generic;
      3 using System.Linq;
      4 using System.Text;
      5 
      6 using System.Threading;
      7 
      8 
      9 
     10 namespace ThreadStu
     11 {
     12     /// <summary>
     13     /// 学习如何避免变量在多线程中冲突(都是调用同一个值)
     14     /// 
     15     /// 【参考】:
     16     /// 蜘蛛爬虫多线程控制 - Robin99 - 博客园
     17     ///http://www.cnblogs.com/yinhaiming/articles/1533700.html
     18     /// 
     19     /// </summary>
     20     class Program
     21     {
     22         private static int pwd = 321;              //假设密码是321(我们一开始并不知道),现在要求利用多线程来暴力穷举它出来;
     23         private static int startNum = 1;           //假设从1开始穷举
     24         private static int count = 0;              //穷举次数; 
     25                 
     26         static void Main(string[] args)
     27         {
     28             //ThreadStart startCalu = new ThreadStart(calc);
     29             //线程开始,即每个线程都执行calc();
     30             //Thread calcThread = new Thread(startCalu);
     31             //实例化要开启的新类;
     32             //calcThread.Start();
     33             //开启线程;
     34 
     35 
     36 //         由于线程起始时启动的方法不能带有参数,这就为多线程调用同一个方法添加了麻烦。
     37 //         知道开启多线程下载的方法后,大家可能会产生几个疑问:
     38 //1.       如何控制线程的数量?
     39 //2.       如何防止多线程执行时startNum变量都是从同一数值开始以及如果防止变量count冲突(如线程1的count已经到达98了,线程2实际才10,也跟着结束了。。)?
     40 
     41 //3.       如何控制线程结束?
     42 
     43 
     44 //            下面就这几个问题提出解决方法:
     45 //1.       线程数量我们可以通过for循环来实现
     46 
     47             //比如已知用户指定了n(它是一个int型变量)个线程吧,可以用如下方法开启五个线程
     48             
     49 
     50             Thread[] calcThread;
     51          //声明下载线程,这是C#的优势,即数组初始化时,不需要指定其长度,可以在使用时才指定。这个声明应为类级,这样也就为其它方法控件它们提供了可能:
     52             ThreadStart startCalc = new ThreadStart(calc);
     53 
     54             int n = 4;
     55             calcThread=new Thread[n];
     56             //为线程申请资源,确定线程总数;
     57 
     58             for (int i = 0; i < n; i++)
     59             {
     60                 calcThread[i] = new Thread(startCalc);
     61                 //指定线程起始设置;
     62                 calcThread[i].Start();
     63                 //逐个开启线程;
     64             }
     65 
     66 
     67             //2.下面出现的一个问题:所有的线程都调用calc()方法,这样如何避免它们变量startNum都是从相同的数值开始?
     68 
     69             //★ a.这个问题也好解决,只要建立一下startNum地址表,表中的每个地址只允许被一个线程申请即可。
     70             
     71             //具体实现:..不会操作了,请各位帮忙解决!
     72 
     73 
     74             //★ b.去重问题也可以在C#语言内解决,只根建立一个临时文件(文本就可以),保存所有的startNum地址,差对它们设置相应的属性即可,但查找效率可能不及数据库快。
     75 
     76                         
     77 
     78             //4.当所有线程任务完成后,通过for循环结束:
     79 
     80             for (int i = 0; i < n; i++)
     81             {
     82                 calcThread[i].Abort();
     83             }
     84 
     85 
     86 
     87                 Console.ReadLine();
     88 
     89         }
     90         
     91         //如果要达到在第一个线程中,startNum从1开始    
     92         //            第二个线程中,.......从100开始
     93         //            第三个线程,.........从200开始
     94         //            第四个线程,.........从300....
     95         
     96 
     97         //这个startNum的值可以保存在一个文本文件中,只要能达到避免线程冲突就可以了:
     98         static void calc()
     99         {
    100             while (count < 100)                     //当一个线程把变量startNum累加100次(如果避免这个count变量线程冲突??)后停止;
    101             {
    102                 if (startNum != pwd)
    103                 {
    104                     startNum++;
    105                 }
    106                 else
    107                 {
    108 
    109 
    110 
    111                     //xxxxxxxxxxxxxxxxxxxxxxxxxxxx
    112                     //当穷举正确后,停止所有线程;
    113                     Console.WriteLine(startNum);
    114                     Console.ReadLine();
    115                 }
    116                 count++;
    117             }
    118 
    119         }
    120 
    121 
    122 
    123     }
    124 }
    复制代码

    在暴力破解中的应用问题---如何避免变量在多线程中冲突(都是调用同一个值)【请各位指点一下!】

  • 相关阅读:
    Open source cryptocurrency exchange
    Salted Password Hashing
    95. Unique Binary Search Trees II
    714. Best Time to Buy and Sell Stock with Transaction Fee
    680. Valid Palindrome II
    Java compiler level does not match the version of the installed Java project facet.
    eclipse自动编译
    Exception in thread "main" java.lang.StackOverflowError(栈溢出)
    博客背景美化——动态雪花飘落
    java九九乘法表
  • 原文地址:https://www.cnblogs.com/Leo_wl/p/3346538.html
Copyright © 2011-2022 走看看