Coder Social home page Coder Social logo

Comments (9)

Doddddza avatar Doddddza commented on June 3, 2024 2

当前 master 的 SingletonFactory 代码是这样的:

public final class SingletonFactory {
    private static final Map<String, Object> OBJECT_MAP = new HashMap<>();

    private SingletonFactory() {
    }

    public static <T> T getInstance(Class<T> c) {
        String key = c.toString();
        Object instance;
        synchronized (SingletonFactory.class) {
            instance = OBJECT_MAP.get(key);
            if (instance == null) {
                try {
                    instance = c.getDeclaredConstructor().newInstance();
                    OBJECT_MAP.put(key, instance);
                } catch (IllegalAccessException | InstantiationException | NoSuchMethodException | InvocationTargetException e) {
                    throw new RuntimeException(e.getMessage(), e);
                }
            }
        }
        return c.cast(instance);
    }
}

我很疑惑为什么所有单例的对象需要共享同一把锁?他们之间也互不冲突。
其次,代码中似乎没有体现出 double check,目前 master 中代码的逻辑中,无论 OBJECT_MAP 中是否已经存在目标单例对象,都需要先与其他线程竞争锁,这一点是不是不太合理?
基于这些存在的问题, 是否改成下面的代码会更好?

public class SingletonFactory {
    private static final Map<String, Object> SINGLETON_MAP = new ConcurrentHashMap<>();
    private static final Map<Class<?>, Object> LOCK_MAP = new ConcurrentHashMap<>();

    private SingletonFactory() {
    }

    /**
     * Class must have no-arguments constructor.
     */
    public static <T> T getInstance(Class<T> clazz) {
        if (clazz == null) {
            throw new IllegalArgumentException();
        }
        String key = clazz.toString();
        Object instance = SINGLETON_MAP.get(key);
        if (instance == null) {
            synchronized (LOCK_MAP.computeIfAbsent(clazz, k -> new Object())) {
                instance = SINGLETON_MAP.get(key);
                if (instance == null) {
                    try {
                        instance = clazz.getDeclaredConstructor().newInstance();
                        SINGLETON_MAP.put(key, instance);
                    } catch (InstantiationException | InvocationTargetException | NoSuchMethodException
                            | IllegalAccessException e) {
                        throw new RuntimeException(e.getMessage(), e);
                    }
                }
            }
        }
        return clazz.cast(instance);
    }
}

通过 ConcurrentHashMap 也可以

    public static Object getInstance(Class<Object> c) {
        String key = c.toString();
        if (OBJECT_MAP.containsKey(key)) {
            return OBJECT_MAP.get(key);
        } else {
            return OBJECT_MAP.computeIfAbsent(key, k -> {
                try {
                    return c.getDeclaredConstructor().newInstance();
                } catch (InstantiationException | NoSuchMethodException | IllegalAccessException | InvocationTargetException e) {
                    throw new RuntimeException(e.getMessage(), e);
                }
            });
        }
    }

但是这样似乎会因为 ConcurrentHashMap 在内部 CAS instance 而导致 单例失去了意义?
我举个例子,有线程 A ,线程 B,线程 C, 线程 A 跟线程 B 在同一时刻进入了 computeIfAbsent,并且同时 CAS 他们各自 new 出来的 instance,接着其中有一个线程(假设是 A)就会 CAS 成功(并且在线程 B 替换 instance 引用的时候 结束了 getInstance 方法,返回了线程 A 自己 new 出来的 instance),另外一个就会在第二次设置值的时候,去替换掉这个值。
在这个背景为前提下,假设线程 C 在线程 A CAS 成功的时候,恰好进入了 if (OBJECT_MAP.containsKey(key)) 并且在线程 B 还没替换 instance 的时候, 线程 C 执行了 get 方法。 这样就会导致, 这个程序中这个单例工厂, 单例这个定义被破坏了,在这个时刻以后,线程 A、C 持有了线程 A new 出来的实例, 线程 B 则持有线程 B 自己 new 出来的实例。

说的可能有点绕,如果没理解我的意思的话,我会尝试表达的更清楚一些

另外,这个问题我说的很绕很难理解么....

我觉得,其实你这个问题在方法注释上已经写清楚了,computeIfAbsent 整个方法已经是原子的,同时如果有并发情况会阻碍别的 Function<? super K, ? extends V> mappingFunction 的计算

具体在注释里
image

同时
image

from guide-rpc-framework.

Snailclimb avatar Snailclimb commented on June 3, 2024

s

当前master的SingletonFactory代码是这样的:

public final class SingletonFactory {
    private static final Map<String, Object> OBJECT_MAP = new HashMap<>();

    private SingletonFactory() {
    }

    public static <T> T getInstance(Class<T> c) {
        String key = c.toString();
        Object instance;
        synchronized (SingletonFactory.class) {
            instance = OBJECT_MAP.get(key);
            if (instance == null) {
                try {
                    instance = c.getDeclaredConstructor().newInstance();
                    OBJECT_MAP.put(key, instance);
                } catch (IllegalAccessException | InstantiationException | NoSuchMethodException | InvocationTargetException e) {
                    throw new RuntimeException(e.getMessage(), e);
                }
            }
        }
        return c.cast(instance);
    }
}

我很疑惑为什么所有单例的对象需要共享同一把锁?他们之间也互不冲突。

其次,代码中似乎没有体现出double check,目前master中代码的逻辑中,无论OBJECT_MAP中是否已经存在目标单例对象,都需要先与其他线程竞争锁,这一点是不是不太合理?

基于这些存在的问题, 是否改成下面的代码会更好?

public class SingletonFactory {
    private static final Map<String, Object> SINGLETON_MAP = new ConcurrentHashMap<>();
    private static final Map<Class<?>, Object> LOCK_MAP = new ConcurrentHashMap<>();

    private SingletonFactory() {
    }

    /**
     * Class must have no-arguments constructor.
     */
    public static <T> T getInstance(Class<T> clazz) {
        if (clazz == null) {
            throw new IllegalArgumentException();
        }
        String key = clazz.toString();
        Object instance = SINGLETON_MAP.get(key);
        if (instance == null) {
            synchronized (LOCK_MAP.computeIfAbsent(clazz, k -> new Object())) {
                instance = SINGLETON_MAP.get(key);
                if (instance == null) {
                    try {
                        instance = clazz.getDeclaredConstructor().newInstance();
                        SINGLETON_MAP.put(key, instance);
                    } catch (InstantiationException | InvocationTargetException | NoSuchMethodException
                            | IllegalAccessException e) {
                        throw new RuntimeException(e.getMessage(), e);
                    }
                }
            }
        }
        return clazz.cast(instance);
    }
}

是的,这种性能要好一点。

from guide-rpc-framework.

ChoKhoOu avatar ChoKhoOu commented on June 3, 2024

s

当前master的SingletonFactory代码是这样的:

public final class SingletonFactory {
    private static final Map<String, Object> OBJECT_MAP = new HashMap<>();

    private SingletonFactory() {
    }

    public static <T> T getInstance(Class<T> c) {
        String key = c.toString();
        Object instance;
        synchronized (SingletonFactory.class) {
            instance = OBJECT_MAP.get(key);
            if (instance == null) {
                try {
                    instance = c.getDeclaredConstructor().newInstance();
                    OBJECT_MAP.put(key, instance);
                } catch (IllegalAccessException | InstantiationException | NoSuchMethodException | InvocationTargetException e) {
                    throw new RuntimeException(e.getMessage(), e);
                }
            }
        }
        return c.cast(instance);
    }
}

我很疑惑为什么所有单例的对象需要共享同一把锁?他们之间也互不冲突。
其次,代码中似乎没有体现出double check,目前master中代码的逻辑中,无论OBJECT_MAP中是否已经存在目标单例对象,都需要先与其他线程竞争锁,这一点是不是不太合理?
基于这些存在的问题, 是否改成下面的代码会更好?

public class SingletonFactory {
    private static final Map<String, Object> SINGLETON_MAP = new ConcurrentHashMap<>();
    private static final Map<Class<?>, Object> LOCK_MAP = new ConcurrentHashMap<>();

    private SingletonFactory() {
    }

    /**
     * Class must have no-arguments constructor.
     */
    public static <T> T getInstance(Class<T> clazz) {
        if (clazz == null) {
            throw new IllegalArgumentException();
        }
        String key = clazz.toString();
        Object instance = SINGLETON_MAP.get(key);
        if (instance == null) {
            synchronized (LOCK_MAP.computeIfAbsent(clazz, k -> new Object())) {
                instance = SINGLETON_MAP.get(key);
                if (instance == null) {
                    try {
                        instance = clazz.getDeclaredConstructor().newInstance();
                        SINGLETON_MAP.put(key, instance);
                    } catch (InstantiationException | InvocationTargetException | NoSuchMethodException
                            | IllegalAccessException e) {
                        throw new RuntimeException(e.getMessage(), e);
                    }
                }
            }
        }
        return clazz.cast(instance);
    }
}

是的,这种性能要好一点。

好的,已PR

from guide-rpc-framework.

Snailclimb avatar Snailclimb commented on June 3, 2024

当前master的SingletonFactory代码是这样的:

public final class SingletonFactory {
    private static final Map<String, Object> OBJECT_MAP = new HashMap<>();

    private SingletonFactory() {
    }

    public static <T> T getInstance(Class<T> c) {
        String key = c.toString();
        Object instance;
        synchronized (SingletonFactory.class) {
            instance = OBJECT_MAP.get(key);
            if (instance == null) {
                try {
                    instance = c.getDeclaredConstructor().newInstance();
                    OBJECT_MAP.put(key, instance);
                } catch (IllegalAccessException | InstantiationException | NoSuchMethodException | InvocationTargetException e) {
                    throw new RuntimeException(e.getMessage(), e);
                }
            }
        }
        return c.cast(instance);
    }
}

我很疑惑为什么所有单例的对象需要共享同一把锁?他们之间也互不冲突。

其次,代码中似乎没有体现出double check,目前master中代码的逻辑中,无论OBJECT_MAP中是否已经存在目标单例对象,都需要先与其他线程竞争锁,这一点是不是不太合理?

基于这些存在的问题, 是否改成下面的代码会更好?

public class SingletonFactory {
    private static final Map<String, Object> SINGLETON_MAP = new ConcurrentHashMap<>();
    private static final Map<Class<?>, Object> LOCK_MAP = new ConcurrentHashMap<>();

    private SingletonFactory() {
    }

    /**
     * Class must have no-arguments constructor.
     */
    public static <T> T getInstance(Class<T> clazz) {
        if (clazz == null) {
            throw new IllegalArgumentException();
        }
        String key = clazz.toString();
        Object instance = SINGLETON_MAP.get(key);
        if (instance == null) {
            synchronized (LOCK_MAP.computeIfAbsent(clazz, k -> new Object())) {
                instance = SINGLETON_MAP.get(key);
                if (instance == null) {
                    try {
                        instance = clazz.getDeclaredConstructor().newInstance();
                        SINGLETON_MAP.put(key, instance);
                    } catch (InstantiationException | InvocationTargetException | NoSuchMethodException
                            | IllegalAccessException e) {
                        throw new RuntimeException(e.getMessage(), e);
                    }
                }
            }
        }
        return clazz.cast(instance);
    }
}

通过 ConcurrentHashMap 也可以

    public static Object getInstance(Class<Object> c) {
        String key = c.toString();
        if (OBJECT_MAP.containsKey(key)) {
            return OBJECT_MAP.get(key);
        } else {
            return OBJECT_MAP.computeIfAbsent(key, k -> {
                try {
                    return c.getDeclaredConstructor().newInstance();
                } catch (InstantiationException | NoSuchMethodException | IllegalAccessException | InvocationTargetException e) {
                    throw new RuntimeException(e.getMessage(), e);
                }
            });
        }
    }

from guide-rpc-framework.

ChoKhoOu avatar ChoKhoOu commented on June 3, 2024

当前master的SingletonFactory代码是这样的:

public final class SingletonFactory {
    private static final Map<String, Object> OBJECT_MAP = new HashMap<>();

    private SingletonFactory() {
    }

    public static <T> T getInstance(Class<T> c) {
        String key = c.toString();
        Object instance;
        synchronized (SingletonFactory.class) {
            instance = OBJECT_MAP.get(key);
            if (instance == null) {
                try {
                    instance = c.getDeclaredConstructor().newInstance();
                    OBJECT_MAP.put(key, instance);
                } catch (IllegalAccessException | InstantiationException | NoSuchMethodException | InvocationTargetException e) {
                    throw new RuntimeException(e.getMessage(), e);
                }
            }
        }
        return c.cast(instance);
    }
}

我很疑惑为什么所有单例的对象需要共享同一把锁?他们之间也互不冲突。
其次,代码中似乎没有体现出double check,目前master中代码的逻辑中,无论OBJECT_MAP中是否已经存在目标单例对象,都需要先与其他线程竞争锁,这一点是不是不太合理?
基于这些存在的问题, 是否改成下面的代码会更好?

public class SingletonFactory {
    private static final Map<String, Object> SINGLETON_MAP = new ConcurrentHashMap<>();
    private static final Map<Class<?>, Object> LOCK_MAP = new ConcurrentHashMap<>();

    private SingletonFactory() {
    }

    /**
     * Class must have no-arguments constructor.
     */
    public static <T> T getInstance(Class<T> clazz) {
        if (clazz == null) {
            throw new IllegalArgumentException();
        }
        String key = clazz.toString();
        Object instance = SINGLETON_MAP.get(key);
        if (instance == null) {
            synchronized (LOCK_MAP.computeIfAbsent(clazz, k -> new Object())) {
                instance = SINGLETON_MAP.get(key);
                if (instance == null) {
                    try {
                        instance = clazz.getDeclaredConstructor().newInstance();
                        SINGLETON_MAP.put(key, instance);
                    } catch (InstantiationException | InvocationTargetException | NoSuchMethodException
                            | IllegalAccessException e) {
                        throw new RuntimeException(e.getMessage(), e);
                    }
                }
            }
        }
        return clazz.cast(instance);
    }
}

通过 ConcurrentHashMap 也可以

    public static Object getInstance(Class<Object> c) {
        String key = c.toString();
        if (OBJECT_MAP.containsKey(key)) {
            return OBJECT_MAP.get(key);
        } else {
            return OBJECT_MAP.computeIfAbsent(key, k -> {
                try {
                    return c.getDeclaredConstructor().newInstance();
                } catch (InstantiationException | NoSuchMethodException | IllegalAccessException | InvocationTargetException e) {
                    throw new RuntimeException(e.getMessage(), e);
                }
            });
        }
    }

但是这样似乎会因为ConcurrentHashMap 在内部CAS instance而导致 单例失去了意义?

我举个例子,有线程A ,线程B,线程C, 线程A跟线程B在同一时刻进入了computeIfAbsent,并且同时CAS 他们各自new出来的instance,接着其中有一个线程(假设是A)就会CAS成功(并且在线程B替换instance引用的时候 结束了getInstance方法,返回了线程A自己new 出来的instance),另外一个就会在第二次设置值的时候,去替换掉这个值。

在这个背景为前提下,假设线程C在线程A CAS成功的时候,恰好进入了if (OBJECT_MAP.containsKey(key)) 并且在线程B还没替换instance的时候, 线程C执行了get方法。 这样就会导致, 这个程序中这个单例工厂, 单例这个定义被破坏了,在这个时刻以后,线程A、C持有了线程A new 出来的实例, 线程B则持有线程B 自己new 出来的实例。

from guide-rpc-framework.

ChoKhoOu avatar ChoKhoOu commented on June 3, 2024

当前master的SingletonFactory代码是这样的:

public final class SingletonFactory {
    private static final Map<String, Object> OBJECT_MAP = new HashMap<>();

    private SingletonFactory() {
    }

    public static <T> T getInstance(Class<T> c) {
        String key = c.toString();
        Object instance;
        synchronized (SingletonFactory.class) {
            instance = OBJECT_MAP.get(key);
            if (instance == null) {
                try {
                    instance = c.getDeclaredConstructor().newInstance();
                    OBJECT_MAP.put(key, instance);
                } catch (IllegalAccessException | InstantiationException | NoSuchMethodException | InvocationTargetException e) {
                    throw new RuntimeException(e.getMessage(), e);
                }
            }
        }
        return c.cast(instance);
    }
}

我很疑惑为什么所有单例的对象需要共享同一把锁?他们之间也互不冲突。
其次,代码中似乎没有体现出double check,目前master中代码的逻辑中,无论OBJECT_MAP中是否已经存在目标单例对象,都需要先与其他线程竞争锁,这一点是不是不太合理?
基于这些存在的问题, 是否改成下面的代码会更好?

public class SingletonFactory {
    private static final Map<String, Object> SINGLETON_MAP = new ConcurrentHashMap<>();
    private static final Map<Class<?>, Object> LOCK_MAP = new ConcurrentHashMap<>();

    private SingletonFactory() {
    }

    /**
     * Class must have no-arguments constructor.
     */
    public static <T> T getInstance(Class<T> clazz) {
        if (clazz == null) {
            throw new IllegalArgumentException();
        }
        String key = clazz.toString();
        Object instance = SINGLETON_MAP.get(key);
        if (instance == null) {
            synchronized (LOCK_MAP.computeIfAbsent(clazz, k -> new Object())) {
                instance = SINGLETON_MAP.get(key);
                if (instance == null) {
                    try {
                        instance = clazz.getDeclaredConstructor().newInstance();
                        SINGLETON_MAP.put(key, instance);
                    } catch (InstantiationException | InvocationTargetException | NoSuchMethodException
                            | IllegalAccessException e) {
                        throw new RuntimeException(e.getMessage(), e);
                    }
                }
            }
        }
        return clazz.cast(instance);
    }
}

通过 ConcurrentHashMap 也可以

    public static Object getInstance(Class<Object> c) {
        String key = c.toString();
        if (OBJECT_MAP.containsKey(key)) {
            return OBJECT_MAP.get(key);
        } else {
            return OBJECT_MAP.computeIfAbsent(key, k -> {
                try {
                    return c.getDeclaredConstructor().newInstance();
                } catch (InstantiationException | NoSuchMethodException | IllegalAccessException | InvocationTargetException e) {
                    throw new RuntimeException(e.getMessage(), e);
                }
            });
        }
    }

但是这样似乎会因为ConcurrentHashMap 在内部CAS instance而导致 单例失去了意义?

我举个例子,有线程A ,线程B,线程C, 线程A跟线程B在同一时刻进入了computeIfAbsent,并且同时CAS 他们各自new出来的instance,接着其中有一个线程(假设是A)就会CAS成功(并且在线程B替换instance引用的时候 结束了getInstance方法,返回了线程A自己new 出来的instance),另外一个就会在第二次设置值的时候,去替换掉这个值。

在这个背景为前提下,假设线程C在线程A CAS成功的时候,恰好进入了if (OBJECT_MAP.containsKey(key)) 并且在线程B还没替换instance的时候, 线程C执行了get方法。 这样就会导致, 这个程序中这个单例工厂, 单例这个定义被破坏了,在这个时刻以后,线程A、C持有了线程A new 出来的实例, 线程B则持有线程B 自己new 出来的实例。

说的可能有点绕,如果没理解我的意思的话,我会尝试表达的更清楚一些

from guide-rpc-framework.

Doddddza avatar Doddddza commented on June 3, 2024

emmm,其实我有个疑问,为什么要用单例工厂?
如果要用单例模式,为什么不用单元素枚举类,或者私有构造函数然后提供常量呢

from guide-rpc-framework.

ChoKhoOu avatar ChoKhoOu commented on June 3, 2024

emmm,其实我有个疑问,为什么要用单例工厂?
如果要用单例模式,为什么不用单元素枚举类,或者私有构造函数然后提供常量呢

但这项目里面这么多地方依赖单例工厂,如果全改成用单元素枚举,得整多少个枚举类啊。
私有构造函数提供常量的话,我个人觉得还不如一个单例工厂方便管理?

from guide-rpc-framework.

ChoKhoOu avatar ChoKhoOu commented on June 3, 2024

当前master的SingletonFactory代码是这样的:

public final class SingletonFactory {
    private static final Map<String, Object> OBJECT_MAP = new HashMap<>();

    private SingletonFactory() {
    }

    public static <T> T getInstance(Class<T> c) {
        String key = c.toString();
        Object instance;
        synchronized (SingletonFactory.class) {
            instance = OBJECT_MAP.get(key);
            if (instance == null) {
                try {
                    instance = c.getDeclaredConstructor().newInstance();
                    OBJECT_MAP.put(key, instance);
                } catch (IllegalAccessException | InstantiationException | NoSuchMethodException | InvocationTargetException e) {
                    throw new RuntimeException(e.getMessage(), e);
                }
            }
        }
        return c.cast(instance);
    }
}

我很疑惑为什么所有单例的对象需要共享同一把锁?他们之间也互不冲突。
其次,代码中似乎没有体现出double check,目前master中代码的逻辑中,无论OBJECT_MAP中是否已经存在目标单例对象,都需要先与其他线程竞争锁,这一点是不是不太合理?
基于这些存在的问题, 是否改成下面的代码会更好?

public class SingletonFactory {
    private static final Map<String, Object> SINGLETON_MAP = new ConcurrentHashMap<>();
    private static final Map<Class<?>, Object> LOCK_MAP = new ConcurrentHashMap<>();

    private SingletonFactory() {
    }

    /**
     * Class must have no-arguments constructor.
     */
    public static <T> T getInstance(Class<T> clazz) {
        if (clazz == null) {
            throw new IllegalArgumentException();
        }
        String key = clazz.toString();
        Object instance = SINGLETON_MAP.get(key);
        if (instance == null) {
            synchronized (LOCK_MAP.computeIfAbsent(clazz, k -> new Object())) {
                instance = SINGLETON_MAP.get(key);
                if (instance == null) {
                    try {
                        instance = clazz.getDeclaredConstructor().newInstance();
                        SINGLETON_MAP.put(key, instance);
                    } catch (InstantiationException | InvocationTargetException | NoSuchMethodException
                            | IllegalAccessException e) {
                        throw new RuntimeException(e.getMessage(), e);
                    }
                }
            }
        }
        return clazz.cast(instance);
    }
}

通过 ConcurrentHashMap 也可以

    public static Object getInstance(Class<Object> c) {
        String key = c.toString();
        if (OBJECT_MAP.containsKey(key)) {
            return OBJECT_MAP.get(key);
        } else {
            return OBJECT_MAP.computeIfAbsent(key, k -> {
                try {
                    return c.getDeclaredConstructor().newInstance();
                } catch (InstantiationException | NoSuchMethodException | IllegalAccessException | InvocationTargetException e) {
                    throw new RuntimeException(e.getMessage(), e);
                }
            });
        }
    }

但是这样似乎会因为ConcurrentHashMap 在内部CAS instance而导致 单例失去了意义?
我举个例子,有线程A ,线程B,线程C, 线程A跟线程B在同一时刻进入了computeIfAbsent,并且同时CAS 他们各自new出来的instance,接着其中有一个线程(假设是A)就会CAS成功(并且在线程B替换instance引用的时候 结束了getInstance方法,返回了线程A自己new 出来的instance),另外一个就会在第二次设置值的时候,去替换掉这个值。
在这个背景为前提下,假设线程C在线程A CAS成功的时候,恰好进入了if (OBJECT_MAP.containsKey(key)) 并且在线程B还没替换instance的时候, 线程C执行了get方法。 这样就会导致, 这个程序中这个单例工厂, 单例这个定义被破坏了,在这个时刻以后,线程A、C持有了线程A new 出来的实例, 线程B则持有线程B 自己new 出来的实例。

说的可能有点绕,如果没理解我的意思的话,我会尝试表达的更清楚一些

另外,这个问题我说的很绕很难理解么....

from guide-rpc-framework.

Related Issues (20)

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.