C#_动态加载嵌入资源(DLL) - 小 .xin - 博客园

mikel阅读(2608)

来源: C#_动态加载嵌入资源(DLL) – 小 .xin – 博客园

在Resources.resx资源文件中添加资源后,编译后资源可以嵌入在exe文件中,常见的资源有:图片,音频,文本等等。在程序中通过如下代码即可调用:

Properties.Resources.*****

星号部分就是添加的资源名称,点出来就有。

调用嵌入的Dll资源

同样在Resources.resx中,嵌入一个编译好的DLL文件,如db.dll,通过代码Properties.Resources.db,返回类型是byte[],二进制格式。此时,如果想要调用其中的方法,字段,需要对这个二进制数据做处理了。下面是一个简单的方法示例:


/// <summary>
/// 动态调用资源文件
/// </summary>
/// <param name="nameSpace">使用到的命名空间</param>
/// <param name="className">使用到的类名</param>
/// <param name="lpProcName">调用的方法</param>
/// <param name="ObjArray_Parameter">方法的参数数组(如果没有则为null)</param>
/// <returns>如果调用的方法有返回值则返回,如果没有返回null</returns>
public object InvokeMethod(string nameSpace,string className,string lpProcName,object[] ObjArray_Parameter)
{
try
{
Assembly assembly = Assembly.Load(Properties.Resources.db);//加载指定的DLL程序集
Type[] type = assembly.GetTypes();
foreach(Type t in type)
{
if (t.Namespace == nameSpace && t.Name == className)//存在指定的命名空间和类
{
MethodInfo m=t.GetMethod(lpProcName);//加载需要调用的方法
if(m!=null)
{
object _object=Activator.CreateInstance(t);
return m.Invoke(_object, ObjArray_Parameter);//调用指定的方法,并返回结果(如果有)
}
else
System.Windows.Forms.MessageBox.Show("方法:"+lpProcName+" 不存在!");
}
else
System.Windows.Forms.MessageBox.Show("命名空间:" + nameSpace + ",类:" + className+" 不存在!");
}
}
catch(Exception e)
{
MessageBox.Show(e.Message);
}
return null;
}

当然如果不用Resources.resx,可以通过添加现有项的方式来添加dll资源,此时,需要修改文件属性,【生成操作】改为 嵌入的资源,然后通过以下方法来调用:


private byte[] LoadDll(string lpFileName)
{
Assembly assembly = Assembly.GetExecutingAssembly();
try
{
Stream stream = assembly.GetManifestResourceStream(assembly.GetName().Name + "." + lpFileName);
byte[] buffer = new byte[(int)stream.Length];
stream.Read(buffer, 0, buffer.Length);
stream.Close();
return buffer;
}
catch(Exception e)
{
MessageBox.Show(e.Message);
}
return null;
}

/// <summary>
/// 动态调用资源文件
/// </summary>
/// <param name="lpFileName">DLL名</param>
/// <param name="nameSpace">使用到的命名空间</param>
/// <param name="className">使用到的类名</param>
/// <param name="lpProcName">调用的方法</param>
/// <param name="ObjArray_Parameter">方法的参数数组(如果没有则为null)</param>
/// <returns>如果调用的方法有返回值则返回,如果没有返回null</returns>
public object InvokeMethod(string lpFileName,string nameSpace,string className,string lpProcName,object[] ObjArray_Parameter)
{
try
{
Assembly assembly=Assembly.Load(LoadDll(lpFileName));//加载指定的DLL程序集
Type[] type = assembly.GetTypes();
foreach(Type t in type)
{
if (t.Namespace == nameSpace && t.Name == className)//存在指定的命名空间和类
{
MethodInfo m=t.GetMethod(lpProcName);//加载需要调用的方法
if(m!=null)
{
object _object=Activator.CreateInstance(t);
return m.Invoke(_object, ObjArray_Parameter);//调用指定的方法,并返回结果(如果有)
}
else
System.Windows.Forms.MessageBox.Show("方法:"+lpProcName+" 不存在!");
}
else
System.Windows.Forms.MessageBox.Show("命名空间:" + nameSpace + ",类:" + className+" 不存在!");
}
}
catch(Exception e)
{
MessageBox.Show(e.Message);
}
return null;
}

说明

1.调用的方法当然只能调用公有的或者同程序集的,private是无法调用的。

2.以上代码修改于网络上某些糟糕的文章,已成功编译通过。

3.这里么有做更详细的解释,仅贴了些代码,这些东西都能一看理解吧,至少知道该如何使用它。

4.有任何疑问,留言回复…

5.么有了…

.net 动态加载Dll - icyjiang - 博客园

mikel阅读(1112)

来源: .net 动态加载Dll – icyjiang – 博客园

在程序正在使用的过程中,常常需要升级DLL。这时,如果dll已经被主程序引用,则无法修改,这样的需求应该很常见。换个角度,可以理解成程序的升级或者修改Bug的功能。

以下通过动态的加载Dll来解决这个问题。

整个思路的前提是,动态调用的东西和前台需要的功能通过代理IBaseInterface连接起来,也就是说动态dll里面的类和Proxy都需要实现这个接口。


namespace BaseInterface
{
public interface IBaseInterface
{
string GetString();
}
}

核心代码:Proxy.dll

<pre>namespace Proxy
{
    internal class AppDomainCore
    {
        public AppDomain DefaultAppDomain { get; private set; }
        public string DefaultAppDomainName { get; private set; }

        public AppDomainCore(string appDomainName)
        {
            DefaultAppDomainName = appDomainName;
            AppDomainSetup setup = new AppDomainSetup();
            setup.ApplicationBase = AppDomain.CurrentDomain.BaseDirectory;
            setup.ConfigurationFile = AppDomain.CurrentDomain.SetupInformation.ConfigurationFile;

            Evidence evidence = new Evidence(AppDomain.CurrentDomain.Evidence);
            DefaultAppDomain = AppDomain.CreateDomain(appDomainName, evidence, setup);
        }

        public bool ClearAppDomain()
        {
            try
            {
                AppDomain.Unload(DefaultAppDomain);
                DefaultAppDomain = null;
                return true;
            }
            catch { return false; }
        }

        ~AppDomainCore()
        {
            ClearAppDomain();
        }
    }
}</pre>
<div class="cnblogs_code_toolbar"><span class="cnblogs_code_copy"><a title="复制代码"><img src="http://www.mikel.cn/wp-content/uploads/2015/05/copycode30.gif" alt="复制代码" data-bd-imgshare-binded="1" /></a></span>namespace Proxy
{
internal class AssemblyCore
{
public string ActivedAssemblyName { get; private set; }
public string CurrentType { get; private set; }
public FileInfo DefaultAssemblyFile { get; private set; }

public AssemblyCore(string assemblyName, string type)
{
ActivedAssemblyName = assemblyName;
CurrentType = type;

try
{
DefaultAssemblyFile = new FileInfo(assemblyName);
}
catch (Exception ex)
{
MessageBox.Show(ex.Message);
}
}
}
}</div>
<div class="cnblogs_code_toolbar"></div>
<div class="cnblogs_code_toolbar">namespace Proxy
{
public class Proxy : BaseInterface.IBaseInterface
{
AssemblyCore _assemblyCore;
AppDomainCore _appDomainCore;

public string DefaultAssemblyName { get { return _assemblyCore.ActivedAssemblyName; } }
public string DefaultAppDomainName { get { return _appDomainCore.DefaultAppDomainName; } }

public Proxy(string assemblyName, string typeName, string appDomainName)
{
_assemblyCore = new AssemblyCore(assemblyName, typeName);
_appDomainCore = new AppDomainCore(appDomainName);
}

public void UnLoad()
{
_appDomainCore.ClearAppDomain();
}

BaseInterface.IBaseInterface _proxy;
public string GetString()
{
if (_proxy == null)
_proxy = _appDomainCore.DefaultAppDomain.CreateInstanceFromAndUnwrap(
_assemblyCore.ActivedAssemblyName, _assemblyCore.CurrentType)
as BaseInterface.IBaseInterface;
return _proxy.GetString();
}
}
}</div>
<div class="cnblogs_code_toolbar">

以上代码在项目Proxy里面写入,是动态加载Dll的核心代码。

在Proxy里面,其中AppDomainCore根据传递的参数生成新的AppDomain, AssemblyCore则根据传递的参数生成新 的FileInfo. 在Proxy类里面,同时定义一个AssemblyCore和AppDomainCore,根据方 法:_appDomainCore.DefaultAppDomain.CreateInstanceFromAndUnwrap(_assemblyCore.ActivedAssemblyName, _assemblyCore.CurrentType), 动态的生成实例,最后用as 转换成接口IBaseInterface,通过调用接口的GetString方法来调用dll里面的方法。

一下为模拟的两个Dll类,


namespace Assembly1
{
[Serializable]
public class ClassLibrary : MarshalByRefObject, BaseInterface.IBaseInterface
{
public string GetString()
{
return "Assembly1.ClassLibrary";
}
}
}
<pre>namespace Assembly2
{
    [Serializable]
    public class ClassLibrary : MarshalByRefObject, BaseInterface.IBaseInterface
    {
        public string GetString()
        {
            return "Assembly2.ClassLibrary";
        }
    }
}</pre>
<div class="cnblogs_code_toolbar"><span class="cnblogs_code_copy"><a title="复制代码"><img src="http://www.mikel.cn/wp-content/uploads/2015/05/copycode30.gif" alt="复制代码" data-bd-imgshare-binded="1" /></a></span>

分别生成到Assembly v1.0.dll和Assembly v2.0.dll中。

最终的界面代码:


namespace DynamicDll
{
public partial class Form1 : Form
{
Proxy.Proxy _proxy;
public Form1()
{
InitializeComponent();
LoadDll("Assembly v1.0.dll", "Assembly1.ClassLibrary", "Domain1");
radV1.Click += (a, b) =&gt; LoadDll("Assembly v1.0.dll", "Assembly1.ClassLibrary", "Domain1");
radV2.Click += (a, b) =&gt; LoadDll("Assembly v2.0.dll", "Assembly2.ClassLibrary", "Domain2");
}

void LoadDll(string assName, string type, string appName)
{
if (_proxy != null) _proxy.UnLoad();
_proxy = new Proxy.Proxy(assName, type, appName);
lblCurrentAppDomain.Text = _proxy.DefaultAppDomainName;
lblCurrentAssembly.Text = _proxy.DefaultAssemblyName;
lblMainAppDomain.Text = AppDomain.CurrentDomain.FriendlyName;
}

private void btnRes_Click(object sender, EventArgs e)
{
txtRes.Text = _proxy.GetString();
}
}
}

 

查看项目Dynamic的依赖项,可以很清楚的看到:它只依赖BaseInterface和Proxy两个项目,与Assembly v1.0和v2.0都无关。

也就是说,程序运行的时候,可以修改Assembly v1.0和v2.0里面的代码,重新生成,同时替换运行目录下的dll。

 

C#动态加载DLL - 老D - 博客园

mikel阅读(1086)

来源: C#动态加载DLL – 老D – 博客园

利用反射进行动态加载和调用.
Assembly ass=Assembly.LoadFrom(DllPath); //利用dll的路径加载,同时将此程序集所依赖的程序集加载进来,需后辍名.dll
Assembly.LoadFile 只加载指定文件,并不会自动加载依赖程序集.Assmbly.Load无需后辍名
加载dll后,需要使用dll中某类.
Type type=ass.GetType(“TypeName”);//利用类型的命名空间和名称获得类型
需要实例化类型,才可以使用,参数可以人为的指定,也可以无参数,静态实例可以省略
Object obj = Activator.CreateInstance(type,params[]);//利用指定的参数实例话类型
调用类型中的某个方法:
需要首先得到此方法
MethodInfo mi=type.GetMethod(“MehtodName”);//通过方法名称获得方法
然后对方法进行调用,多态性利用参数进行控制
mi.Invoke(obj,params[]);//根据参数直线方法,返回值就是原方法的返回值

Objective-C中的@property和@synthesize用法

mikel阅读(1033)

@代表“Objective-C”的标志,证明您正在使用Objective-C语言

 

Objective-C语言关键词,@property与@synthesize配对使用。

 

功能:让编译好器自动编写一个与数据成员同名的方法声明来省去读写方法的声明。

 

如:

1、在头文件中:

C代码  收藏代码
  1. @property int count;

等效于在头文件中声明2个方法:

C代码  收藏代码
  1. – (int)count;
  2. -(void)setCount:(int)newCount;

 

2、实现文件(.m)中

C代码  收藏代码
  1. @synthesize count;

等效于在实现文件(.m)中实现2个方法。

C代码  收藏代码
  1. – (int)count
  2. {
  3.     return count;
  4. }
  5. -(void)setCount:(int)newCount
  6. {
  7.     count = newCount;
  8. }

 

以上等效的函数部分由编译器自动帮开发者填充完成,简化了编码输入工作量。

 

格式:

 

声明property的语法为:@property (参数1,参数2) 类型 名字;

 

如:

C代码  收藏代码
  1. @property(nonatomic,retain) UIWindow *window;

 

其中参数主要分为三类:

读写属性: (readwrite/readonly)

setter语意:(assign/retain/copy)

原子性: (atomicity/nonatomic)

 

各参数意义如下:

 

readwrite: 产生setter\getter方法

readonly: 只产生简单的getter,没有setter。

assign: 默认类型,setter方法直接赋值,而不进行retain操作

retain: setter方法对参数进行release旧值,再retain新值。

copy: setter方法进行Copy操作,与retain一样

nonatomic: 禁止多线程,变量保护,提高性能

 

参数类型

参数中比较复杂的是retain和copy,具体分析如下:

 

getter 分析

 

1、

C代码  收藏代码
  1. @property(nonatomic,retain)test* thetest;
  2. @property(nonatomic ,copy)test* thetest;

等效代码:

C代码  收藏代码
  1. -(void)thetest
  2. {
  3.   return thetest;
  4. }

 

2、

C代码  收藏代码
  1. @property(retain)test* thetest;
  2. @property(copy)test* thetest;

等效代码:

C代码  收藏代码
  1. -(void)thetest
  2. {
  3.     [thetest retain];
  4.     return [thetest autorelease];
  5. }

 

setter分析

 

1、

C代码  收藏代码
  1. @property(nonatomic,retain)test* thetest;
  2. @property(retain)test* thetest;

等效于:

C代码  收藏代码
  1. -(void)setThetest:(test *)newThetest {
  2.     if (thetest!= newThetest) {
  3.         [thetestrelease];
  4.         thetest= [newThetest retain];
  5.     }
  6. }

 

2、

C代码  收藏代码
  1. @property(nonatomic,copy)test* thetest;
  2. @property(copy)test* thetest;

等效于:

C代码  收藏代码
  1. -(void)setThetest:(test *)newThetest {
  2.     if (thetest!= newThetest) {
  3.         [thetest release];
  4.         thetest= [newThetest copy];
  5.     }
  6. }

 

nonatomic

如果使用多线程,有时会出现两个线程互相等待对方导致锁死的情况(具体可以搜下线程方面的注意事项去了解)。在没有(nonatomic)的情况下,即默认(atomic),会防止这种线程互斥出现,但是会消耗一定的资源。所以如果不是多线程的程序,打上(nonatomic)即可

 

retain

代码说明

如果只是@property NSString*str; 则通过@synthesize自动生成的setter代码为:

C代码  收藏代码
  1. -(void)setStr:(NSString*)value{
  2.     str=value;
  3. }

 

如果是@property(retain)NSString*str; 则自动的setter内容为:

C代码  收藏代码
  1. -(void)setStr:(NSString*)v{
  2.     if(v!=str){
  3.         [str release];
  4.         str=[v retain];
  5.     }
  6. }

 

 

所有者属性

我们先来看看与所有权有关系的属性,关键字间的对应关系。

属性值 关键字 所有权

strong __strong
weak __weak
unsafe_unretained __unsafe_unretained
copy __strong
assign __unsafe_unretained
retain __strong

strong

该属性值对应 __strong 关键字,即该属性所声明的变量将成为对象的持有者。

weak

该属性对应 __weak 关键字,与 __weak 定义的变量一致,该属性所声明的变量将没有对象的所有权,并且当对象被破弃之后,对象将被自动赋值nil。

并且,delegate 和 Outlet 应该用 weak 属性来声明。同时,如上一回介绍的 iOS 5 之前的版本是没有 __weak 关键字的,所以 weak 属性是不能使用的。这种情况我们使用 unsafe_unretained。

unsafe_unretained

等效于__unsafe_unretaind关键字声明的变量;像上面说明的,iOS 5之前的系统用该属性代替 weak 来使用。

copy

与 strong 的区别是声明变量是拷贝对象的持有者。

assign

一般Scalar Varible用该属性声明,比如,int, BOOL。

retain

该属性与 strong 一致;只是可读性更强一些。

 

 

参考:

http://blog.eddie.com.tw/2010/12/08/property-and-synthesize/

http://www.cocoachina.com/bbs/read.php?tid=7322

http://www.cnblogs.com/pinping/archive/2011/08/03/2126150.html

 

 

声明的分类

在 Objective-C官方文档 中的Property一章里有对类Property详细说明。
@property中的声明列表已分类为以下几种:

1, 声明属性的访问方法:

  • getter=getterName
  • setter=setterName
    声明访问属性的设置与获取方法名。

2,声明属性写操作权限:

  • readwrite
    声明此属性为读写属性,即可以访问设置方法(setter),也可以访问获取方法(getter),与readonly互斥。
  • readonly
    声明此属性为只读属性,只能访问此属性对应的获取方法(getter),与readwrite互斥。

3,声明写方法的实现:

  • assign
    声明在setter方法中,采用直接赋值来实现设值操作。如:
C代码  收藏代码
  1. -(void)setName:(NSString*)_name{
  2.      name = _name;
  3. }
  • retain
    声明在setter方法中,需要对设过来的值进行retain 加1操作。如:
C代码  收藏代码
  1. -(void)setName:(NSString*)_name{
  2.      //首先判断是否与旧对象一致,如果不一致进行赋值。
  3.      //因为如果是一个对象的话,进行if内的代码会造成一个极端的情况:当此name的retain为1时,使此次的set操作让实例name提前释放,而达不到赋值目的。
  4.      if ( name != _name){
  5.           [name release];
  6.           name = [_name retain];
  7.      }
  8. }
  • copy
    调用此实例的copy方法,设置克隆后的对象。实现参考retain。

4,访问方法的原子性:

  • nonatomic
    在默认的情况下,通过synthesized 实现的 setter与getter 都是原子性访问的。多线程同时访问时,保障访问方法同时只被访问一个线程访问,如:
  • C代码  收藏代码
    1. [ _internal lock ]; // lock using an object-level lock
    2. id result = [ [ value retain ] autorelease ];
    3. [ _internal unlock ];
    4. return result;
  • 但如果设置nonatomic时,属性的访问为非原子性访问。

 

来源:http://wiki.magiche.net/pages/viewpage.action?pageId=1540101

 

 

@synthesize tabBarController=_tabBarController;

@synthesize 中可以定义 与变量名不相同的getter和setter的命名,籍此来保护变量不会被不恰当的访问

Android HttpClientConnection Get and Post - Epirus - 博客园

mikel阅读(1150)

来源: Android HttpClientConnection Get and Post – Epirus – 博客园

KeyPoint:

1.HttpClientConnection 默认是使用Get的方式的

Get方式的KeyCode

class DownloadTask extends AsyncTask<String, Integer, String>{
        String resultData="lee";
        @Override
        protected String doInBackground(String... params) {
             try {
                    URL url=new URL("http://www.baidu.com");
                    HttpURLConnection conn=(HttpURLConnection)url.openConnection();
                    conn.setDoInput(true);
                    InputStreamReader isr=new InputStreamReader(conn.getInputStream());
                    BufferedReader buffer=new BufferedReader(isr);
                    String inputLine="";
                
                    while((inputLine=buffer.readLine())!=null){
                        resultData+=inputLine+"\n";
                    }
                    isr.close();
                    conn.disconnect();
                    System.out.println(resultData);
                    
            } catch (Exception e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
        
            }
            
        
        
            return null;
        }
        @Override
        protected void onPostExecute(String result) {
            textView.setText(resultData);
            super.onPostExecute(result);
        }
    
        
    }

  这可以作为内部类放到Activity 中然后就可以直接访问UI的组件了

2.HttpClient->Post 使用Apache的,感觉非常的简洁,一个字爽

publicvoid postData(){
    // Create a new HttpClient and Post Header
    HttpClient httpclient =newDefaultHttpClient();
    HttpPost httppost =newHttpPost("http://www.yoursite.com/script.php");

    try{
        // Add your data
        List<NameValuePair> nameValuePairs =newArrayList<NameValuePair>(2);
        nameValuePairs.add(newBasicNameValuePair("id","12345"));
        nameValuePairs.add(newBasicNameValuePair("stringdata","AndDev is Cool!"));
        httppost.setEntity(newUrlEncodedFormEntity(nameValuePairs));
     
        // Execute HTTP Post Request
        HttpResponse response = httpclient.execute(httppost);
      //Get Data 
     bufferedReader=new BufferedReader(new InputStreamReader(response.getEntity().getContent()));
      while((inputLine=bufferedReader.readLine())!=null){resultData+=inputLine+"\n";}
        
    }catch(ClientProtocolException e){
        // TODO Auto-generated catch block
    }catch(IOException e){
        // TODO Auto-generated catch block
    }
}

如果需要使用Get方式则,设置HttpGet httpget一样的

3. HttpClientConnection POST method 官方推荐使用,其实httpclient也停止了维护,所以这个会是将来的趋势

class DownloadTask extends AsyncTask<String, Integer, String>{
        String resultData="lee";
        @Override
        protected String doInBackground(String... params) {
             try {
                    URL url=new URL("http://xxxxxx.xxxx/index.php");
                    HttpURLConnection conn=(HttpURLConnection)url.openConnection();
                    conn.setDoInput(true);
                    conn.setDoOutput(true);
                    conn.setRequestMethod("POST");
                    conn.setUseCaches(false);  
                    conn.setInstanceFollowRedirects(true);
                    conn.setRequestProperty("Content-Type", "application/x-www-form-urlencoded"); 
                    conn.connect();
                    DataOutputStream out = new DataOutputStream(conn.getOutputStream());
                    String content="username="+URLEncoder.encode("lee","UTF-8");
                    out.writeBytes(content);
                    out.flush();
                    out.close();
                    InputStreamReader isr=new InputStreamReader(conn.getInputStream());
                    BufferedReader buffer=new BufferedReader(isr);
                    String inputLine="";
                
                    while((inputLine=buffer.readLine())!=null){
                        resultData+=inputLine+"\n";
                    }
                    isr.close();
                    conn.disconnect();
                    System.out.println(resultData);
                    
            } catch (Exception e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
        
            }
            
        
        
            return null;
        }

今年,这些互联网公司要上市 也有O2O公司倒闭的

mikel阅读(1816)

原文:《今年,这些互联网公司要上市》,摘要:

暴风科技回归A股,短短一个月市值增长20多倍。三十多个涨停板一字排开,蔚为壮观。这是以实际表现向国内的同行们招手喊话:股市人傻钱多,速来!

如今的科技概念股的确风头无两,而一大波国内互联网公司也趁势想在股市分一杯羹。具体哪些公司有上市的可能呢?接下来笔者为大家盘点一番。

 

 

  一、滴滴快的

去年的情人节,滴滴与快的上演了一幕仇敌变爱人的戏码,让不少无法和男女朋友共度周末的“媒体老师”腹诽了半天。

合体之后的新公司自然成为了投资人的宠儿,据说估值达到了六十亿美金以上,而市占率上来讲,如果将之前两家公司分别公布的数据相加,总公司的市占率将超越100%,这中间当然有一定的水分,但新公司成为行业老大是必然的。

两家的合并其实一定程度上是资本的意志,双方斗的死去活来,烧的都是投资人的钱,不如结成秦晋之好,拉着手去上市,投资人也可以在高市值时赶紧套现,皆大欢喜。

而另一方面讲,uber是这个行业一个很大的不确定性因素,尽管这两天在广州和成都受到了一定的阻力,但一旦专车相关法律规范落地,收益最大的其实是这个外来者,毕竟人家有钱。因此虽然新公司几乎主宰了市场,但烧钱还不能停,资金哪里来?最好的途径就是股市吧。

所以快的吕传伟也在内部邮件中明确表示:合并之后,上市计划会提上日程。至于时间,应该就在今年。

  二、搜狗

搜狗下半年上市的消息已经甚嚣尘上,原因是搜狗已经实现了规模性盈利,具备了上市讲故事的资本。

搜狗去年第四季度收入同比增长70%达到了1.19亿美元,全年实现了3300万美元的盈利,如果根据纳斯达克46倍左右的市盈率,搜狗的上市后的市值可以达到十亿美元以上,而事实上,国外媒体给出的数据更高,是30亿美金。

搜狗上市有动力吗?如果从融资需求来看,动力不大,有搜狐这个亲爹,还有腾讯这个干爹,这样的孩子总缺不着钱花。

但从上市故事这个角度来讲,搜狗又有上市的理由,毕竟王小川也在去年放话了:搜狗已经迎来了历史上最好的时期。

自从接入微信入口以来,搜狗在移动端表现非常亮眼,但这样的快速增长是否具有持续性是存疑的,毕竟在如京东这样体量的公司身上,微信入口似乎并 没有展示出太大的作用。因此,仍身处增量市场的搜狗,有必要冲刺上市,一来可以可以凭借高速的增长赢得更好的估值,二来可以在上市后,为自己的股价增长迎 来更大的空间。

现在唯一的问题是在哪上市。目前美国市场对中国概念股的热情不高,盛大、完美纷纷退市已经很能说明问题,选择A股上市吗?这可能也是一个不错的选项。

  三、美丽说

对于某些男同胞来说,美丽说这家公司可能从来都没听说过,但现在请务必记住这个名字,因为它可能会成为你老婆(女朋友)败家的又一个作案场所。

女人的钱好赚,于是传说这家公司也要上市了。

先是2月27日,有媒体报道称美丽说已经邀请了魏萍担任其公司的CFO。之后,又有外媒爆料,称美丽说正在寻求新一轮约3亿美金的融资,为上市做最后的冲刺。

服装类电商已经有了阿里这么个天然的巨无霸对手,但爱败家的女同志这么多,市场总还是有得。据称美丽说今年的业绩有望达到150亿人民币,其估值也达到了30亿美元。

不过资本市场虽然需要针对企业目前的状况做出投资评估,但更看重的是企业的发展潜力。电商已经是一个红海行业,想要上市,好的故事是必不可少的。

说到这点,美丽说和搜狗一样身背微信概念,因此微信的导流作用,在现在是一个很好的故事;同时,美丽说在与蘑菇街、明星衣橱这两个同行姐妹的品牌比拼中,并不占上风,在大家都加大投入,很难分出高下的情况下,抓紧时间上市融资拉开差距,是一个很不错的选择。

最后,在有了唯品会这只妖股做榜样之后,女性电商们对海外资本市场或许会更有信心,成败在此一举,上市或许就在今年。

  四、大众点评

其实在团购这个行业美团才是老大,但人家老大王兴已经放出了“团购行业谁先上市谁就认输了”这样的豪言,所以在这里就不给人家掺和了。

大众点评会认输吗?当然不会。但他们一直在宣称团购只占了自己业务的20%,因此赶在美团前上市,貌似也不算是认输。

今年年初有消息称,大众点评确定新一轮8.5亿美元的融资,公司的估值达到了40.5亿美元。如果消息属实的话,这已经算是公开确认过的第F轮融资,字母第一排已快用完。

从融资需求上来讲,大众点评的上市欲望同样不是很大,加上去年腾讯的2亿美元投资,这笔巨款可以烧上很长一段时间。

但事实上,大众点评一直都在做上市的准备,用张涛自己的话来说,IPO本身是一个节点,是为了让公司发展的更好,大众点评已经在年初办好了上市的手续,准备工作已经做好。

在年前,大众点评也的确有很多的动作:业务多方向扩展,媒体频频发声,一副卯足了劲冲击上市的样子。原因也不难理解,阿里等巨头已经开始在点评的业务领域发力,留给点评慢慢发展的时间不多了。

不过,点评上市的困难也并不小,首先是有用户但变现难的困局难以突破,其次,其树立的美国标杆yelp和groupon表现都非常乏力,yelp股价大涨,原因竟然是因为要出售了。

因此综合看来,点评有上市的冲动,也有上市的能力,但困难不小,也有后路,不排除暂时留力,年后再战的可能

  五、e代驾

今年的5月5日,e代驾在微信群中向媒体们宣布,他们已经完成了D轮融资,额度1亿美元,估值达到了8亿美元。

在出行行业这个大概念中,e代价似乎显得并不起眼,但在代驾这个细分领域,它却是毋庸置疑的行业老大。而这个细分市场的潜力,貌似并不小。据国内某研究机构表示,未来五年国内代驾市场的规模或许将达到500亿美元。

这样大的蛋糕,自然会有人想要来啃上一两口。比如刚刚合并的滴滴快的,就在前段时间宣布推出了代驾业务,因此对于e代驾来说,上市融资,迅速扩大规模必须得提上日程了,否则拿什么和这些巨头拼。

e代驾上市有戏吗?当然。从成功模板上来说,韩国最大的代驾公司韩代驾已经成功上市,而坐拥更大市场的e代驾没有理由不被资本市场认可。同时,e代驾也在拓展自己的业务,继续丰满自己的上市故事。

  六、美图公司

如果从用户量上来说,美图秀秀这家公司不上市真的是屈才了。

据他们公布出来的数据,其全线产品的用户数已经达到了7.4亿,移动端用户数达到了4.22亿,在这个有用户就是大爷,移动胜过一切的年代,美图秀秀似乎赶超BAT指日可待了。

但事实上,资本市场对于图片处理市场并不看好,最主要的原因是粘性不强,盈利模式不明朗,空有一大批爱美的女用户,却始终不能变现。

所以美图也在试图转型。一方面推出美拍增强社交属性,提高用户粘度;另一方面推出手机,争取解决现金流的问题。

在如今监管部门鼓励国内互联网公司创业板上市的大背景下,在有了乐视、暴风等成功案例的前提下,蔡文胜有动力积极的推动美图上市,市场变现难,股市套现貌似就容易多了。

  七、大疆

最近这两年,智能硬件很不讲理的火了,而无人机市场也跟着热闹了起来。尤其是在日前飞了一回白宫,又跟着汪峰上了一回头条之后,大疆这个品牌开始被越来越多的普通消费者所熟知。

日前,国外有媒体称大疆刚刚获得了7500万美元的融资,公司的估值达到了80亿美元。投资者在接受采访时对大疆不吝赞美之词,称其为来自中国的第一批真正的技术创新企业。

从营收上来讲,大疆去年的全球收入达到了20亿人民币,这其中绝大部分来自于国外。有媒体估计,其今年的销售额将超过10亿美金。

有概念,有营收,被海外资本认可,大疆似乎上市很有希望,最新的融资也被看成是为上市做准备。这样的传言其实是有依据的,毕竟随着国家在无人机领域相关政策的落地,这个领域的竞争正在变得残酷,而且,2013年大疆工作人员也曾宣称要两年内上市。

但在今年,其公关总监邵健伙却改了说法,他宣称在至少5年内,公司没有考虑上市,要专注于产品。这究竟是真话,还是放烟雾弹,咱们还是等着看吧。

原文:《迅速倒闭从上线到关门只有14个月》,摘要:

“一位曾在不打烊公司上班的员工告诉记者,由于经营不善,不打烊公司在上个月停止了运营,至今还欠约150名员工五六十万薪水。而此时距离其2013年12 月24日正式上线,只有一年两个月时间。3月25日记者登录“不打烊”官网,发现网站已很久没有更新,主业的促销活动还停留在国庆出游产品推荐。随后记者 又拨打了公司客服电话:96567和5255716,提示为忙音和空号。

“不打烊”为何这么快“打烊”?

1、与家门口超市没有竞争力

“送货上门、24小时不打烊,这是安庆从未有过的销售模式,我用过确实很方便,有市场需求。 ”一位网友说。但也有人认为,这样的电商模式配错了超市,“安庆城市规模不大,家门口都有超市,送货上门、24小时不打烊没有多少竞争力。 ”

2、团队太年轻公司发展太快

曾担任该公司业务经理的王丽(化名)则坚信“不打烊”方向是对的,“失败是因为我们没有准备好,我们的团队太年轻了,没有经验。比如,物流、贸易、营销、 市场等模块都有很深的学问,需要精打细算,但其实从公司老总到下面员工,几乎都不懂,公司发展太快,暴露出很多一时无法解决的问题。 ”

3、与社区超市竞争是方向错误

安庆市高新技术创业服务中心的一名专业人士告诉记者,他其实一直不看好“不打烊”,从目前电商形势上看,O2O模式发展的盈利模式尚不清晰,而电商烧钱太快,刘李程本人的资金实力并不雄厚。

对于一个没有任何实体超市背景的互联网企业,做这个本身就是一个错误的选择。现在二三线城市的社区超市已经是饱和状态,价格也很合理,没有很大的利润空 间,而且部分也可以免费送货。 “你去跟这么多社区店打没有差异化的竞争,能搞过吗?我们不说能不能挣钱,首先你的盈利能抵消你的配送成本吗?所以是方向错了,越努力只会越辛苦。 ”一家知名电商创办人说。

 

观点:

原文看完了,第一篇看了让人兴奋,第二篇也让人深思,两篇文章比较着来看,就大有深意了,也就是O2O的乱局更加混乱,一招棋走错满盘皆空,为什么几家欢喜几家愁,定位要准,否则动了别人的奶酪或者资金不济,只能打样回家了。

上市就像鲤鱼跳龙门,没有好的概念难得走到这步,可要走到这步O2O是否算成功也很难说,大众点评、滴滴无不是抱了大腿,实力为尊依然是O2O乱世中的主流势力,没有好的靠山难能有个结果。

如何成为一个糟糕的程序员_IT新闻_博客园

mikel阅读(912)

来源: 如何成为一个糟糕的程序员_IT新闻_博客园

英文原文:How to become a lousy developer

想要成为优秀的开发人员很难。那我们就来说说如何成为一个糟糕的开发人员!

只学一遍

想要实现功能,想要让功能正常工作,呵呵,你的方法是不是这样子的呢:

不接触、不思考、也不去想能不能改善

为什么要我来解决问题?没有损坏的部分就用不着修复了吧?进展程度慢,无所谓,代码不可读或者是从程序的其他部分复制粘贴来的,也无所谓,哪怕是摘自于一些见不得人的网站的,也可以。只要能解决问题,那就万事大吉了。

照此推论,我们的做法是:不读书,不读博客、文章,不接受他人的见解,也不看网络广播。为什么要你来解决这个难题呢,很显然你的知识是最匹配的,看上去非你不可,所以……你觉得根本用不着浪费时间——一旦掌握这知识之后,完全没必要深入学习嘛!

顺便说一句,你也不需要学习新的编程语言。 Groovy? Clojure? Scala?呸,通通都是骗人的!看看那些只会 COBOL 的家伙:不是依然干得风生水起么!

不要钻研自己学到的东西

好吧,不管怎么说,你毕竟学到了点东西。在 StackOverflow 上搜索解决方案,偶然发现 Martin Fowler 的一篇文章讲得还挺吸引人,又或者觉得过于无聊而将《The Clean Coder》束之高阁。

反正你学到什么都不要去钻研。是的,只需要盲从这些死板的内容就可以了:不要去验证这些知识的真假,也不要检查它是否适合你的风格!凡事只学一遍哦亲!

从不同的角度观察,然后思考出一些独特的见解……何苦呢,应用了,解决问题了,那就可以轻轻松松回家玩游戏了。以后的事以后再说,得过且过知道不?

不接受他人的见解和指导

这是显而易见的,因为……难道他们的话就一定正确吗?

你已经学会如何解决这个问题。并且很管用。那不就成了。别人凭什么质疑你的编码方式?你也没有必要去学习解决问题的其他途径!

倚老卖老,喋喋不休什么的真心是太讨厌了,还会伤害偶们的自我意识。所以,不要听这些家伙的罗里吧嗦。

不需要让你的代码变得可读

仔细想想:为什么要让代码变得可读呢?说的好像我们还要常回去看看一样?你的代码已然是非常棒,又能工作,所以我们不需要再去碰触它。

此外,对于计算机而言,它才不管这些代码是否可读呢,只要能运行程序就成。你的代码不是为了方便其他程序员阅读而写的。事实上,最好只有你能读得懂,这样这份工作就非你不可了,不是吗?

不写测试

Loser 才需要测试。测试是愚蠢者的墓志铭。

请相信自己的代码是完美的!你永远不会犯错误——有也是因为编程语言有缺陷,或者是机器的错。

如果代码能在你的机器上运行,那么没有理由不能在其他地方正常运行,永永久久地正常运行。

除了写代码,其他的啥也别干

为什么要分析需求,了解业务,写测试,学习如何在自己电脑之外的地方部署呢?

况且,这些事对你写代码一点好处也没有,是吧?完成这些任务除了浪费时间,有帮助吗?

不要帮助别人

不要帮助别人:让他们自己想办法。也许他们会问你是如何解决他们眼中的难题的,但是你为什么要多费唇舌呢?反正已经搞定了,不是吗?

而且,搞不好那个程序员也和你一样根本听不进其他人的建议:“不接受他人的见解和指导”这一条,没忘记吧?

帮助他人不但费时,还会让你怀疑自己的知识和能力,这是不应该出现的情况。所以,各人自扫门前雪莫管他人瓦上霜。

结论

掌握了上述所有技巧,那么你就成功成为了一个糟糕的开发人员。糟糕但活得舒服的开发人员。别谢我!

为此干杯!

咦,你说你不想成为一个糟糕的开发人员?

好吧,但是首先,我要郑重告诉你,这条路绝对会走得很艰难,请做好心理准备:

  1. 对于上面如何成为“糟糕开发人员”的技巧完全要反着来。没错,我指的是所有,每一条!
  2. 经常性地反省和自我批评:这有效吗?为什么有效?为什么无效?还有没有改进的可能呢?思考的过程或许会让人无比头大,但也会让你不断地进步。
  3. 阅读 Robert C. Martin 写得《The Clean Coder》。这不是在推销。如果你有志于成为一名真正的专业开发人员,而不是糟糕的开发人员,它绝对对得起你花的每一分钱。

好了,现在就向着目标出发吧!

译文链接:http://www.codeceo.com/article/how-to-become-lousy-programmer.html

翻译作者:码农网 – 小峰

 

出现( linker command failed with exit code 1)错误总结

mikel阅读(856)

这种问题,通常出现在添加第三方库文件或者多人开发时。

这种问题一般是找不到文件而导致的链接错误。 我们可以从如下几个方面着手排查。

1.以如下错误为例,如果是多人开发,你同步完成后发现出现如下的错误。

   1. Undefined symbols for architecture armv7:
   2.   "_OBJC_CLASS_$_MyPageLogViewController", referenced from:
   3.       objc-class-ref in BaiduMobStatAppDelegate.o
   4. ld: symbol(s) not found for architecture armv7
   5. clang: error: linker command failed with exit code 1 (use -v to see invocation)

错误中出现了“MyPageLogViewController”这个类,你可以找到这个类的.m文件, 查看他的Target Membeship, 如下图

如果没有勾选上,点击勾选。然后编译查看。

2. 如果是新添加的第三方库,且不是静态库

先重复第一步过程,然后找到 Build settings->Linking->Other Linker Flags

将此属性修改成-all_load  或者 -ObjC ,这个视情况而定。总之可以多试几次。

3.如果添加的是第三方静态库(.a文件)

# Undefined symbols for architecture armv7:
#   "_OBJC_CLASS_$_BaiduMobStat", referenced from:
#       objc-class-ref in BaiduMobStatAppDelegate.o
#       objc-class-ref in MyPageLogViewController.o
#      (maybe you meant: _OBJC_CLASS_$_BaiduMobStatAppDelegate)
# ld: symbol(s) not found for architecture armv7
# clang: error: linker command failed with exit code 1 (use -v to see invocation)

在用到这个库的所有文件中都出现了错误, 如上 BaiduMobStatAppDelegate 类和 MyPageLogViewController类
这种情况就可能是这个静态库路径混乱导致的链接错误

解决方法:Build settings->Search Path->Library Search Paths  添加静态库的相应路径。如下图

如果上面的所有方法都不管用。你可以再试试一下几个方法:

1,看看是不是有新添加的文件跟之前文件同名

2,错误信息中出现了某个类的名字,去原文件中看看#import了哪些第三方库,把这些库挨个注释排除,找到出错的那个库,然后按照官方提供的步骤重新添加一遍。

Bmob云端代码快速入门

mikel阅读(1241)

注册Bmob帐号

在网址栏输入www.bmob.cn或者在百度输入Bmob进行搜索,打开Bmob官网后,点击右上角的“注册”,在跳转页面填入你的姓名、邮箱、设置密码,确认后到你的邮箱激活Bmob账户,你就可以用Bmob轻松开发应用了。

网站后台创建应用

登录账号进入bmob后台后,点击后台界面左上角“创建应用”,在弹出框输入你应用的名称,然后确认,你就拥有了一个等待开发的应用。

获取应用密钥和下载SDK

选择你要开发的应用,点击该应用下方对应的“应用密钥”

在跳转页面,获取Application ID,此ID将会在初始化SDK中使用到。

获取Application ID后,下载SDK,开发者可以根据自己的需求选择相应的iOS SDK 或Android SDK,点击下载即可。

创建云端代码

在Bmob后台中,选择你刚刚创建好的应用,然后依次点击“云端代码->添加”,在弹出窗口中输入云端代码的方法名,该方法名将会在SDK调用时使用到。如下图所示:

接着,你就可以在云端代码的编辑器中撰写云端代码了。如果你熟悉js脚本语言的话,撰写云端代码非常简单,你只需要在onRequest方法中补充 你的业务逻辑代码就可以了。onRequest方法包含3个参数,分别是request(请求对象,可以从中获取SDK上传的参数), response(回应对象,可以将云端代码的执行结果返回到SDK中), modules(可调用的模块,包含数据库对象、HTTP对象等)。为方便演示,这里简单实现一个功能:接收客户端上传上来的name参数,根据name 的值返回不同的结果。代码如下:

function onRequest(request, response, modules) {
  //获取SDK客户端上传的name参数
  var name = request.body.name;
    if(name == 'bmob')
      response.end('欢迎使用Bmob');
    else
      response.end('输入错误,请重新输入');
}

安装和初始化BmobSDK

云端代码的调用执行可以是在云端(通过“定时任务”模块去设置执行,实现定时业务逻辑计算的功能,如排行榜,这个操作非常简单,这里不再一一介 绍),但更多的开发者是通过SDK调用的方式来执行云端代码。这有点像存储过程,大家可以将更多的业务逻辑放在云端,可以随意改变,不需要更新应用,也不 需要上传太多的数据参数。

安装和初始化SDK的过程大家根据各自的平台(Android / iOS等)具体参考快速入门文档即可。

调用云端代码

将如下的代码根据各自平台,插入到触发执行的方法里面。

Android调用云端代码

//test对应你刚刚创建的云端代码名称
String cloudCodeName = "test";
JSONObject params = new JSONObject();
//name是上传到云端的参数名称,值是bmob,云端代码可以通过调用request.body.name获取这个值 
params.put("name", "bmob");
//创建云端代码对象
AsyncCustomEndpoints cloudCode = new AsyncCustomEndpoints();
//异步调用云端代码
cloudCode.callEndpoint(MainActivity.this, cloudCodeName, params, new CloudCodeListener() {

    //执行成功时调用,返回result对象
    @Override
    public void onSuccess(Object result) {
        Log.i("bmob", "result = "+result.toString());
    }

    //执行失败时调用
    @Override
    public void onFailure(String err) {
        Log.i("bmob", "BmobException = "+err);
    }
});

iOS调用云端代码

    //name是上传到云端的参数名称,值是bmob,云端代码可以通过调用request.body.name获取这个值 
    NSDictionary  *dic = [NSDictionary  dictionaryWithObject:@"bmob" forKey:@"name"];
    //test对应你刚刚创建的云端代码名称
    [BmobCloud callFunctionInBackground:@"test" withParameters:dic block:^(id object, NSError *error) {

    if (!error) {
         //执行成功时调用
        NSLog(@"error %@",[object description]);
    }else{
       //执行失败时调用
        NSLog(@"error %@",[error description]);
    }

    }] ;

源码下载

iOS源码下载

Android源码下载

写代码可能是成为软件工程师最容易的部分_IT新闻_博客园

mikel阅读(1173)

来源: 写代码可能是成为软件工程师最容易的部分_IT新闻_博客园

写代码可能是成为软件工程师最容易的部分

英文原文:Coding is probably the easiest part of being a software engineer

当然,写代码是超级重要的,但是我认为它只是整个过程中的一小部分,且不一定是最难学的。

学习如何写代码要花些时间,但是只要有足够的训练(每天写代码,坚持数年),你就能真正擅长它。

你知道的,我相信在某种程度上,每个软件开发人员几乎能给任何软件写代码。(当然有时候这要用更长的时间,但是你不再感到害怕,肯定能按照你的方式来运行。)

我和自己的同事都看到了这种现象。我今天的一部分工作是把项目分配给开发人员,我的团队有一些成员,常常能够适应任何项目。这些家伙就是我说的能够给任何软件写代码的人。

基本上,我不得不改变我过去用于衡量他们做为工程师的标准。他们已经都是非常优秀的程序员了。

不仅仅是要成为优秀的写代码的人

这些家伙都擅长让计算机做他们想做的事情。但是这个行业里任何有经验的人将要对你说,还有更多的能力。

其中较大的一部分,是你通过看书、然后经过一周训练还无法准备好的。像大部分其它工作一样,经验在软件工程职业里发挥着巨大作用,没有其它捷径可走。

我花了一些时间,尽量思考我在软件工程里最看重的所有方面(和写代码有关),下面是我想到的,不分顺序:

  • 编码的能力(当然,这是既定事实。)
  • 编写正确的程序的能力。
  • 使用正确的方式编码的能力。
  • 快速编码的能力。
  • 证明你的代码运行的能力。
  • 和其他人编码的能力。
  • 为其他人写代码的能力。(更多详情
  • 讨论你的代码的能力。
  • 为将来编码的能力。
  • 从你的代码学到经验的能力。

除了写代码的能力,列表中的其它方面对于靠软件谋生的任何人而言,都是相当重要的。而且,我敢肯定,所有这些对于优秀的职业生涯都是同等重要的。它们每一项都难以学习,不能速成,需要数年经验才能掌握。

(当然,写代码的能力就像把其它所有东西粘在一起的胶水。没有这种能力,一切无从谈起。)

不过,它是最容易的吗?

我给本文的标题为“写代码可能是成为软件工程师最容易的部分”,因为我深信,成为优秀的开发人员,比成为优秀的工程师要用更少的时间。

达到“优秀的开发人员”的状态,对于任何软件工程师而言,是一个不可逾越的阶段:首先你需要学习弹钢琴,然后你才能开始音乐创作。你具备了写代码的一流能力,才能打造你的软件工程师职业生涯。此后你拓展能力,开始增加和夯实越来越多的技能。

但是,所有一切能力的基础是掌握写代码的能力。

没有绝对

我认识一些杰出的开发人员,他们能够用 C++ 编译器做出牛逼的东西。我从来达不到这种境界。我认识的大部分优秀的软件工程师也将不可能达到这种境界。这些家伙是用他们的生命积累了海量的编程技能,十分不易。

我还认识一些优秀的软件工程师,他们从来不是好的开发人员。他们选择了一条不同的道路,才成为他们今天的样子,这条路适合他们。

对于我,以及我认识的大部分人来说,他们从写代码开始,并以此为基础。写代码是最容易的部分。其它部分要花时间,大量的时间。


译文: 《写代码可能是成为软件工程师最容易的部分 》 腊八粥