15 research outputs found

    Automated Refactoring of Legacy Java Software to Default Methods

    Full text link
    Java 8 default methods, which allow interfaces to contain (instance) method implementations, are useful for the skeletal implementation software design pattern. However, it is not easy to transform existing software to exploit default methods as it requires analyzing complex type hierarchies, resolving multiple implementation inheritance issues, reconciling differences between class and interface methods, and analyzing tie-breakers (dispatch precedence) with overriding class methods to preserve type-correctness and confirm semantics preservation. In this paper, we present an efficient, fully-automated, type constraint-based refactoring approach that assists developers in taking advantage of enhanced interfaces for their legacy Java software. The approach features an extensive rule set that covers various corner-cases where default methods cannot be used. To demonstrate applicability, we implemented our approach as an Eclipse plug-in and applied it to 19 real-world Java projects, as well as submitted pull requests to popular GitHub repositories. The indication is that it is useful in migrating skeletal implementation methods to interfaces as default methods, sheds light onto the pattern’s usage, and provides insight to language designers on how this new construct applies to existing software

    Reengineering and Refactoring

    Full text link

    Proactive Empirical Assessment of New Language Feature Adoption via Automated Refactoring: The Case of Java 8 Default Methods

    Full text link
    Programming languages and platforms improve over time, sometimes resulting in new language features that offer many benefits. However, despite these benefits, developers may not always be willing to adopt them in their projects for various reasons. In this paper, we describe an empirical study where we assess the adoption of a particular new language feature. Studying how developers use (or do not use) new language features is important in programming language research and engineering because it gives designers insight into the usability of the language to create meaning programs in that language. This knowledge, in turn, can drive future innovations in the area. Here, we explore Java 8 default methods, which allow interfaces to contain (instance) method implementations. Default methods can ease interface evolution, make certain ubiquitous design patterns redundant, and improve both modularity and maintainability. A focus of this work is to discover, through a scientific approach and a novel technique, situations where developers found these constructs useful and where they did not, and the reasons for each. Although several studies center around assessing new language features, to the best of our knowledge, this kind of construct has not been previously considered. Despite their benefits, we found that developers did not adopt default methods in all situations. Our study consisted of submitting pull requests introducing the language feature to 19 real-world, open source Java projects without altering original program semantics. This novel assessment technique is proactive in that the adoption was driven by an automatic refactoring approach rather than waiting for developers to discover and integrate the feature themselves. In this way, we set forth best practices and patterns of using the language feature effectively earlier rather than later and are able to possibly guide (near) future language evolution. We foresee this technique to be useful in assessing other new language features, design patterns, and other programming idioms

    Proactive Empirical Assessment of New Language Feature Adoption via Automated Refactoring: The Case of Java 8 Default Methods

    Full text link
    Programming languages and platforms improve over time, sometimes resulting in new language features that offer many benefits. However, despite these benefits, developers may not always be willing to adopt them in their projects for various reasons. In this paper, we describe an empirical study where we assess the adoption of a particular new language feature. Studying how developers use (or do not use) new language features is important in programming language research and engineering because it gives designers insight into the usability of the language to create meaning programs in that language. This knowledge, in turn, can drive future innovations in the area. Here, we explore Java 8 default methods, which allow interfaces to contain (instance) method implementations. Default methods can ease interface evolution, make certain ubiquitous design patterns redundant, and improve both modularity and maintainability. A focus of this work is to discover, through a scientific approach and a novel technique, situations where developers found these constructs useful and where they did not, and the reasons for each. Although several studies center around assessing new language features, to the best of our knowledge, this kind of construct has not been previously considered. Despite their benefits, we found that developers did not adopt default methods in all situations. Our study consisted of submitting pull requests introducing the language feature to 19 real-world, open source Java projects without altering original program semantics. This novel assessment technique is proactive in that the adoption was driven by an automatic refactoring approach rather than waiting for developers to discover and integrate the feature themselves. In this way, we set forth best practices and patterns of using the language feature effectively earlier rather than later and are able to possibly guide (near) future language evolution. We foresee this technique to be useful in assessing other new language features, design patterns, and other programming idioms

    Proactive Empirical Assessment of New Language Feature Adoption via Automated Refactoring: The Case of Java 8 Default Methods

    Full text link
    Programming languages and platforms improve over time, sometimes resulting in new language features that offer many benefits. However, despite these benefits, developers may not always be willing to adopt them in their projects for various reasons. In this paper, we describe an empirical study where we assess the adoption of a particular new language feature. Studying how developers use (or do not use) new language features is important in programming language research and engineering because it gives designers insight into the usability of the language to create meaning programs in that language. This knowledge, in turn, can drive future innovations in the area. Here, we explore Java 8 default methods, which allow interfaces to contain (instance) method implementations. Default methods can ease interface evolution, make certain ubiquitous design patterns redundant, and improve both modularity and maintainability. A focus of this work is to discover, through a scientific approach and a novel technique, situations where developers found these constructs useful and where they did not, and the reasons for each. Although several studies center around assessing new language features, to the best of our knowledge, this kind of construct has not been previously considered. Despite their benefits, we found that developers did not adopt default methods in all situations. Our study consisted of submitting pull requests introducing the language feature to 19 real-world, open source Java projects without altering original program semantics. This novel assessment technique is proactive in that the adoption was driven by an automatic refactoring approach rather than waiting for developers to discover and integrate the feature themselves. In this way, we set forth best practices and patterns of using the language feature effectively earlier rather than later and are able to possibly guide (near) future language evolution. We foresee this technique to be useful in assessing other new language features, design patterns, and other programming idioms

    Safe Automated Refactoring for Intelligent Parallelization of Java 8 Streams

    Full text link
    Streaming APIs are becoming more pervasive in mainstream Object-Oriented programming languages and platforms. For example, the Stream API introduced in Java 8 allows for functional-like, MapReduce-style operations in processing both finite, e.g., collections, and infinite data structures. However, using this API efficiently involves subtle considerations such as determining when it is best for stream operations to run in parallel, when running operations in parallel can be less efficient, and when it is safe to run in parallel due to possible lambda expression side-effects. Also, streams may not run all operations in parallel depending on particular collectors used in reductions. In this paper, we present an automated refactoring approach that assists developers in writing efficient stream code in a semantics-preserving fashion. The approach, based on a novel data ordering and typestate analysis, consists of preconditions and transformations for automatically determining when it is safe and possibly advantageous to convert sequential streams to parallel, unorder or de-parallelize already parallel streams, and optimize streams involving complex reductions. The approach was implemented as a plug-in to the popular Eclipse IDE, uses the WALA and SAFE analysis frameworks, and was evaluated on 11 Java projects consisting of ∼642K lines of code. We found that 57 of 157 candidate streams (36.31%) were refactorable, and an average speedup of 3.49 on performance tests was observed. The results indicate that the approach is useful in optimizing stream code to their full potential

    Safe Automated Refactoring for Intelligent Parallelization of Java 8 Streams

    Full text link
    Streaming APIs are becoming more pervasive in mainstream Object-Oriented programming languages. For example, the Stream API introduced in Java 8 allows for functional-like, MapReduce-style operations in processing both finite and infinite data structures. However, using this API efficiently involves subtle considerations like determining when it is best for stream operations to run in parallel, when running operations in parallel can be less efficient, and when it is safe to run in parallel due to possible lambda expression side-effects. In this paper, we present an automated refactoring approach that assists developers in writing efficient stream code in a semantics-preserving fashion. The approach, based on a novel data ordering and typestate analysis, consists of preconditions for automatically determining when it is safe and possibly advantageous to convert sequential streams to parallel and unorder or de-parallelize already parallel streams. The approach was implemented as a plug-in to the Eclipse IDE, uses the WALA and SAFE analysis frameworks, and was evaluated on 11 Java projects consisting of ∼642K lines of code. We found that 57 of 157 candidate streams (36.31%) were refactorable, and an average speedup of 3.49 on performance tests was observed. The results indicate that the approach is useful in optimizing stream code to their full potential

    An Empirical Study of Refactorings and Technical Debt in Machine Learning Systems

    Full text link
    Machine Learning (ML), including Deep Learning (DL), systems, i.e., those with ML capabilities, are pervasive in today’s data-driven society. Such systems are complex; they are comprised of ML models and many subsystems that support learning processes. As with other complex systems, ML systems are prone to classic technical debt issues, especially when such systems are long-lived, but they also exhibit debt specific to these systems. Unfortunately, there is a gap of knowledge in how ML systems actually evolve and are maintained. In this paper, we fill this gap by studying refactorings, i.e., source-to-source semantics-preserving program transformations, performed in real-world, open-source software, and the technical debt issues they alleviate. We analyzed 26 projects, consisting of 4.2 MLOC, along with 327 manually examined code patches. The results indicate that developers refactor these systems for a variety of reasons, both specific and tangential to ML, some refactorings correspond to established technical debt categories, while others do not, and code duplication is a major cross-cutting theme that particularly involved ML configuration and model code, which was also the most refactored. We also introduce 14 and 7 new ML-specific refactorings and technical debt categories, respectively, and put forth several recommendations, best practices, and anti-patterns. The results can potentially assist practitioners, tool developers, and educators in facilitating long-term ML system usefulness

    Automated Evolution of Feature Logging Statement Levels Using Git Histories and Degree of Interest

    Full text link
    Loggingβ€”used for system events and security breaches to more informational yet essential aspects of software featuresβ€”is pervasive. Given the high transactionality of today’s software, logging effectiveness can be reduced by information overload. Log levels help alleviate this problem by correlating a priority to logs that can be later filtered. As software evolves, however, levels of logs documenting surrounding feature implementations may also require modification as features once deemed important may have decreased in urgency and vice-versa. We present an automated approach that assists developers in evolving levels of such (feature) logs. The approach, based on mining Git histories and manipulating a degree of interest (DOI) model, transforms source code to revitalize feature log levels based on the β€œinterestingness” of the surrounding code. Built upon JGit and Mylyn, the approach is implemented as an Eclipse IDE plug-in and evaluated on 18 Java projects with ~3 million lines of code and ~4K log statements. Our tool successfully analyzes 99.26% of logging statements, increases log level distributions by ~20%, identifies logs manually modified with a recall of ~80% and a level-direction match rate of ~87%, and increases the focus of logs in bug fix contexts ~83% of the time. Moreover, pull (patch) requests were integrated into large and popular open-source projects. The results indicate that the approach is promising in assisting developers in evolving feature log levels

    Π˜ΡΡ‚Ρ€Π°ΠΆΡƒΠ²Π°ΡšΠ΅ Π·Π° Сфикасноста Π½Π° Π³Π΅Π½Π΅Ρ€ΠΈΡ€Π°ΡšΠ΅ ΠΊΠΎΠ΄ со GPT (Generative Pre-Trained Transformer) Π·Π° Π·Π°Π΄Π°Ρ‡ΠΈ Π²ΠΎ софтвСрското инТСнСрство

    Get PDF
    Π‘Ρ€Π·ΠΈΠΎΡ‚ Π½Π°ΠΏΡ€Π΅Π΄ΠΎΠΊ Π½Π° ΠΌΠΎΠ΄Π΅Π»ΠΈΡ‚Π΅ Π·Π° машинско ΡƒΡ‡Π΅ΡšΠ΅ ΠΊΠΎΠΈ користат ΠΎΠ±Ρ€Π°Π±ΠΎΡ‚ΠΊΠ° Π½Π° ΠΏΡ€ΠΈΡ€ΠΎΠ΄Π΅Π½ јазик ΠΏΡ€Π΅Π΄ΠΈΠ·Π²ΠΈΠΊΠ° интСрСс Π·Π° Π½ΠΈΠ²Π½Π°Ρ‚Π° ΠΏΠΎΡ‚Π΅Π½Ρ†ΠΈΡ˜Π°Π»Π½Π° ΠΏΡ€ΠΈΠΌΠ΅Π½Π° Π·Π° Π³Π΅Π½Π΅Ρ€ΠΈΡ€Π°ΡšΠ΅ ΠΊΠΎΠ΄ Π²ΠΎ областа софтвСрското инТСнСрство. Оваа Ρ‚Π΅Π·Π° ја испитува Сфикасноста Π½Π° GPT (Π“Π΅Π½Π΅Ρ€Π°Ρ‚ΠΈΠ²Π΅Π½ ΠΏΡ€Π΅Ρ‚Ρ…ΠΎΠ΄Π½ΠΎ-Ρ‚Ρ€Π΅Π½ΠΈΡ€Π°Π½ трансформСр) ΠΌΠΎΠ΄Π΅Π»ΠΈΡ‚Π΅ Π²ΠΎ Π°Π²Ρ‚ΠΎΠΌΠ°Ρ‚ΠΈΠ·ΠΈΡ€Π°ΡšΠ΅Ρ‚ΠΎ Π½Π° Π·Π°Π΄Π°Ρ‡ΠΈΡ‚Π΅ Π·Π° ΠΊΠΎΠ΄ΠΈΡ€Π°ΡšΠ΅, ΠΎΡ†Π΅Π½ΡƒΠ²Π°Ρ˜ΡœΠΈ Π³ΠΎ Π½ΠΈΠ²Π½ΠΈΠΎΡ‚ ΠΏΠΎΡ‚Π΅Π½Ρ†ΠΈΡ˜Π°Π» Π·Π° ΠΏΠΎΠ΄ΠΎΠ±Ρ€ΡƒΠ²Π°ΡšΠ΅ Π½Π° Сфикасноста, точноста ΠΈ ΠΊΠ²Π°Π»ΠΈΡ‚Π΅Ρ‚ΠΎΡ‚ Π½Π° ΠΊΠΎΠ΄ΠΎΡ‚. Π‘Ρ‚ΡƒΠ΄ΠΈΡ˜Π°Ρ‚Π° Π²ΠΊΠ»ΡƒΡ‡ΡƒΠ²Π° длабинска Π°Π½Π°Π»ΠΈΠ·Π° Π½Π° ΠΌΠΎΠ΄Π΅Π»ΠΈΡ‚Π΅ Π±Π°Π·ΠΈΡ€Π°Π½ΠΈ Π½Π° GPT, Π²ΠΊΠ»ΡƒΡ‡ΡƒΠ²Π°Ρ˜ΡœΠΈ Π³ΠΈ GPT-3.5 ΠΈ GPT-4, ΠΈ Π³ΠΈ ΠΎΡ†Π΅Π½ΡƒΠ²Π° Π½ΠΈΠ²Π½ΠΈΡ‚Π΅ пСрформанси Π²Ρ€Π· Ρ€Π°Π·Π»ΠΈΡ‡Π½ΠΈ програмски Ρ˜Π°Π·ΠΈΡ†ΠΈ ΠΈ Π·Π°Π΄Π°Ρ‡ΠΈ. Π’Π°Π° користи ΠΊΠ²Π°Π»ΠΈΡ‚Π°Ρ‚ΠΈΠ²Π½ΠΈ ΠΈ ΠΊΠ²Π°Π½Ρ‚ΠΈΡ‚Π°Ρ‚ΠΈΠ²Π½ΠΈ ΠΌΠ΅Ρ€ΠΊΠΈ ΠΈ ΡƒΠ²ΠΈΠ΄ΠΈ Π±Π°Π·ΠΈΡ€Π°Π½ΠΈ Π½Π° Π°Π½ΠΊΠ΅Ρ‚ΠΈ Π·Π° Π΄Π° ΠΎΠ±Π΅Π·Π±Π΅Π΄ΠΈ сСопфатна ΠΏΡ€ΠΎΡ†Π΅Π½ΠΊΠ° Π·Π° Сфикасноста Π½Π° ΠΎΠ²ΠΈΠ΅ ΠΌΠΎΠ΄Π΅Π»ΠΈ Π²ΠΎ Π³Π΅Π½Π΅Ρ€ΠΈΡ€Π°ΡšΠ΅Ρ‚ΠΎ ΠΊΠΎΠ΄. ΠŸΡ€Π²ΠΈΡ‡Π½ΠΈΡ‚Π΅ Π½Π°ΠΎΠ΄ΠΈ сугСрираат Π΄Π΅ΠΊΠ° ΠΈΠ°ΠΊΠΎ GPT ΠΌΠΎΠ΄Π΅Π»ΠΈΡ‚Π΅ ΠΏΠΎΠΊΠ°ΠΆΡƒΠ²Π°Π°Ρ‚ ΠΏΠΎΡ‚Π΅Π½Ρ†ΠΈΡ˜Π°Π» Π·Π° производство Π½Π° Ρ‚ΠΎΡ‡Π΅Π½, синтаксички ΠΏΡ€Π΅Ρ†ΠΈΠ·Π΅Π½ ΠΊΠΎΠ΄ Π·Π° Π΄ΠΎΠ±Ρ€ΠΎ спСцифицирани Π·Π°Π΄Π°Ρ‡ΠΈ, Π½ΠΈΠ²Π½Π°Ρ‚Π° Сфикасност сС Π½Π°ΠΌΠ°Π»ΡƒΠ²Π° ΠΊΠΎΠ³Π° сС соочуваат со двосмислСни ΠΈΠ»ΠΈ слоТСни описи Π½Π° Π·Π°Π΄Π°Ρ‡ΠΈ. ОвиС Ρ€Π΅Π·ΡƒΠ»Ρ‚Π°Ρ‚ΠΈ Π³ΠΈ истакнуваат ΠΈ моТноститС ΠΈ ΠΎΠ³Ρ€Π°Π½ΠΈΡ‡ΡƒΠ²Π°ΡšΠ°Ρ‚Π° Π½Π° Π°Π»Π°Ρ‚ΠΊΠΈΡ‚Π΅ Π·Π° Π³Π΅Π½Π΅Ρ€ΠΈΡ€Π°ΡšΠ΅ ΠΊΠΎΠ΄ Π±Π°Π·ΠΈΡ€Π°Π½ΠΈ Π½Π° GPT, ΡˆΡ‚ΠΎ ΡƒΠΊΠ°ΠΆΡƒΠ²Π° Π½Π° ΠΏΠΎΡ‚Ρ€Π΅Π±Π°Ρ‚Π° Π·Π° пософистицирани ΠΌΠΎΠ΄Π΅Π»ΠΈ способни Π΄Π° сС справат со слоТСноста Π½Π° софтвСрското инТСнСрство. Π˜ΡΡ‚Ρ€Π°ΠΆΡƒΠ²Π°ΡšΠ΅Ρ‚ΠΎ, исто Ρ‚Π°ΠΊΠ°, Π³ΠΈ истраТува ΠΈΠΌΠΏΠ»ΠΈΠΊΠ°Ρ†ΠΈΠΈΡ‚Π΅ Π½Π° Π³Π΅Π½Π΅Ρ€ΠΈΡ€Π°ΡšΠ΅Ρ‚ΠΎ ΠΊΠΎΠ΄ засновано Π½Π° GPT Π²Ρ€Π· Ρ€Π°Π±ΠΎΡ‚Π½ΠΈΡ‚Π΅ Ρ‚Π΅ΠΊΠΎΠ²ΠΈ Π½Π° софтвСрското инТСнСрство, Π΄ΠΈΡΠΊΡƒΡ‚ΠΈΡ€Π°Ρ˜ΡœΠΈ Π³ΠΈ ΠΌΠΎΠΆΠ½ΠΈΡ‚Π΅ ΠΏΡ€ΠΎΠΌΠ΅Π½ΠΈ Π²ΠΎ ΡƒΠ»ΠΎΠ³ΠΈΡ‚Π΅ Π½Π° софтвСрскитС ΠΈΠ½ΠΆΠ΅Π½Π΅Ρ€ΠΈ. Анализиран Π΅ ΠΏΠΎΡ‚Π΅Π½Ρ†ΠΈΡ˜Π°Π»ΠΎΡ‚ ΠΎΠ²ΠΈΠ΅ Π°Π»Π°Ρ‚ΠΊΠΈ Π·Π° Π²Π΅ΡˆΡ‚Π°Ρ‡ΠΊΠ° ΠΈΠ½Ρ‚Π΅Π»ΠΈΠ³Π΅Π½Ρ†ΠΈΡ˜Π° Π΄Π° ΠΈΠ·Π²Ρ€ΡˆΡƒΠ²Π°Π°Ρ‚ сСкојднСвни Π·Π°Π΄Π°Ρ‡ΠΈ, со ΡˆΡ‚ΠΎ ќС ΠΈΠΌ сС ΠΎΠ²ΠΎΠ·ΠΌΠΎΠΆΠΈ Π½Π° ΠΈΠ½ΠΆΠ΅Π½Π΅Ρ€ΠΈΡ‚Π΅ Π΄Π° сС фокусираат Π½Π° дизајн Π½Π° високо Π½ΠΈΠ²ΠΎ ΠΈ Π½Π° стратСгиско ΠΎΠ΄Π»ΡƒΡ‡ΡƒΠ²Π°ΡšΠ΅. Π˜ΡΡ‚ΠΎΠ²Ρ€Π΅ΠΌΠ΅Π½ΠΎ, сС Π°Π½Π°Π»ΠΈΠ·ΠΈΡ€Π°Π°Ρ‚ ΠΏΡ€Π΅Π΄ΠΈΠ·Π²ΠΈΡ†ΠΈΡ‚Π΅, Π²ΠΊΠ»ΡƒΡ‡ΠΈΡ‚Π΅Π»Π½ΠΎ ΠΈ нСопходноста ΠΎΠ΄ 4 Ρ‚Π΅ΠΌΠ΅Π»Π½ΠΎ Ρ‚Π΅ΡΡ‚ΠΈΡ€Π°ΡšΠ΅ ΠΈ Π²Π΅Ρ€ΠΈΡ„ΠΈΠΊΠ°Ρ†ΠΈΡ˜Π° Π½Π° ΠΊΠΎΠ΄ΠΎΡ‚ Π³Π΅Π½Π΅Ρ€ΠΈΡ€Π°Π½ со ΠΎΠ²ΠΈΠ΅ Π°Π»Π°Ρ‚ΠΊΠΈ ΠΈ ΠΏΠΎΡ‚Π΅Π½Ρ†ΠΈΡ˜Π°Π»Π½ΠΈΡ‚Π΅ Π΅Ρ‚ΠΈΡ‡ΠΊΠΈ ΠΈΠΌΠΏΠ»ΠΈΠΊΠ°Ρ†ΠΈΠΈ Π½Π° Π²Π΅ΡˆΡ‚Π°Ρ‡ΠΊΠ°Ρ‚Π° ΠΈΠ½Ρ‚Π΅Π»ΠΈΠ³Π΅Π½Ρ†ΠΈΡ˜Π° Π²ΠΎ Ρ€Π°Π·Π²ΠΎΡ˜ΠΎΡ‚ Π½Π° софтвСрот. Оваа ΡΡ‚ΡƒΠ΄ΠΈΡ˜Π° придонСсува Π·Π° Ρ€Π°Π·Π±ΠΈΡ€Π°ΡšΠ΅ Π½Π° ΠΏΡ€Π°ΠΊΡ‚ΠΈΡ‡Π½ΠΈΡ‚Π΅ Π°ΠΏΠ»ΠΈΠΊΠ°Ρ†ΠΈΠΈ ΠΈ ΠΎΠ³Ρ€Π°Π½ΠΈΡ‡ΡƒΠ²Π°ΡšΠ°Ρ‚Π° Π½Π° Π’Π˜ Π²ΠΎ Ρ€Π°Π·Π²ΠΎΡ˜ΠΎΡ‚ Π½Π° софтвСр ΠΈ ΠΈΠ·Π³Π»Π΅Π΄ΠΈΡ‚Π΅ Π·Π° ΠΏΠΎΠ΄ΠΎΠ±Ρ€ΡƒΠ²Π°ΡšΠ΅. Π‘Π΅ ΠΏΠΎΡ‚Π²Ρ€Π΄ΡƒΠ²Π° Π΄Π΅ΠΊΠ° ΠΈΠ°ΠΊΠΎ ΠΌΠΎΠ΄Π΅Π»ΠΈΡ‚Π΅ Π±Π°Π·ΠΈΡ€Π°Π½ΠΈ Π½Π° GPT ΠΏΠΎΠΊΠ°ΠΆΡƒΠ²Π°Π°Ρ‚ Π·Π½Π°Ρ‡ΠΈΡ‚Π΅Π»Π΅Π½ ΠΏΠΎΡ‚Π΅Π½Ρ†ΠΈΡ˜Π°Π» Π²ΠΎ Π°Π²Ρ‚ΠΎΠΌΠ°Ρ‚ΠΈΠ·ΠΈΡ€Π°ΡšΠ΅Ρ‚ΠΎ Π½Π° спСцифичнитС аспСкти Π½Π° софтвСрското инТСнСрство, Ρ‡ΠΎΠ²Π΅Ρ‡ΠΊΠΈΠΎΡ‚ придонСс ΠΈ Π½Π°Π΄Π·ΠΎΡ€ΠΎΡ‚ остануваат ΠΊΠ»ΡƒΡ‡Π½ΠΈ Π·Π° ΡΠΏΡ€Π°Π²ΡƒΠ²Π°ΡšΠ΅ со слоТСни, ΠΊΡ€Π΅Π°Ρ‚ΠΈΠ²Π½ΠΈ ΠΈ двосмислСни Π·Π°Π΄Π°Ρ‡ΠΈ. ΠšΠ»ΡƒΡ‡Π½ΠΈ Π·Π±ΠΎΡ€ΠΎΠ²ΠΈ: Π’Π΅ΡˆΡ‚Π°Ρ‡ΠΊΠ° ΠΈΠ½Ρ‚Π΅Π»ΠΈΠ³Π΅Π½Ρ†ΠΈΡ˜Π°, машинско ΡƒΡ‡Π΅ΡšΠ΅, ΠΎΠ±Ρ€Π°Π±ΠΎΡ‚ΠΊΠ° Π½Π° ΠΏΡ€ΠΈΡ€ΠΎΠ΄Π½ΠΈ Ρ˜Π°Π·ΠΈΡ†ΠΈ, автоматско ΠΏΡ€ΠΎΠ³Ρ€Π°ΠΌΠΈΡ€Π°ΡšΠ΅, ΠΊΠ²Π°Π»ΠΈΡ‚Π΅Ρ‚ Π½Π° ΠΊΠΎΠ΄, Сфикасност Π½Π° Ρ€Π°Π±ΠΎΡ‚Π½ΠΈΠΎΡ‚ Ρ‚Π΅ΠΊ, Π΅Ρ‚ΠΈΠΊΠ° Π²ΠΎ Π²Π΅ΡˆΡ‚Π°Ρ‡ΠΊΠ°Ρ‚Π° ΠΈΠ½Ρ‚Π΅Π»ΠΈΠ³Π΅Π½Ρ†ΠΈΡ˜Π°
    corecore