Обновить
512K+

Java *

Объектно-ориентированный язык программирования

238,24
Рейтинг
Сначала показывать
Порог рейтинга
Уровень сложности

Java Multicore Programming: Lecture #1

Время на прочтение2 мин
Охват и читатели17K
Добрый день.
15 мая была проведен первый вебинар (из 16) курса «Multicore programming in Java». Тут я бы хотел опубликовать материалы, упоминавшиеся на лекции: ссылки на источники, термины, картинки, задание. Возможно кто-то сочтет их полезными для себя.

Также я веду курс «Scala for Java Developers» на платформе для онлайн-образования udemy.com (аналог Coursera/EdX).

Введение




“Железо”


Стоит «посмотреть картинки» в следующих источниках

Читать дальше →

Дорог ли native метод? «Секретное» расширение JNI

Время на прочтение5 мин
Охват и читатели33K

Для чего Java-программисты прибегают к native методам? Иногда, чтобы воспользоваться сторонней DLL библиотекой. В других случаях, чтобы ускорить критичный алгоритм за счет оптимизированного кода на C или ассемблере. Например, для обработки потокового медиа, для сжатия, шифрования и т.п.

Но вызов native метода не бесплатен. Порой, накладные расходы на JNI оказываются даже больше, чем выигрыш в производительности. А всё потому, что они включают в себя:
  1. создание stack frame;
  2. перекладывание аргументов в соответствии с ABI;
  3. оборачивание ссылок в JNI хендлы (jobject);
  4. передачу дополнительных аргументов JNIEnv* и jclass;
  5. захват и освобождение монитора, если метод synchronized;
  6. «ленивую» линковку нативной функции;
  7. трассировку входа и выхода из метода;
  8. перевод потока из состояния in_Java в in_native и обратно;
  9. проверку необходимости safepoint;
  10. обработку возможных исключений.

Но зачастую native методы просты: они не бросают исключений, не создают новые объекты в хипе, не обходят стек, не работают с хендлами и не синхронизованы. Можно ли для них не делать лишних действий?

Да, и сегодня я расскажу о недокументированных возможностях HotSpot JVM для ускоренного вызова простых JNI методов. Хотя эта оптимизация появилась еще с первых версий Java 7, что удивительно, о ней еще никто нигде не писал.
Читать дальше →

Consulo + .NET плагин, спустя два месяца

Время на прочтение2 мин
Охват и читатели6.4K
После моей первой публикации прошло два месяца. После него я немного сменил приоритет на одну задачу. А именно — реализацию дебаггера, хотя бы для Mono .NET.
Читать дальше →

Программирование-по-Контракту в Java

Время на прочтение31 мин
Охват и читатели56K
Добрый день.
В рамках детальной проработки курса удаленного образования «Java Core» я пишу серию публикаций и делаю несколько переводов наиболее популярных статей.

Также я веду курс «Scala for Java Developers» на платформе для онлайн-образования udemy.com (аналог Coursera/EdX).

Сейчас я предлагаю Вам на рассмотрение мой перевод «Programming With Assertions» с некоторыми комментариями.

Оригинальная публикация не только детально объясняет варианты использования ключевого слова assert в Java и то, как реализована поддержка данного механизма на уровне загрузки классов, но также является достаточно неформальным введением в Разработку-по-Контракту (Design-by-Contract).




P.S. Автор признает, что для него лично русский язык намного сложнее языка Java, с благодарностью выслушает в личку о всех замеченных ошибках и постарается их в кратчайшие сроки исправить.



Программирование с утверждениями (oracle.com: Programming With Assertions)

Утверждение (assert) — это оператор (statement) языка программирования Java, который позволяет вам проверить свои предположения о программе. Например, если вы пишете метод, вычисляющий скорость частицы, можно «утверждать», что расчетная скорость меньше скорости света.

Каждое утверждение содержит логическое выражение, которое, по вашему мнению, будет верным в момент выполнения. В противном случае, система выбросит исключение. Проверяя, что логическое выражение на самом деле верно, утверждение (assert) подтверждает ваши предположения (ожидания) о поведении программы, увеличивая уверенность в том, что программа не содержит ошибок.
Читать дальше →

Результаты и обсуждение майского хабрасоревнования: делаем свой ГЛОНАСС

Время на прочтение16 мин
Охват и читатели14K
Итак, настало время подвести итоги прошедшего майского хабрасоревнования. Было прислано 49 решений, удовлетворяющих требованиям по оформлению и 8 решений вне конкурса (позже дедлайна, с ошибками оформления, на неверный адрес). Что-ж, посмотрим, кто что написал.

Хотя в обсуждении топика с самой задачей люди переживали, что самое компактное и самое быстрое решение — это разные вещи, оказалось что решение победителя lany — является и самым компактным, удовлетворяющим всем требованиям. Решение Frommi было вдвое компактнее, 863 байта — но не смогло пройти все тесты. Следующим шло решение ibessonov на 1613 байта — но оно внезапно показало большую ошибку на первом тесте.

Если у меня читатели не найдут ошибки, тройка победителей будет выглядеть так:

  1. lany — двойной победитель, 89.9448 баллов и самое компактное решение.
    Самый большой тест (2.4Гб) пройден за 0.61 секунду.
    Смотреть исходник
    //@lany
    public class G{java.io.InputStream I=System.in;int c,i=0,j,m,M;double[]S=new double[512],C=new double[512];byte[]P="111001100011101101".getBytes(),d=new byte[999999];double N=4.0678884e13,L=29.9792458,X,Y,q,F,G,H=1e99;S[]z;S f,g;class S{double x,y,r,q,R,Q;S(){x=new Double(l());y=new Double(l());try{I.read(d);I.skip(9000001);}catch(Exception e){}q=L*o()+L/2;Q=q*q;r=q-L;R=r*r;l();}int o(){int o=0,p;for(;;o+=10){for(p=0;p<18;p++)if(P[p]!=d[o+p*10])break;if(p==18){while(d[--o]>48);return o+1;}}}}void u(double X,double Y){if(X*X+Y*Y<N){double S=d(X,Y);if(S<H){H=S;F=X;G=Y;}}}double d(double x,double y){double q=0,Q=-1,X,Y;for(S s:z){X=x-s.x;Y=y-s.y;X=X*X+Y*Y;if(X>s.Q)q+=X-s.Q;else if(X<s.R)q+=s.R-X;else if(q==0){Y=Math.sqrt(X);Q*=Math.min(s.q-Y,Y-s.r)*.1;}}return q>0?q:Q;}void b(double r,double R){if(r+R>q){double d=Math.abs(r*r-R*R+q*q)/2/q,h=Math.sqrt(r*r-d*d),x=f.x+X*d,y=f.y+Y*d;u(x-Y*h,y+X*h);u(x+Y*h,y-X*h);}}String l(){char[]o=new char[99];int p=0,b;try{while((b=I.read())!=10)o[p++]=(char)b;}catch(Exception e){}return new String(o,0,p).trim();}public static void main(String[]a){new G();}G(){for(;i<512;i++){q=Math.PI*i/256;S[i]=Math.sin(q);C[i]=Math.cos(q);}c=new Short(l());z=new S[c];for(i=0;i<c;)z[i++]=new S();for(i=1;i<c&&H>0;i++)for(j=0;j<i&&H>0;j++){f=z[i];g=z[j];X=g.x-f.x;Y=g.y-f.y;q=Math.sqrt(X*X+Y*Y);X/=q;Y/=q;b(f.q,g.q);b(f.r,g.q);b(f.q,g.r);b(f.r,g.r);}double x=F,y=G,r=d(x,y),t=r<1e10?1e3:3e6,u,v,w,R;while(t>.1&&(i++<999||r>0)){R=r;X=x;Y=y;for(M=4;M<513&&R==r;M*=2){for(m=0;m<M;m++)if(M<5||m%2>0){j=m*512/M;u=x+S[j]*t;v=y+C[j]*t;if(u*u+v*v<N){w=d(u,v);if(w<R){X=u;Y=v;R=w;}}}}if(R<r){x=X;y=Y;r=R;}else t/=2;}System.out.println(x+" "+y);}}
  2. @AKashta — 86.9558 балла, на самом большом тесте вдвое быстрое lany, но немного проиграл по точности.
    Смотреть исходник
    //@AKashta
    
    import java.io.*;
    import java.util.ArrayList;
    
    public class Main {
    
        public static final boolean ADVANCED_MODE = true;
        public static final int MAX_POINTS = 50;
        public static final double PRECISION = 30;
        public static final int THRESHOLD = 300;
    
        public static final String START_TOKEN = "111001100011101101";
        public static final long DATA_LENGTH = 10000000;
        public static final long SPEED = 299792458;
        public static final long EARTH_R = 6378000;
        public static final long MIN_SAT_POS = 10000000;
        public static final long MAX_SAT_POS = 20000000;
        public static final int MIN_OFFSET = (int)((MIN_SAT_POS - EARTH_R) * DATA_LENGTH / SPEED);
        public static final int MAX_OFFSET = (int)((MAX_SAT_POS + EARTH_R) * DATA_LENGTH / SPEED);
    
        public static void main(String args[ ]) {
            //long startTime = System.currentTimeMillis();
            try {
                DataInputStream in = new DataInputStream(System.in);
                DataReader reader = new DataReader(in);
                Point result = null;
    
                int q = reader.readInt();
                ArrayList<Circle> sats = new ArrayList<Circle>(q);
                for(int i = 0; i < Math.min(q, MAX_POINTS); i++) {
                    double x = reader.readDouble();
                    double y = reader.readDouble();
                    int offset = reader.readOffset();
    
                    double radius = ((double)SPEED / DATA_LENGTH * offset);
    
                    sats.add(new Circle(new Point(x, y),  radius));
                }
    
                if(sats.size() == 2) {
                    ArrayList<Point> points = sats.get(0).intersect(sats.get(1));
                    for(Point p : points) {
                        result = p;
                        break;
                    }
                }  else {
                    if(ADVANCED_MODE) {
                        result = advancedCalc(sats);
                    } else {
                        result = simpleCalc(sats);
                    }
                }
    
                System.out.println(result.x + " " + result.y);
                //long time = (System.currentTimeMillis() - startTime);
                //System.out.println("Time: " + time);
            } catch (Exception e) {
                System.out.println(e.getMessage());
            }
        }
    
        public static Point findRefPoint(ArrayList<Circle> sats){
            ArrayList<Point> points = new ArrayList<Point>();
            for(int i = 0; i < 2; i++) {
                for(int j = i + 1; j < 3; j++) {
                    points.addAll(sats.get(i).intersect(sats.get(j)));
                }
            }
    
            Point p0 = null, p1 = null, p2 = null;
            for(Point p : points) {
                for(Point t : points) {
                    if(p1 == null && t != p && p.distance(t) < THRESHOLD){
                        p1 = t;
                        continue;
                    }
                    if(p1 != null && t != p && t != p1 && p.distance(t) < THRESHOLD){
                        p2 = t;
                        break;
                    }
                }
                if(p1 != null && p2 != null) {
                    p0 = p;
                    break;
                } else {
                    p1 = null;
                    p2 = null;
                }
            }
            return new Point((p0.x + p1.x + p2.x) / 3, (p0.y + p1.y + p2.y) / 3);
        }
    
        public static Point advancedCalc(ArrayList<Circle> sats){
            ArrayList<Point> allPoints = new ArrayList<Point>();
            for(int i = 0; i < sats.size() - 1; i++) {
                for(int j = i + 1; j < sats.size(); j++) {
                    allPoints.addAll(sats.get(i).intersect(sats.get(j)));
                }
            }
    
            int count = 0;
            double sumX = 0;
            double sumY = 0;
    
            for(Point p : allPoints) {
                boolean containsInAll = true;
                for (Circle sat : sats){
                    if(!sat.hasPoint(p)) {
                        containsInAll = false;
                        break;
                    }
                }
                if(containsInAll) {
                    count++;
                    sumX += p.x;
                    sumY += p.y;
                }
            }
            return new Point(sumX / count, sumY / count);
        }
    
        public static Point simpleCalc(ArrayList<Circle> sats){
            int count = 0;
            double sumX = 0;
            double sumY = 0;
    
            Point refPoint = findRefPoint(sats);
            for(int i = 0; i < sats.size() - 1; i++) {
                for(int j = i + 1; j < sats.size(); j++) {
                    for(Point p : sats.get(i).intersect(sats.get(j))) {
                        if(refPoint.distance(p) < THRESHOLD) {
                            count++;
                            sumX += p.x;
                            sumY += p.y;
                        }
                    }
                }
            }
            return new Point(sumX / count, sumY / count);
        }
    
        public static class DataReader {
            private DataInputStream _in;
    
            public DataReader(DataInputStream in){
                _in = in;
            }
    
            public int readOffset() throws Exception {
                byte firstByte = _in.readByte();
                int offset = 1;
                while( _in.readByte() == firstByte) {
                    offset++;
                }
                int needToSkip = ((MIN_OFFSET - offset) / 10) * 10;
                _in.skipBytes(needToSkip);
                offset += needToSkip;
    
                byte[] buffer = new byte[MAX_OFFSET - offset];
                _in.read(buffer);
                _in.skipBytes((int) DATA_LENGTH - offset - buffer.length - 1 + 2);
    
                StringBuilder sb = new StringBuilder(buffer.length / 10);
                for(int i = 0; i < buffer.length / 10; i++ ){
                    sb.append((char) buffer[i * 10]);
                }
    
                int index = sb.indexOf(START_TOKEN)* 10;
    
                return index + offset;
            }
    
            public String readLine() throws Exception {
                StringBuilder sb = new StringBuilder();
                char c;
                while((c = (char)_in.readByte()) != '\r') {
                    sb.append(c);
                }
                _in.readByte(); // read '\n' char
                return  sb.toString();
            }
    
            public int readInt() throws Exception {
                String s = readLine();
                return Integer.parseInt(s);
            }
    
            public Double readDouble() throws Exception {
                String s = readLine();
                return Double.parseDouble(s);
            }
        }
    
        public static class Point {
            public double x;
            public double y;
    
            public Point(double x, double y) {
                this.x = x;
                this.y = y;
            }
    
            public double distance() {
                return Math.sqrt(x*x + y*y);
            }
    
            public double distance(Point p) {
                return Math.sqrt(Math.pow(x - p.x, 2) + Math.pow(y - p.y, 2));
            }
        }
    
        public static class Circle {
            public Point center;
            public double radius;
            public Circle(Point p, double r) {
                center = p;
                radius = r;
            }
    
            public ArrayList<Point> intersect(Circle c) {
                ArrayList<Point> result = new ArrayList<Point>();
    
                double dx = c.center.x - center.x;
                double dy = c.center.y - center.y;
                double d = Math.sqrt((dy * dy) + (dx * dx));
    
                if(d < Math.abs(radius - c.radius)) {
                    if(radius < c.radius)
                        radius += Math.abs(radius - c.radius) - d + 0.1;
                    else
                        c.radius += Math.abs(radius - c.radius) - d + 0.1;
                }
                if (d > (radius + c.radius)) {
                    double add = (d - (radius + c.radius))/ 2.0 + 0.1;
                    radius += add;
                    c.radius += add;
                }
    
                if (d > (radius + c.radius) || d < Math.abs(radius - c.radius)) {
                    //System.out.println("do not intersect");
                    return result;
                }
    
                double a = ((radius * radius) - (c.radius * c.radius) + ( d *d)) / (2.0 * d);
    
                Point p2 = new Point(center.x + (dx * a/d), center.y + (dy * a/d));
    
                double h = Math.sqrt((radius * radius) - (a*a));
                double rx = -dy * (h/d);
                double ry = dx * (h/d);
    
                Point p = new Point(p2.x + rx, p2.y + ry);
                if(p.distance() <= EARTH_R) {
                    result.add(p);
                }
                p = new Point(p2.x - rx, p2.y - ry);
                if(p.distance() <= EARTH_R) {
                    result.add(p);
                }
    
                return result;
            }
    
            public boolean hasPoint(Point p) {
                double d = center.distance(p);
                return Math.abs(d - radius) <= PRECISION;
            }
        }
    }
  3. @habrunit — 83.9379 балла, буквально вырвал призовое место из рук Staker.
    Смотреть исходник
    //@habrunit
    //package olimp;
    
    import java.io.FileInputStream;
    import java.io.FileNotFoundException;
    import java.io.IOException;
    import java.io.InputStream;
    import java.io.UnsupportedEncodingException;
    import java.security.NoSuchAlgorithmException;
    import static java.lang.Math.*;
    
    public class Olimp {
    	private static int cash[]={0xc0001200,0x10818201,0x51feba02,0x1483a003,0xb6ffc304,0x8d953105,0x1b2e7e06,0x780a707,0x59041a08,0x283b1c09,0x5818430a,0xc13b950b,0x3921ed0c,0x599b60d,0x99c8400e,0x2612640f,0xb7b0ca10,0x8c17d11,0xd35fda12,0x96863f13,0xca7ea414,0x90875415,0xc860e416,0x6239c317,0x9f39d418,0xccc48419,0x3f43d11a,0x9e366d1b,0x37fc9a1c,0x103bd91d,0xe96c501e,0x80ccf81f,0x602aca20,0xed28b721,0xcedf2d22,0xd2da9e23,0x93574024,0xebba4125,0x77fcc26,0xf8eb1a27,0xc6e09728,0x58dfe129,0xc776642a,0x6688342b,0x102a252c,0xedec802d,0xdf737f2e,0x4b5b402f,0x9c29fb30,0x93300a31,0xc30d2b32,0xabe73633,0x61f4fa34,0xf4334c35,0xd27b8a36,0xf7b63e37,0x602d9038,0x2e8aff39,0x4e62003a,0xc489143b,0x4e5ed53c,0x57a46f3d,0xf6630b3e,0xb392f53f,0xba827340,0x5b9b7e41,0x3e9d1f42,0x29b2c743,0x47f8644,0xe4d74745,0xf1263046,0x3d44e47,0xb1905148,0xd079d849,0x66f16d4a,0x281ff94b,0x4cbc284c,0xe364e94d,0x5fda1a4e,0x4628d24f,0x47d17d50,0x53ca2751,0x6738c52,0x2a1c9653,0xcdab0454,0x7429e855,0x91c38556,0xb3c8ab57,0xa98cb258,0x26151d59,0x5525b75a,0xd955c75b,0x51c3475c,0x8350855d,0x1c30b65e,0x70339d5f,0x78a88460,0x4cc2a361,0x12464c62,0x5a34b63,0x3fee8864,0xa8633565,0x3e23d766,0xf8cd5767,0x52432068,0x9cae0969,0x63aa1d6a,0x8742826b,0x75e67b6c,0x2ef696d,0x25006d6e,0x89daa76f,0xbbb71870,0x2faca571,0x71374172,0x9b818673,0xa0de6274,0x29326075,0xb2401776,0x8edcb677,0x7a265378,0x87dd7779,0xb726ce7a,0x99f0397b,0x81a8967c,0x97d0437d,0xc9147e,0x27a1a17f,0xabd65680,0xc405e681,0xc0107482,0xe63b7783,0x16d43984,0x37c8e085,0xc6f26286,0x151dac87,0x67c36588,0xe593b589,0x669e388a,0x5c46a68b,0xb822fe8c,0x6455d18d,0x54b49d8e,0x475edc8f,0xfa8a9690,0xa38c7d91,0xa25f6692,0x32b9a193,0x22bf7c94,0xa72cfb95,0xcaa48696,0x78639e97,0x5dca8798,0xe263e99,0x59c599a,0x855a4f9b,0x4e66949c,0x3a27d89d,0xca15ec9e,0xe443da9f,0xaeaea3a0,0xdc6cdca1,0xa3bb51a2,0xd0f12da3,0xfcd7cda4,0x959c62a5,0x9e276ca6,0x67caeca7,0xc36d51a8,0xe76712a9,0x95d4b5aa,0xe6b1a1ab,0x60979aac,0xae2d55ad,0xf73e82ae,0x87622af,0x55678db0,0xf3813ab1,0x66bd2ab2,0x640762b3,0xab7d25b4,0xce243ab5,0x565e39b6,0x9389fcb7,0xecb84db8,0x8da369b9,0x2b1138ba,0x1a1b3ebb,0xa6a40cbc,0x2659acbd,0xb90ac3be,0xbb61e9bf,0x17dc81c0,0xf9cb57c1,0x1f2c47c2,0x177c6ec3,0x68cb55c4,0x94648fc5,0xb6c33ec6,0x9e71ffc7,0x21d49c8,0x1c1f96c9,0x40fdf8ca,0x608471cb,0x90c71acc,0x83049fcd,0x31232bce,0xa755d0cf,0x2995fd0,0x8ef786d1,0xaf7ae2d2,0x49e5f9d3,0xb621d1d4,0xa30ef5d5,0x75e168d6,0x6fcb3d7,0xe83308d8,0x29c1ead9,0x6b000ada,0xf37c94db,0xe2884cdc,0x7f92e0dd,0x93836ade,0x633232df,0xe29bc4e0,0x8e761fe1,0x31a905e2,0xd46a41e3,0x159184e4,0xd3f654e5,0x6abdbde6,0x865f3be7,0x9f7c41e8,0xb6e13de9,0xae2525ea,0x62d6c9eb,0x271459ec,0x1a13ffed,0x173ed9ee,0x1d2edaef,0x44366bf0,0xc9928f1,0x3fb38bf2,0xdf3dacf3,0x1b5250f4,0xf5f486f5,0x6a7c18f6,0xfce055f7,0xde547ff8,0x35a76ef9,0x2d3666fa,0xa4ba58fb,0x83f9f6fc,0xedb424fd,0xcc4d8fe,0xe0f0baff};
    	private static int cashLen[]={0x328aa,0x6144d,0xb900e,0x3ef04,0x7a10,0xc65aa,0x85819,0x6acf,0x16e30,0x3c13e,0x95b7b,0xcdfba,0xdd3e0,0xbae88,0x1406b,0x2ae9a,0x7bf85,0x17d72,0x9e4cd,0x8e16a,0x754b6,0x68e5c,0xd4a89,0xd6904,0x501a8,0x496da,0x21606,0x3d080,0x98942,0x4f269,0x374f4,0x8f0af,0xa9be5,0xc74e5,0x1f782,0x3fe46,0xc0a16,0xc37da,0x8a462,0x31968,0x510eb,0x59a3c,0x19bf6,0xa4f9b,0xaf773,0xb15f4,0xc8424,0xe10f0,0xb80c2,0x97a00,0x3dfc2,0x90f31,0x94c38,0xf1440,0xa1294,0x6cb64,0xca2b1,0x9d58a,0x632d8,0x42c0c,0x112a4,0x56c76,0xf23e2,0xe8af6,0x93cf6,0x29016,0x848d6,0xac9aa,0xe2f62,0x7733a,0x4b561,0x48799,0xd3b4a,0xe5d49,0xcd078,0x80bce,0x1e84,0xe7bad,0x2dc60,0x5202c,0x10362,0x74574,0x40d88,0xb718,0x9b707,0x35670,0x13128,0xbfada,0x3b1fc,0xcfe57,0x41ccc,0xd59e,0xd2c03,0x67f1b,0x2eba2,0x8952,0xe4e0d,0xb06b4,0x7de08,0x1c9bc,0x57bb8,0x14fac,0xaba6b,0xd59c5,0x26250,0x6bc24,0xb7184,0x38436,0xee717,0x121e6,0x46916,0x9894,0xe019d,0x18cb4,0x1d8fe,0x53eb0,0x83998,0x52f6e,0x39379,0x337ec,0xa4059,0xc4724,0x6daa6,0x5a97e,0x726f0,0x66097,0x6f92a,0x717ae,0xa5ee4,0x73632,0x2348a,0x0,0xc289a,0x7ed4a,0xd784f,0x6e9e8,0x6238e,0xdb54c,0xbeb93,0x92db5,0x66fd8,0x9988a,0x4c4a0,0xe6c69,0x5f5c8,0xd1cb8,0x5b8c0,0x64212,0x1ba7a,0xf420,0x5e686,0xd878a,0xbcd0c,0x7086c,0xe9a3b,0xad8ec,0x54df2,0x5d744,0x763fa,0xe3ecf,0x8d22d,0xb6243,0x9f412,0x206c5,0x9a7c8,0x9c64c,0xcc12f,0x81b12,0x89520,0x96abc,0xe204a,0x365b2,0x7b045,0xa7d6,0x44a90,0xd0d84,0x4e325,0xb3485,0x29f58,0x55d34,0x459d3,0xb253c,0x4c4a,0x5b8c,0xda610,0xea98d,0x885de,0xc65a,0x69d9e,0xc9367,0x4a61c,0xa3117,0x8b3a4,0xd96c8,0x65154,0xde316,0x6ace0,0x3d08,0x5c803,0xbbdcd,0xb43bc,0xc565e,0xa0351,0xf33a7,0xa7d60,0x791be,0xdc4ad,0x280d4,0x1e840,0x2dc6,0x7827c,0xdf25d,0xa8ca8,0x91e73,0xf42,0x8fff1,0x47856,0x7cec6,0x243ce,0xe4de,0xb5305,0x82a53,0x2cd22,0x3472e,0x58afa,0xc195a,0xcb1ec,0xb9f48,0x8675a,0xae834,0xceef9,0xbdc52,0x2bddc,0x8769c,0x7a100,0x7fc91,0x8c2ea,0xa21d5,0x22548,0x3a2bc,0x6050b,0x1ab38,0xef5b9,0xaab26,0xeb8b3,0x15eee,0x43b4e,0x27192,0x2fae4,0xa6e29,0xec7fb,0x2530e,0x4d3e2,0xed769,0x30a26,0xf0568};
    	Circle circles[];
    	double kof=29.9792458;
    	// 
    	static InputStream in;
    	// 
    	final int maxLen10=10000000;
    	final int maxLen1=maxLen10/10;
    	final int maxLenB=16384;
    	// 
    	final byte buf[]=new byte[maxLenB];
    	int posBuf=0;
    	int lenBuf=0;
    	
    	public static void main(String[] args) throws UnsupportedEncodingException, NoSuchAlgorithmException, FileNotFoundException, IOException {
    		
    //		Pset tests[]=new Pset[]{new Pset(-1.81683e+006,-1.74334e+006),new Pset(3.06932e+006, -2.59405e+006),new Pset(3420803.233, -1950298.548)};
    //		long t=System.currentTimeMillis();
    //
    //		for(int i=0;i<tests.length;i++){
    //			in=new FileInputStream("test"+(i+1)+".in");
    //			Pset answer=new Pset();
    //			new Olimp(answer);
    //			answer.printDlta(tests[i]);
    //		}
    //		System.out.println("end"+(System.currentTimeMillis()-t));
    
    
    
    		//in=new FileInputStream("test1.in");
    		in=System.in;
    		Pset answer=new Pset();
    		new Olimp(answer);
    		answer.print();
    		
    	}
    	
    	
    	double readDouble(){
    		while(isBR(buf[posBuf]))posBuf++;
    		int start=posBuf;
    		while(!isBR(buf[posBuf]))posBuf++;
    		String s=new String(buf,start,posBuf-start);
    		while(isBR(buf[posBuf]))posBuf++;
    		return Double.parseDouble(s);
    	}
    	static final boolean isBR(final byte val){
    		return val==13 || val==10 || val==32;
    	}
    	void readMin500()throws IOException{
    		while(lenBuf<500){
    			int l=in.read(buf,lenBuf,maxLenB-lenBuf);
    			if(l==-1)
    				throw new IOException();
    			lenBuf+=l;
    		}
    	}
    	void read()throws IOException{
    		if(posBuf>=maxLenB){
    			posBuf%=maxLenB;
    			lenBuf=0;
    		}
    		int l=in.read(buf,lenBuf,maxLenB-lenBuf);
    		if(l==-1)
    			throw new IOException();
    		lenBuf+=l;
    	}
    
    	private Olimp(final Pset answer)throws IOException{	
    		readMin500();
    		circles=new Circle[(int)readDouble()];
    		for(int sp=0;sp<circles.length;sp++){
    			readMin500();
    			circles[sp]=new Circle(readDouble(), readDouble());	
    
    			int readData=0;
    			int shift=0;
    			{
    				byte temp=buf[posBuf];
    				while(buf[posBuf+shift]==temp)
    					shift++;
    				shift%=10;
    				posBuf+=shift;
    				readData+=shift;
    			}
    			
    			int data=0;
    			for(int i=0;i<32;i++,posBuf+=10){
    				data<<=1;
    				data|=buf[posBuf]==48?(byte)0:(byte)1;
    			}
    			readData+=320;
    			
    			m1:while(posBuf<maxLenB){
    				for(;posBuf<lenBuf;posBuf+=10,readData+=10){
    					if(cash[data&0xFF]==data){
    						double len=            readData             -320 +maxLen10-cashLen[data&0xFF]*10   ;
    						circles[sp].r=len*kof;
    						break m1;
    					}
    							
    					data<<=1;
    					data|=buf[posBuf]==48?(byte)0:(byte)1;
    				}
    				read();
    			}
    			in.skip(maxLen10-(readData+(lenBuf-posBuf)));
    			posBuf=0;
    			lenBuf=0;
    		}
    		int testPset=1;
    		for(int i=2;i<circles.length;i++){
    			if(circles[testPset].r<circles[i].r){
    				testPset=i;
    			}
    		}
    		Pset p0=new Pset();
    		Pset p1=new Pset();
    		int gggg=intersection(circles[0],circles[testPset],p0,p1);
    		double delta0=precisionAll(p0,circles);
    		if(gggg==1){
    			answer.x=p0.x;
    			answer.y=p0.y;
    			return;
    		}
    		double delta1=precisionAll(p1,circles);
    		if(delta0<delta1){
    			answer.x=p0.x;
    			answer.y=p0.y;
    		}else{
    			answer.x=p1.x;
    			answer.y=p1.y;
    		}
    	}
    	static double pow2(double x){
    		return x*x;
    	}
    	static double precisionAll(Pset p0,Circle[] circles){
    		double delta=0;
    		Pset sum=new Pset();
    		Pset temp=new Pset();
    		for(int j=1;j<7;j++){
    			sum.x=0;
    			sum.y=0;
    			for(int i=0;i<circles.length;i++){
    				precision(p0,circles[i],temp);
    				sum.x+=temp.x;
    				sum.y+=temp.y;
    				delta=pow2(temp.x-p0.x)+pow2(temp.y-p0.y);
    			}
    			p0.x=sum.x/circles.length;
    			p0.y=sum.y/circles.length;
    		}
    		return 	delta;
    	}
    	static void precision(Pset pset,Circle circle,Pset returnPset){
    		double dx=pset.x-circle.x;
    		double dy=pset.y-circle.y;
    		double dz=circle.distanceTo(pset);
    		if(dz<0.0000001){
    			if(circle.r<0.000001){
    				returnPset.x=circle.x;
    				returnPset.y=circle.y;
    				return ;
    			}
    			
    			returnPset.x=pset.x+ circle.r;
    			returnPset.y=pset.y+circle.r;
    			return;	
    		}
    		returnPset.x=circle.x+dx*circle.r/dz;
    		returnPset.y=circle.y+dy*circle.r/dz;
    	}
    	static int intersection(Circle circle0,Circle circle1,Pset first,Pset second) 
    	{
    		double x0,y0;
    		double d;
    		double a;
    		double h;
    
    		d=circle0.distanceTo(circle1);
    		
    		double deltaX=circle1.x - circle0.x;
    		double deltaY=circle1.y - circle0.y;
    		
    		if(d >= circle0.r+circle1.r) {
    			first.x = circle0.x+deltaX*circle0.r/(circle0.r+circle1.r);
    			first.y = circle0.y+deltaY*circle0.r/(circle0.r+circle1.r);
    			return 1; 
    		}
    		if(d <= abs(circle0.r-circle1.r)) { 
    			deltaX/=d;
    			deltaY/=d;
    			if(circle1.r<circle0.r){
    				first.x = (circle0.x+deltaX*circle0.r   +  circle1.x+deltaX*circle1.r)/2;
    				first.y = (circle0.y+deltaY*circle0.r   +  circle1.y+deltaY*circle1.r)/2;
    			}else{
    				first.x = (circle0.x-deltaX*circle0.r   +  circle1.x-deltaX*circle1.r)/2;
    				first.y = (circle0.y-deltaY*circle0.r   +  circle1.y-deltaY*circle1.r)/2;
    			}
    				
    			return 1;
    		}
    
    		a= (pow2(circle0.r) - pow2(circle1.r) + d*d ) / (2*d);
    		h= sqrt( pow2(circle0.r) - pow2(a));
    
    		x0 = circle0.x + a*deltaX / d;
    		y0 = circle0.y + a*deltaY / d;
    
    		first.x= x0 + h*deltaY / d;
    		first.y= y0 - h*deltaX / d;
    		//if(a == circle0.r ) return 1;
    		second.x= x0 - h*deltaY / d;
    		second.y= y0 + h*deltaX / d;
    		return 2;
    	}
    }
    class Pset{
    	double x;
    	double y;
    	Pset(){
    	}
    	Pset(double xx,double yy){
    		x=xx;
    		y=yy;
    	}
    	double distanceTo(Pset p){
    		return sqrt((x-p.x)*(x-p.x)+(y-p.y)*(y-p.y));
    	}
    	void print(){
    		System.out.println(""+x+" "+y);
    	}
    	void printDlta(Pset answer){
    		System.out.println(""+(x-answer.x)+" "+(y-answer.y)+" "+Math.sqrt((x-answer.x)*(x-answer.x)+(y-answer.y)*(y-answer.y)));
    	}
    
    }
    class Circle extends Pset{
    	double r;
    	Circle(double xx,double yy){
    		super(xx,yy);
    	}
    	Circle(double xx,double yy,double rr){
    		super(xx,yy);
    		this.r=rr;
    	}
    }
    

С полной таблицей результатов можно ознакомится тут. Красным подсвечены результаты, выходящие за допустимые пределы (ошибка более 1000 метров, или время работы более 5 секунд. ). Скачать все решения, их ответы и результаты компиляции — можно тут. В верхней части таблицы все еще есть read-only пользователи, исправляем: ibessonov, where-is-s, Leng, Kofko, shuternay, wSpirit, dimka-74.
Читать дальше →

Spring изнутри. Этапы инициализации контекста

Время на прочтение11 мин
Охват и читатели405K


Доброго времени суток уважаемые хабравчане. Уже 3 года я работаю на проекте в котором мы используем Spring. Мне всегда было интересно разобраться с тем, как он устроен внутри. Я поискал статьи про внутреннее устройство Spring, но, к сожалению, ничего не нашел.

Всех, кого интересует внутреннее устройство Spring, прошу под кат.
Читать дальше →

Пул констант

Время на прочтение3 мин
Охват и читатели33K
Многие знают, что в каждом .class-файле есть замечательная структура данных, которая называется пулом констант. Но далеко не каждый Java-разработчик, глядя на исходник, сможет даже примерно оценить, сколько констант будет создано в пуле.

Возьмём, к примеру, такой код:

System.out.println("Hello World!");

Он транслируется в три инструкции байткода: getstatic (для загрузки статического поля System.out), ldc (для загрузки константной строки «Hello World!») и invokevirtual (для выполнения виртуальной функции println). Попробуйте прикинуть, сколько констант нужно для того, чтобы этот код работал.
Читать дальше →

Анализ утечек PermGen памяти в Java

Время на прочтение7 мин
Охват и читатели60K

О чем речь?


Кто занимался веб-разработкой на Java, наверняка сталкивался с такой проблемой как java.lang.OutOfMemoryError: PermGen space. Возникает она, как правило, после перезапуска веб-приложения внутри сервера без перезапуска самого сервера. Перезапуск веб-приложения без перезапуска сервера может понадобиться в процессе разработки, чтобы не ждать лишнее время запуска самого сервера. Если у вас задеплоено несколько веб-приложений, перезапуск всего сервера может быть гораздо дольше перезапуска одного веб-приложения. Или же весь сервер просто нельзя перезапускать, так как другие веб-приложения используются. Первое решение, которое приходит на ум – увеличить максимальный объем PermGen памяти, доступный JVM (сделать это можно опцией -XX:MaxPermSize), но это лишь отсрочит падение, после нескольких перезапусков вы снова получите OutOfMemoryError. Хорошо было бы иметь возможность сколько угодно раз перезапускать и передеплоивать веб-приложение на работающем сервере. О том, как побороть PermGen, и пойдет дальнейший разговор.

Читать дальше →

Oracle выиграла аппеляцию против Google

Время на прочтение1 мин
Охват и читатели63K

Корпорация Oracle одержала победу в ключевом деле против Google. Аппеляционный суд США постановил: Oracle обладает авторским правом на части языка программирования Java, использованные Google при разработке ОС Android. «Мы пришли к выводу, что набор команд, заставляющий компьютер выполнить желаемые операции, может содержать выражения, подвергаемые авторскому праву», — комментирует судья федерального округа Кэтлин О'Мэлли.

В 2010 Oracle подала в суд на Google за нарушение авторских прав на части Java для Android. Oracle оценила ущерб в один миллиард долларов.

Oracle чрезвычайно удовлетворена: «решение федерального округа — большая победа для Oracle и всей индустрии программного обеспечения, продиктованное защитой авторского права для стимулирования инноваций и уверенности, что разработчики будут вознаграждены за свои достижения».

Компания Google не прокомментировала ситуацию.

Майское хабрасоревнование: делаем свой ГЛОНАСС

Время на прочтение5 мин
Охват и читатели30K
Шла холодная зима 2063 года… Вы, сидя в избушке в сибирских степях, попивая горячий чай, из ностальгических побуждений достали свой любимый раритетный смартфон образца 2014 года с поддержкой ГЛОНАСС — однако он почему-то не нашел ни одного спутника. Вдруг тишину разрезал пронзительный звонок красного правительственного телефона — голос на той стороне затараторил: оказалось все спутники ГЛОНАСС вышли из строя из-за неизвестного сбоя… (ТЗЧ? Закладки? Кто теперь разберет....)

Что-ж, надежда теперь только на вас — нужно в кратчайшие сроки (к понедельнику) разработать новую систему спутниковой навигации с учетом достижений науки и техники 2063 года: в связи с тем, что термоядерные реакторы и аннигиляционные двигатели стали достаточно компактными, чтобы помещаться на борту спутника — их теперь фиксируют в одной точке в околоземном пространстве, никакой орбиты больше нет. Соответственно, альманах и эфемериды (параметры орбиты спутников) больше не нужно передавать со спутника на землю.
Читать дальше →

Типы-значения в Java

Время на прочтение1 мин
Охват и читатели25K
Duke
Этот пост — вольно-краткий перевод документа State of the Values, предложения по введению типов-значений в JVM и сам язык Java, который написали Джон Роуз, Брайан Гоетц и Гай Стил, разбавленный моими мыслями. Опущены детали предложения по реализации типов-значений на уровне байт-кода, что не очень интересно для большинства Java-программистов.



Важнейшая мысль: объектная (ссылочная) идентичность нужна только для поддержки изменяемости объектов. Объект может изменить состояние, но по ссылке мы всегда можем проверить, что это «тот же» объект. Поэтому типы-значения будут строго неизменяемые.

Предполагаемые варианты использования типов-значений:
  • Числа: комплексные, беззнаковые, 128-битные, с фиксированной запятой и т. д. Все, что не описывается имеющимися примитивами.
  • Алгебраические типы: Optional, Choice<T,U>, перечисления
    Кортежи: пары, тройки, ...
    Итераторы, курсоры
    «Уплощение» сложных структур

  • Целевые фичи:
Читать дальше →

Java 8, Spring, Hibernate, SSP — начинаем играться

Время на прочтение7 мин
Охват и читатели44K
Совсем недавно вышла Java 8. И у меня возникло желание написать что-то с использованием новых плюшечек, которые дает 8-ерка.
Конкретно Лямбы, новый collection api, позволяющий работать с коллекциями в более функциональном стиле и default-методы в интерфейсах.

Статья является кратким обзором моего опыта по интегрированию Java 8, Spring MVC, Hibernate и SSP.

Кому интересно, прошу под кат.
Читать дальше →

Анонс майского хабрасоревнования по программированию на Java от WayRay

Время на прочтение1 мин
Охват и читатели12K
Не знаете чем заняться в майские праздники? Решение есть!

Мы в WayRay сейчас как раз ищем разработчиков и у меня возникла идея: а что, если совместить приятное с полезным, и за деньги, которые обычно отдают рекрутерам — попробовать организовать маленькое соревнование с призами, а с десяток авторов лучших результатов — помимо вручения призов пригласить на собеседование? (вы естественно можете забрать приз и не идти на собеседование — это сугубо добровольно).

Что-ж, посмотрим, что из этого выйдет!

Сроки проведения соревнования: с 9 мая 0:00 по 11 мая 23:59 по московскому времени.
Условия будут опубликованы 9 мая в 0:00 — в этих же хабах на хабре, прием решений соответственно не позднее 11 мая 23:59.
Читать дальше →

Ближайшие события

Анонс первой встречи Java User Group EKB

Время на прочтение1 мин
Охват и читатели2.7K
Привет, Хабр!

Несмотря на то, что в Екатеринбурге на java разрабатывает далеко не одна компания, java комьюнити отсутствует. Но когда тебе чего-то не хватает, то нужно просто взять и сделать это. Так, просмотрев очередную встречу JUG.ru, окончательно стало ясно, что Екатеринбургу нужно место, где java разработчики могут встретиться, обсудить новости java технологий, поговорить про внутренности java, да и просто пообщаться!

Так родилось JUG.EKB — cообщество Java разработчиков Екатеринбурга.
Читать дальше →

Как понять NullPointerException

Время на прочтение5 мин
Охват и читатели296K
Эта простая статья скорее для начинающих разработчиков Java, хотя я нередко вижу и опытных коллег, которые беспомощно глядят на stack trace, сообщающий о NullPointerException (сокращённо NPE), и не могут сделать никаких выводов без отладчика. Разумеется, до NPE своё приложение лучше не доводить: вам помогут null-аннотации, валидация входных параметров и другие способы. Но когда пациент уже болен, надо его лечить, а не капать на мозги, что он ходил зимой без шапки.

Итак, вы узнали, что ваше приложение упало с NPE, и у вас есть только stack trace. Возможно, вам прислал его клиент, или вы сами увидели его в логах. Давайте посмотрим, какие выводы из него можно сделать.
Читать дальше →

Знакомство с Kotlin и сборка jar при помощи maven

Время на прочтение7 мин
Охват и читатели18K
Это пост заметка о том, как я познакомился с языком Kotlin, какие использовал для этого ресурсы, инструменты, и как я собрал его в jar и запустил в консоли.

В общем-то я PHP программист, немного заком с Java. На днях решил посмотреть Kotlin. Это менее строго типизированный язык от JetBrains до того, что он, по сути, статически типизированный. В этом его основное принципиальное отличие от Java, плюс Kotlin имеет свой приятный синтаксис. Kotlin может быть скомпилирован в JVM или JavaScript.

Приступим к знакомству. Для начала понадобится IDE Idea.
Читать дальше →

JSR 133 (Java Memory Model) FAQ (перевод)

Время на прочтение25 мин
Охват и читатели159K
Добрый день.
В рамках набора на курс «Multicore programming in Java» я делаю серию переводов классических статей по многопоточности в Java. Всякое изучение многопоточности должно начинаться с введения в модель памяти Java (New JMM), основным источником от авторов модели является «The Java Memory Model» home page, где для старта предлагается ознакомится с JSR 133 (Java Memory Model) FAQ. Вот с перевода этой статьи я и решил начать серию.
Я позволил себе несколько вставок «от себя», которые, по моему мнению, проясняют ситуацию.
Я являюсь специалистом по Java и многопоточности, а не филологом или переводчиком, посему допускаю определенные вольности или переформулировки при переводе. В случае, если Вы предложите лучший вариант — с удовольствием сделаю правку.
Этот статья также подходит в качестве учебного материала к лекции «Лекция #5.2: JMM (volatile, final, synchronized)».

Также я веду курс «Scala for Java Developers» на платформе для онлайн-образования udemy.com (аналог Coursera/EdX).

Ну и да, приходите учиться ко мне!


JSR 133 (Java Memory Model) FAQ


Jeremy Manson и Brian Goetz, февраль 2004

Содержание:
Что такое модель памяти, в конце концов?
Другие языки, такие как C++, имеют модель памяти?
Что такое JSR 133?
Что подразумевается под «переупорядочением» (reordering)?
Что было не так со старой моделью памяти?
Что вы подразумеваете под «некорректно синхронизированы»?
Что делает синхронизация?
Как может случиться, что финальная поля меняют значения?
How do final fields work under the new JMM?
Что делает volatile?
Решила ли новая модель памяти «double-checked locking» проблему?
Что если я пишу виртуальную машину?
Почему я должен беспокоиться?
Читать дальше →

J-сортировка

Время на прочтение7 мин
Охват и читатели89K

Пирамидальная сортировка (она же сортировка кучей) – классический алгоритм который, пожалуй, должен знать любой программист. Старая добрая «пирамидка» примечательна тем, что в независимости от набора данных у неё одна и та же сложность по времени (причём, очень пристойная) – O(n log n). Лучших и вырожденных случаев для неё нет.

С момента изобретения метода (а в этом году алгоритм празднует свой полувековой юбилей) было немало охочих кардинально оптимизировать процесс накладывания сортирующих куч. Тернарная пирамидальная сортировка, плавная сортировка, сортировка декартовым деревом – вот неполный список инноваций. Перечисленные алгоритмы хотя при тестировании и опережают оригинал по абсолютной скорости кто на 12, а кто и на 25%, в оценке временной сложности всё равно крутятся вокруг O(n log n). При этом данные методы весьма изощрённо реализованы.

Своё видение пирамидальной сортировки предложил и скромный труженик Университета Манитобы Джейсон Моррисон. При этом способ в некоторых случаях по скорости приближается к O(n).

Так ещё метод и прост до безобразия

Строим веб-приложение на Java без JEE и Spring

Время на прочтение2 мин
Охват и читатели40K


Данная статья будет интересна тем, кто вдруг осознал, что ему хочется
попробовать создать что-то без навязанного обществом JEE и Spring.

Вы, о дорогой Java Смельчак, не хотите быть винтиком в огромном механизме вашего Фреймворка?
Вам надоело чувствовать себя «машинисткой» по написанию конфигов и настроек?
Вы хотите решать задачи так, как хочется вам, а не так, как это видится автору унифицированной на нужды
миллионов библиотеки?

Тогда добро пожаловать под кат, где я поделюсь с вами полезными находками Мира без Фреймворка.

Читать дальше →

Создание Custom Scope в JEE и Spring

Время на прочтение12 мин
Охват и читатели14K
Scope определяет жизненный цикл объекта. Например, java-бин (далее просто бин) определённый в RequestScope создается при получении http запроса и освобождается при завершении данного запроса. В JEE и в Spring есть возможность создавать свой собственный scope. Т.е. мы можем создавать объекты со своим собственным жизненным циклом — они будут создаваться по какому либо нашему событию и также уничтожаться. В JEE за это отвечает спецификация CDI (Context and Dependency Injection) и на самом деле там уже есть один подобный встроенный scope. Это ConversationScope. У нас есть API и аннотации для начала и окончания conversation. Если мы их не используем, то по-умолчанию ConversationScope ведет себя как RequestScope. Для отслеживания conversation каждого отдельного клиента используется специальный conversationId, который обычно добавляется как параметр http запроса. Но такой подход не работает для веб-сервисов. А в Spring вообще нет ничего подобного. Но в моей практике заказчик попросил сделать веб-сервис, который бы использовал одно и то же физическое соединение к внешней системе для нескольких последовательных вызовов. Также надо было хранить некоторое количество дополнительных данных. Т.е. надо было сохранять некое состояние (объект с соединением и данными) на определённый промежуток времени, такой аналог conversation scope для веб-сервиса. Можно, конечно, сохранить этот объект в Мар, где ключом будет наш аналог conversationId, а Мар положить в ServleContext и доставать это всё из методов веб-сервиса. Но это неудобно. Гораздо удобнее, когда сам сервер будет инжектить нам наш объект по заданному conversationId. Поэтому, сделаем свой scope, который будет работать с SOAP веб-сервисом. Сам по себе веб-сервис не может принадлежать какому-либо scope, но наш бин, который мы будем инжектить в веб-сервис, будет принадлежать нашему scope.
Читать дальше →